diff options
author | Brian <[email protected]> | 2007-03-24 10:18:14 -0600 |
---|---|---|
committer | Brian <[email protected]> | 2007-03-24 10:18:14 -0600 |
commit | 0e71d08e8df7f59da74e78212fe8433ceb7c7315 (patch) | |
tree | db2a15d462a631290fcd095fbbe24af34f6860ef | |
parent | b50b036ffb795a12106bd59b1a08b0287a8b3388 (diff) |
Properly free the slang_ir_node->Store data (use ref counting).
-rw-r--r-- | src/mesa/shader/slang/slang_ir.c | 57 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_ir.h | 1 |
2 files changed, 46 insertions, 12 deletions
diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c index 5790d0ab7f5..11c09d33a21 100644 --- a/src/mesa/shader/slang/slang_ir.c +++ b/src/mesa/shader/slang/slang_ir.c @@ -106,33 +106,65 @@ _slang_ir_info(slang_ir_opcode opcode) return NULL; } + static const char * -slang_ir_name(slang_ir_opcode opcode) +_slang_ir_name(slang_ir_opcode opcode) { return _slang_ir_info(opcode)->IrName; } - /** - * Recursively free an IR tree. + * Since many IR nodes might point to the same IR storage info, we need + * to be careful when deleting things. + * Before deleting an IR tree, traverse it and do refcounting on the + * IR storage nodes. Use the refcount info during delete to free things + * properly. */ -void -_slang_free_ir_tree(slang_ir_node *n) +static void +_slang_refcount_storage(slang_ir_node *n) { -#if 1 GLuint i; if (!n) return; + if (n->Store) + n->Store->RefCount++; + for (i = 0; i < 3; i++) + _slang_refcount_storage(n->Children[i]); +} + + +static void +_slang_free_ir(slang_ir_node *n) +{ + GLuint i; + if (!n) + return; + + if (n->Store) { + n->Store->RefCount--; + if (n->Store->RefCount == 0) { + free(n->Store); + n->Store = NULL; + } + } + for (i = 0; i < 3; i++) _slang_free_ir_tree(n->Children[i]); /* Do not free n->List since it's a child elsewhere */ free(n); -#endif } - +/** + * Recursively free an IR tree. + */ +void +_slang_free_ir_tree(slang_ir_node *n) +{ + _slang_refcount_storage(n); + _slang_free_ir(n); +} @@ -149,6 +181,7 @@ swizzle_string(GLuint swizzle) return s; } + static const char * writemask_string(GLuint writemask) { @@ -163,6 +196,7 @@ writemask_string(GLuint writemask) return s; } + static const char * storage_string(const slang_ir_storage *st) { @@ -204,12 +238,11 @@ spaces(int n) } -#define IND 0 - - void _slang_print_ir_tree(const slang_ir_node *n, int indent) { +#define IND 0 + if (!n) return; #if !IND @@ -346,7 +379,7 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent) _slang_print_ir_tree(n->Children[0], indent + 3); break; default: - printf("%s (%p, %p) (store %p)\n", slang_ir_name(n->Opcode), + printf("%s (%p, %p) (store %p)\n", _slang_ir_name(n->Opcode), (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store); _slang_print_ir_tree(n->Children[0], indent+3); _slang_print_ir_tree(n->Children[1], indent+3); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 2b7d8229326..2e90409cafd 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -147,6 +147,7 @@ struct _slang_ir_storage GLint Index; /**< -1 means unallocated */ GLint Size; /**< number of floats */ GLuint Swizzle; + GLint RefCount; /**< Used during IR tree delete */ }; typedef struct _slang_ir_storage slang_ir_storage; |