From 0e71d08e8df7f59da74e78212fe8433ceb7c7315 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 24 Mar 2007 10:18:14 -0600 Subject: Properly free the slang_ir_node->Store data (use ref counting). --- src/mesa/shader/slang/slang_ir.c | 57 +++++++++++++++++++++++++++++++--------- src/mesa/shader/slang/slang_ir.h | 1 + 2 files changed, 46 insertions(+), 12 deletions(-) (limited to 'src/mesa/shader') diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c index 5790d0ab7f..11c09d33a2 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 2b7d822932..2e90409caf 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; -- cgit v1.2.3