From f961e4458f1e894ca782c1627b69cdee993a16f8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 15:47:04 -0700 Subject: glsl_symbol_table: Add new talloc-based new() We take advantage of overloading of the new operator (with an additional parameter!) to make this look as "C++ like" as possible. This closes 507 memory leaks when compiling glsl-orangebook-ch06-bump.frag when measured with: valgrind ./glsl glsl-orangebook-ch06-bump.frag as seen here: total heap usage: 55,623 allocs, 14,389 frees (was 13,882 frees before) --- glsl_symbol_table.h | 33 +++++++++++++++++++++++++++++++++ ir.h | 4 ++++ main.cpp | 6 +----- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/glsl_symbol_table.h b/glsl_symbol_table.h index 26b90fdb7c..ae2fd3f4f1 100644 --- a/glsl_symbol_table.h +++ b/glsl_symbol_table.h @@ -26,6 +26,8 @@ #ifndef GLSL_SYMBOL_TABLE #define GLSL_SYMBOL_TABLE +#include + #include "symbol_table.h" #include "ir.h" #include "glsl_types.h" @@ -44,7 +46,38 @@ private: glsl_function_name_space = 2 }; + static int + _glsl_symbol_table_destructor (glsl_symbol_table *table) + { + table->~glsl_symbol_table(); + + return 0; + } + public: + /* Callers of this talloc-based new need not call delete. It's + * easier to just talloc_free 'ctx' (or any of its ancestors). */ + static void* operator new(size_t size, void *ctx) + { + void *table; + + table = talloc_size(ctx, size); + assert(table != NULL); + + talloc_set_destructor(table, (int (*)(void*)) _glsl_symbol_table_destructor); + + return table; + } + + /* If the user *does* call delete, that's OK, we will just + * talloc_free in that case. Here, C++ will have already called the + * destructor so tell talloc not to do that again. */ + static void operator delete(void *table) + { + talloc_set_destructor(table, NULL); + talloc_free(table); + } + glsl_symbol_table() { table = _mesa_symbol_table_ctor(); diff --git a/ir.h b/ir.h index 9277f76204..68e90653ed 100644 --- a/ir.h +++ b/ir.h @@ -29,6 +29,10 @@ #include #include +extern "C" { +#include +} + #include "list.h" #include "ir_visitor.h" #include "ir_hierarchical_visitor.h" diff --git a/main.cpp b/main.cpp index f56e6f6142..dcd4b8f672 100644 --- a/main.cpp +++ b/main.cpp @@ -29,10 +29,6 @@ #include #include -extern "C" { -#include -} - #include "ast.h" #include "glsl_parser_extras.h" #include "glsl_parser.h" @@ -118,7 +114,7 @@ compile_shader(struct glsl_shader *shader) state->scanner = NULL; state->translation_unit.make_empty(); - state->symbols = new glsl_symbol_table; + state->symbols = new(shader) glsl_symbol_table; state->info_log = talloc_strdup(shader, ""); state->error = false; state->temp_index = 0; -- cgit v1.2.3