summaryrefslogtreecommitdiff
path: root/src/mesa/shader/slang/slang_ir.c
diff options
context:
space:
mode:
authorBrian <brian@yutani.localnet.net>2007-03-24 10:18:14 -0600
committerBrian <brian@yutani.localnet.net>2007-03-24 10:18:14 -0600
commit0e71d08e8df7f59da74e78212fe8433ceb7c7315 (patch)
treedb2a15d462a631290fcd095fbbe24af34f6860ef /src/mesa/shader/slang/slang_ir.c
parentb50b036ffb795a12106bd59b1a08b0287a8b3388 (diff)
Properly free the slang_ir_node->Store data (use ref counting).
Diffstat (limited to 'src/mesa/shader/slang/slang_ir.c')
-rw-r--r--src/mesa/shader/slang/slang_ir.c57
1 files changed, 45 insertions, 12 deletions
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);