From be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 13:34:05 -0700 Subject: glsl2 main: Use talloc to allocate whole_program struct. This way, whole_program can be our top-level talloc context object, allowing us to free the lot with a single talloc_free in the end. --- main.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/main.cpp b/main.cpp index 17f25d741e..78169d257d 100644 --- a/main.cpp +++ b/main.cpp @@ -200,20 +200,21 @@ main(int argc, char **argv) if (argc <= optind) usage_fail(argv[0]); - struct glsl_program whole_program; - memset(&whole_program, 0, sizeof(whole_program)); + struct glsl_program *whole_program; + + whole_program = talloc_zero (NULL, struct glsl_program); + assert(whole_program != NULL); for (/* empty */; argc > optind; optind++) { - whole_program.Shaders = (struct glsl_shader **) - realloc(whole_program.Shaders, - sizeof(struct glsl_shader *) * (whole_program.NumShaders + 1)); - assert(whole_program.Shaders != NULL); + whole_program->Shaders = (struct glsl_shader **) + realloc(whole_program->Shaders, + sizeof(struct glsl_shader *) * (whole_program->NumShaders + 1)); + assert(whole_program->Shaders != NULL); - /* talloc context should probably be whole_program */ - struct glsl_shader *shader = talloc_zero(NULL, glsl_shader); + struct glsl_shader *shader = talloc_zero(whole_program, glsl_shader); - whole_program.Shaders[whole_program.NumShaders] = shader; - whole_program.NumShaders++; + whole_program->Shaders[whole_program->NumShaders] = shader; + whole_program->NumShaders++; const unsigned len = strlen(argv[optind]); if (len < 6) @@ -245,9 +246,11 @@ main(int argc, char **argv) } if ((status == EXIT_SUCCESS) && do_link) { - link_shaders(&whole_program); - status = (whole_program.LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; + link_shaders(whole_program); + status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; } + talloc_free(whole_program); + return status; } -- cgit v1.2.3 From 2d2561ef9696aa5ff0c1a85e3a4a95475f927935 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 15:43:38 -0700 Subject: glsl2 main: Use talloc to allocate _mesa_glsl_parse_state This is a short-lived object. It exists only for the duration of the compile_shader() function, (as opposed to the shader and whole_program which live longer). The state is created with the same talloc parent as the shader, so that other allocation can be done with talloc_parent(state) as the owner in order to attach to a long-lived object. --- main.cpp | 57 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/main.cpp b/main.cpp index 78169d257d..f56e6f6142 100644 --- a/main.cpp +++ b/main.cpp @@ -106,38 +106,39 @@ const struct option compiler_opts[] = { void compile_shader(struct glsl_shader *shader) { - struct _mesa_glsl_parse_state state; + struct _mesa_glsl_parse_state *state; + + state = talloc_zero(talloc_parent(shader), struct _mesa_glsl_parse_state); - memset(& state, 0, sizeof(state)); switch (shader->Type) { - case GL_VERTEX_SHADER: state.target = vertex_shader; break; - case GL_FRAGMENT_SHADER: state.target = fragment_shader; break; - case GL_GEOMETRY_SHADER: state.target = geometry_shader; break; + case GL_VERTEX_SHADER: state->target = vertex_shader; break; + case GL_FRAGMENT_SHADER: state->target = fragment_shader; break; + case GL_GEOMETRY_SHADER: state->target = geometry_shader; break; } - state.scanner = NULL; - state.translation_unit.make_empty(); - state.symbols = new glsl_symbol_table; - state.info_log = talloc_strdup(shader, ""); - state.error = false; - state.temp_index = 0; - state.loop_or_switch_nesting = NULL; - state.ARB_texture_rectangle_enable = true; + state->scanner = NULL; + state->translation_unit.make_empty(); + state->symbols = new glsl_symbol_table; + state->info_log = talloc_strdup(shader, ""); + state->error = false; + state->temp_index = 0; + state->loop_or_switch_nesting = NULL; + state->ARB_texture_rectangle_enable = true; /* Create a new context for the preprocessor output. Ultimately, this * should probably be the parser context, but there isn't one yet. */ const char *source = shader->Source; - state.error = preprocess(shader, &source, &state.info_log); + state->error = preprocess(shader, &source, &state->info_log); - if (!state.error) { - _mesa_glsl_lexer_ctor(& state, source); - _mesa_glsl_parse(& state); - _mesa_glsl_lexer_dtor(& state); + if (!state->error) { + _mesa_glsl_lexer_ctor(state, source); + _mesa_glsl_parse(state); + _mesa_glsl_lexer_dtor(state); } if (dump_ast) { - foreach_list_const(n, &state.translation_unit) { + foreach_list_const(n, &state->translation_unit) { ast_node *ast = exec_node_data(ast_node, n, link); ast->print(); } @@ -145,13 +146,13 @@ compile_shader(struct glsl_shader *shader) } shader->ir.make_empty(); - if (!state.error && !state.translation_unit.is_empty()) - _mesa_ast_to_hir(&shader->ir, &state); + if (!state->error && !state->translation_unit.is_empty()) + _mesa_ast_to_hir(&shader->ir, state); validate_ir_tree(&shader->ir); /* Optimization passes */ - if (!state.error && !shader->ir.is_empty()) { + if (!state->error && !shader->ir.is_empty()) { bool progress; do { progress = false; @@ -171,17 +172,19 @@ compile_shader(struct glsl_shader *shader) validate_ir_tree(&shader->ir); /* Print out the resulting IR */ - if (!state.error && dump_lir) { - _mesa_print_ir(&shader->ir, &state); + if (!state->error && dump_lir) { + _mesa_print_ir(&shader->ir, state); } - shader->symbols = state.symbols; - shader->CompileStatus = !state.error; + shader->symbols = state->symbols; + shader->CompileStatus = !state->error; if (shader->InfoLog) talloc_free(shader->InfoLog); - shader->InfoLog = state.info_log; + shader->InfoLog = state->info_log; + + talloc_free(state); return; } -- cgit v1.2.3 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 From 015b3a5115df9a53b73d4b99fed86cf245c87aca Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 16:27:18 -0700 Subject: exec_node: Remove destructor from exec_node and all descendants. Two of these destructors are non-empty, (s_symbol and s_list), so this commit could potentially introduce memory leaks, (though, no additional leaks are found in glsl-orangebook-ch06-bump.frag at least---perhaps the current code is never calling delete on these classes?). Going forward, we will switch to talloc for exec_node so we won't need explicit destrcutors to free up any memory used. --- s_expression.cpp | 15 --------------- s_expression.h | 8 -------- 2 files changed, 23 deletions(-) diff --git a/s_expression.cpp b/s_expression.cpp index 4022dfab7a..0fb296ef67 100644 --- a/s_expression.cpp +++ b/s_expression.cpp @@ -34,25 +34,10 @@ s_symbol::s_symbol(const char *tmp) strcpy(this->str, tmp); } -s_symbol::~s_symbol() -{ - delete [] this->str; - this->str = NULL; -} - s_list::s_list() { } -s_list::~s_list() -{ - exec_list_iterator it(this->subexpressions.iterator()); - while (it.has_next()) - it.remove(); - - assert(this->subexpressions.is_empty()); -} - unsigned s_list::length() const { diff --git a/s_expression.h b/s_expression.h index d5e52c16e8..8a4eda28da 100644 --- a/s_expression.h +++ b/s_expression.h @@ -46,8 +46,6 @@ class s_expression : public exec_node { public: - virtual ~s_expression() { } - /** * Read an S-Expression from the given string. * Advances the supplied pointer to just after the expression read. @@ -73,8 +71,6 @@ protected: class s_number : public s_expression { public: - virtual ~s_number() { } - bool is_number() const { return true; } virtual float fvalue() = 0; @@ -87,7 +83,6 @@ class s_int : public s_number { public: s_int(int x) : val(x) { } - virtual ~s_int() { } bool is_int() const { return true; } @@ -104,7 +99,6 @@ class s_float : public s_number { public: s_float(float x) : val(x) { } - virtual ~s_float() { } float fvalue() { return this->val; } @@ -118,7 +112,6 @@ class s_symbol : public s_expression { public: s_symbol(const char *); - virtual ~s_symbol(); bool is_symbol() const { return true; } @@ -135,7 +128,6 @@ class s_list : public s_expression { public: s_list(); - virtual ~s_list(); virtual bool is_list() const { return true; } unsigned length() const; -- cgit v1.2.3 From 8f52c9b5fcbc73ed12b23253caa44c28fd4452e2 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 17:12:11 -0700 Subject: ast_node: Add new talloc-based new() And use the talloc-based new for all of the ast objects created by the parser. This closes a lot of memory leaks, and will allow us to use these ast objects as talloc parents in the future, (for things like exec_nodes, etc.). This closes 164 leaks in the glsl-orangebook-ch06-bump.frag test: total heap usage: 55,623 allocs, 14,553 frees (was 14,389 frees) --- ast.h | 19 ++++ glsl_parser.ypp | 297 ++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 211 insertions(+), 105 deletions(-) diff --git a/ast.h b/ast.h index 782e2c7ce7..de300e719c 100644 --- a/ast.h +++ b/ast.h @@ -36,6 +36,25 @@ struct YYLTYPE; class ast_node { 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 *node; + + node = talloc_size(ctx, size); + assert(node != NULL); + + return node; + } + + /* If the user *does* call delete, that's OK, we will just + * talloc_free in that case. */ + static void operator delete(void *table) + { + talloc_free(table); + } + virtual void print(void) const; virtual ir_rvalue *hir(exec_list *instructions, struct _mesa_glsl_parse_state *state); diff --git a/glsl_parser.ypp b/glsl_parser.ypp index ae009ed20c..4132495f40 100644 --- a/glsl_parser.ypp +++ b/glsl_parser.ypp @@ -255,31 +255,36 @@ variable_identifier: primary_expression: variable_identifier { - $$ = new ast_expression(ast_identifier, NULL, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_identifier, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.identifier = $1; } | INTCONSTANT { - $$ = new ast_expression(ast_int_constant, NULL, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_int_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.int_constant = $1; } | UINTCONSTANT { - $$ = new ast_expression(ast_uint_constant, NULL, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_uint_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.uint_constant = $1; } | FLOATCONSTANT { - $$ = new ast_expression(ast_float_constant, NULL, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_float_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.float_constant = $1; } | BOOLCONSTANT { - $$ = new ast_expression(ast_bool_constant, NULL, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_bool_constant, NULL, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.bool_constant = $1; } @@ -293,7 +298,8 @@ postfix_expression: primary_expression | postfix_expression '[' integer_expression ']' { - $$ = new ast_expression(ast_array_index, $1, $3, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_array_index, $1, $3, NULL); $$->set_location(yylloc); } | function_call @@ -308,18 +314,21 @@ postfix_expression: } | postfix_expression '.' IDENTIFIER { - $$ = new ast_expression(ast_field_selection, $1, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_field_selection, $1, NULL, NULL); $$->set_location(yylloc); $$->primary_expression.identifier = $3; } | postfix_expression INC_OP { - $$ = new ast_expression(ast_post_inc, $1, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_post_inc, $1, NULL, NULL); $$->set_location(yylloc); } | postfix_expression DEC_OP { - $$ = new ast_expression(ast_post_dec, $1, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_post_dec, $1, NULL, NULL); $$->set_location(yylloc); } ; @@ -336,7 +345,8 @@ function_call_or_method: function_call_generic | postfix_expression '.' function_call_generic { - $$ = new ast_expression(ast_field_selection, $1, $3, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_field_selection, $1, $3, NULL); $$->set_location(yylloc); } ; @@ -376,19 +386,22 @@ function_call_header: function_identifier: type_specifier { - $$ = new ast_function_expression($1); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_function_expression($1); $$->set_location(yylloc); } | IDENTIFIER { - ast_expression *callee = new ast_expression($1); - $$ = new ast_function_expression(callee); + void *ctx = talloc_parent(state); + ast_expression *callee = new(ctx) ast_expression($1); + $$ = new(ctx) ast_function_expression(callee); $$->set_location(yylloc); } | FIELD_SELECTION { - ast_expression *callee = new ast_expression($1); - $$ = new ast_function_expression(callee); + void *ctx = talloc_parent(state); + ast_expression *callee = new(ctx) ast_expression($1); + $$ = new(ctx) ast_function_expression(callee); $$->set_location(yylloc); } ; @@ -398,17 +411,20 @@ unary_expression: postfix_expression | INC_OP unary_expression { - $$ = new ast_expression(ast_pre_inc, $2, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_pre_inc, $2, NULL, NULL); $$->set_location(yylloc); } | DEC_OP unary_expression { - $$ = new ast_expression(ast_pre_dec, $2, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_pre_dec, $2, NULL, NULL); $$->set_location(yylloc); } | unary_operator unary_expression { - $$ = new ast_expression($1, $2, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression($1, $2, NULL, NULL); $$->set_location(yylloc); } ; @@ -425,17 +441,20 @@ multiplicative_expression: unary_expression | multiplicative_expression '*' unary_expression { - $$ = new ast_expression_bin(ast_mul, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_mul, $1, $3); $$->set_location(yylloc); } | multiplicative_expression '/' unary_expression { - $$ = new ast_expression_bin(ast_div, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_div, $1, $3); $$->set_location(yylloc); } | multiplicative_expression '%' unary_expression { - $$ = new ast_expression_bin(ast_mod, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_mod, $1, $3); $$->set_location(yylloc); } ; @@ -444,12 +463,14 @@ additive_expression: multiplicative_expression | additive_expression '+' multiplicative_expression { - $$ = new ast_expression_bin(ast_add, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_add, $1, $3); $$->set_location(yylloc); } | additive_expression '-' multiplicative_expression { - $$ = new ast_expression_bin(ast_sub, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_sub, $1, $3); $$->set_location(yylloc); } ; @@ -458,12 +479,14 @@ shift_expression: additive_expression | shift_expression LEFT_OP additive_expression { - $$ = new ast_expression_bin(ast_lshift, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_lshift, $1, $3); $$->set_location(yylloc); } | shift_expression RIGHT_OP additive_expression { - $$ = new ast_expression_bin(ast_rshift, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_rshift, $1, $3); $$->set_location(yylloc); } ; @@ -472,22 +495,26 @@ relational_expression: shift_expression | relational_expression '<' shift_expression { - $$ = new ast_expression_bin(ast_less, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_less, $1, $3); $$->set_location(yylloc); } | relational_expression '>' shift_expression { - $$ = new ast_expression_bin(ast_greater, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_greater, $1, $3); $$->set_location(yylloc); } | relational_expression LE_OP shift_expression { - $$ = new ast_expression_bin(ast_lequal, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_lequal, $1, $3); $$->set_location(yylloc); } | relational_expression GE_OP shift_expression { - $$ = new ast_expression_bin(ast_gequal, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_gequal, $1, $3); $$->set_location(yylloc); } ; @@ -496,12 +523,14 @@ equality_expression: relational_expression | equality_expression EQ_OP relational_expression { - $$ = new ast_expression_bin(ast_equal, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_equal, $1, $3); $$->set_location(yylloc); } | equality_expression NE_OP relational_expression { - $$ = new ast_expression_bin(ast_nequal, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_nequal, $1, $3); $$->set_location(yylloc); } ; @@ -510,7 +539,8 @@ and_expression: equality_expression | and_expression '&' equality_expression { - $$ = new ast_expression_bin(ast_bit_or, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); $$->set_location(yylloc); } ; @@ -519,7 +549,8 @@ exclusive_or_expression: and_expression | exclusive_or_expression '^' and_expression { - $$ = new ast_expression_bin(ast_bit_xor, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_bit_xor, $1, $3); $$->set_location(yylloc); } ; @@ -528,7 +559,8 @@ inclusive_or_expression: exclusive_or_expression | inclusive_or_expression '|' exclusive_or_expression { - $$ = new ast_expression_bin(ast_bit_or, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_bit_or, $1, $3); $$->set_location(yylloc); } ; @@ -537,7 +569,8 @@ logical_and_expression: inclusive_or_expression | logical_and_expression AND_OP inclusive_or_expression { - $$ = new ast_expression_bin(ast_logic_and, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_logic_and, $1, $3); $$->set_location(yylloc); } ; @@ -546,7 +579,8 @@ logical_xor_expression: logical_and_expression | logical_xor_expression XOR_OP logical_and_expression { - $$ = new ast_expression_bin(ast_logic_xor, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_logic_xor, $1, $3); $$->set_location(yylloc); } ; @@ -555,7 +589,8 @@ logical_or_expression: logical_xor_expression | logical_or_expression OR_OP logical_xor_expression { - $$ = new ast_expression_bin(ast_logic_or, $1, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_bin(ast_logic_or, $1, $3); $$->set_location(yylloc); } ; @@ -564,7 +599,8 @@ conditional_expression: logical_or_expression | logical_or_expression '?' expression ':' assignment_expression { - $$ = new ast_expression(ast_conditional, $1, $3, $5); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression(ast_conditional, $1, $3, $5); $$->set_location(yylloc); } ; @@ -573,7 +609,8 @@ assignment_expression: conditional_expression | unary_expression assignment_operator assignment_expression { - $$ = new ast_expression($2, $1, $3, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression($2, $1, $3, NULL); $$->set_location(yylloc); } ; @@ -599,8 +636,9 @@ expression: } | expression ',' assignment_expression { + void *ctx = talloc_parent(state); if ($1->oper != ast_sequence) { - $$ = new ast_expression(ast_sequence, NULL, NULL, NULL); + $$ = new(ctx) ast_expression(ast_sequence, NULL, NULL, NULL); $$->set_location(yylloc); $$->expressions.push_tail(& $1->link); } else { @@ -662,7 +700,8 @@ function_header_with_parameters: function_header: fully_specified_type IDENTIFIER '(' { - $$ = new ast_function(); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_function(); $$->set_location(yylloc); $$->return_type = $1; $$->identifier = $2; @@ -672,18 +711,20 @@ function_header: parameter_declarator: type_specifier IDENTIFIER { - $$ = new ast_parameter_declarator(); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); - $$->type = new ast_fully_specified_type(); + $$->type = new(ctx) ast_fully_specified_type(); $$->type->set_location(yylloc); $$->type->specifier = $1; $$->identifier = $2; } | type_specifier IDENTIFIER '[' constant_expression ']' { - $$ = new ast_parameter_declarator(); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); - $$->type = new ast_fully_specified_type(); + $$->type = new(ctx) ast_fully_specified_type(); $$->type->set_location(yylloc); $$->type->specifier = $1; $$->identifier = $2; @@ -707,19 +748,21 @@ parameter_declaration: } | parameter_type_qualifier parameter_qualifier parameter_type_specifier { + void *ctx = talloc_parent(state); $1.i |= $2.i; - $$ = new ast_parameter_declarator(); + $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); - $$->type = new ast_fully_specified_type(); + $$->type = new(ctx) ast_fully_specified_type(); $$->type->qualifier = $1.q; $$->type->specifier = $3; } | parameter_qualifier parameter_type_specifier { - $$ = new ast_parameter_declarator(); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_parameter_declarator(); $$->set_location(yylloc); - $$->type = new ast_fully_specified_type(); + $$->type = new(ctx) ast_fully_specified_type(); $$->type->qualifier = $1.q; $$->type->specifier = $2; } @@ -740,7 +783,8 @@ init_declarator_list: single_declaration | init_declarator_list ',' IDENTIFIER { - ast_declaration *decl = new ast_declaration($3, false, NULL, NULL); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, NULL); decl->set_location(yylloc); $$ = $1; @@ -748,7 +792,8 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' ']' { - ast_declaration *decl = new ast_declaration($3, true, NULL, NULL); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, NULL); decl->set_location(yylloc); $$ = $1; @@ -756,7 +801,8 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' { - ast_declaration *decl = new ast_declaration($3, true, $5, NULL); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, NULL); decl->set_location(yylloc); $$ = $1; @@ -764,7 +810,8 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' ']' '=' initializer { - ast_declaration *decl = new ast_declaration($3, true, NULL, $7); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($3, true, NULL, $7); decl->set_location(yylloc); $$ = $1; @@ -772,7 +819,8 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '[' constant_expression ']' '=' initializer { - ast_declaration *decl = new ast_declaration($3, true, $5, $8); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($3, true, $5, $8); decl->set_location(yylloc); $$ = $1; @@ -780,7 +828,8 @@ init_declarator_list: } | init_declarator_list ',' IDENTIFIER '=' initializer { - ast_declaration *decl = new ast_declaration($3, false, NULL, $5); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($3, false, NULL, $5); decl->set_location(yylloc); $$ = $1; @@ -792,67 +841,75 @@ init_declarator_list: single_declaration: fully_specified_type { + void *ctx = talloc_parent(state); if ($1->specifier->type_specifier != ast_struct) { _mesa_glsl_error(& @1, state, "empty declaration list\n"); YYERROR; } else { - $$ = new ast_declarator_list($1); + $$ = new(ctx) ast_declarator_list($1); $$->set_location(yylloc); } } | fully_specified_type IDENTIFIER { - ast_declaration *decl = new ast_declaration($2, false, NULL, NULL); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); - $$ = new ast_declarator_list($1); + $$ = new(ctx) ast_declarator_list($1); $$->set_location(yylloc); $$->declarations.push_tail(&decl->link); } | fully_specified_type IDENTIFIER '[' ']' { - ast_declaration *decl = new ast_declaration($2, true, NULL, NULL); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, NULL); - $$ = new ast_declarator_list($1); + $$ = new(ctx) ast_declarator_list($1); $$->set_location(yylloc); $$->declarations.push_tail(&decl->link); } | fully_specified_type IDENTIFIER '[' constant_expression ']' { - ast_declaration *decl = new ast_declaration($2, true, $4, NULL); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, NULL); - $$ = new ast_declarator_list($1); + $$ = new(ctx) ast_declarator_list($1); $$->set_location(yylloc); $$->declarations.push_tail(&decl->link); } | fully_specified_type IDENTIFIER '[' ']' '=' initializer { - ast_declaration *decl = new ast_declaration($2, true, NULL, $6); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, true, NULL, $6); - $$ = new ast_declarator_list($1); + $$ = new(ctx) ast_declarator_list($1); $$->set_location(yylloc); $$->declarations.push_tail(&decl->link); } | fully_specified_type IDENTIFIER '[' constant_expression ']' '=' initializer { - ast_declaration *decl = new ast_declaration($2, true, $4, $7); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, true, $4, $7); - $$ = new ast_declarator_list($1); + $$ = new(ctx) ast_declarator_list($1); $$->set_location(yylloc); $$->declarations.push_tail(&decl->link); } | fully_specified_type IDENTIFIER '=' initializer { - ast_declaration *decl = new ast_declaration($2, false, NULL, $4); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); - $$ = new ast_declarator_list($1); + $$ = new(ctx) ast_declarator_list($1); $$->set_location(yylloc); $$->declarations.push_tail(&decl->link); } | INVARIANT IDENTIFIER // Vertex only. { - ast_declaration *decl = new ast_declaration($2, false, NULL, NULL); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, NULL); - $$ = new ast_declarator_list(NULL); + $$ = new(ctx) ast_declarator_list(NULL); $$->set_location(yylloc); $$->invariant = true; @@ -863,13 +920,15 @@ single_declaration: fully_specified_type: type_specifier { - $$ = new ast_fully_specified_type(); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_fully_specified_type(); $$->set_location(yylloc); $$->specifier = $1; } | type_qualifier type_specifier { - $$ = new ast_fully_specified_type(); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_fully_specified_type(); $$->set_location(yylloc); $$->qualifier = $1.q; $$->specifier = $2; @@ -939,17 +998,20 @@ type_specifier_no_prec: type_specifier_nonarray: basic_type_specifier_nonarray { - $$ = new ast_type_specifier($1); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_type_specifier($1); $$->set_location(yylloc); } | struct_specifier { - $$ = new ast_type_specifier($1); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_type_specifier($1); $$->set_location(yylloc); } | IDENTIFIER { - $$ = new ast_type_specifier($1); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_type_specifier($1); $$->set_location(yylloc); } ; @@ -1050,12 +1112,14 @@ precision_qualifier: struct_specifier: STRUCT IDENTIFIER '{' struct_declaration_list '}' { - $$ = new ast_struct_specifier($2, $4); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_struct_specifier($2, $4); $$->set_location(yylloc); } | STRUCT '{' struct_declaration_list '}' { - $$ = new ast_struct_specifier(NULL, $3); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_struct_specifier(NULL, $3); $$->set_location(yylloc); } ; @@ -1076,11 +1140,12 @@ struct_declaration_list: struct_declaration: type_specifier struct_declarator_list ';' { - ast_fully_specified_type *type = new ast_fully_specified_type(); + void *ctx = talloc_parent(state); + ast_fully_specified_type *type = new(ctx) ast_fully_specified_type(); type->set_location(yylloc); type->specifier = $1; - $$ = new ast_declarator_list(type); + $$ = new(ctx) ast_declarator_list(type); $$->set_location(yylloc); $$->declarations.push_degenerate_list_at_head(& $2->link); @@ -1103,12 +1168,14 @@ struct_declarator_list: struct_declarator: IDENTIFIER { - $$ = new ast_declaration($1, false, NULL, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_declaration($1, false, NULL, NULL); $$->set_location(yylloc); } | IDENTIFIER '[' constant_expression ']' { - $$ = new ast_declaration($1, true, $3, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_declaration($1, true, $3, NULL); $$->set_location(yylloc); } ; @@ -1150,12 +1217,14 @@ simple_statement: compound_statement: '{' '}' { - $$ = new ast_compound_statement(true, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_compound_statement(true, NULL); $$->set_location(yylloc); } | '{' statement_list '}' { - $$ = new ast_compound_statement(true, $2); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_compound_statement(true, $2); $$->set_location(yylloc); } ; @@ -1168,12 +1237,14 @@ statement_no_new_scope: compound_statement_no_new_scope: '{' '}' { - $$ = new ast_compound_statement(false, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_compound_statement(false, NULL); $$->set_location(yylloc); } | '{' statement_list '}' { - $$ = new ast_compound_statement(false, $2); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_compound_statement(false, $2); $$->set_location(yylloc); } ; @@ -1203,12 +1274,14 @@ statement_list: expression_statement: ';' { - $$ = new ast_expression_statement(NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_statement(NULL); $$->set_location(yylloc); } | expression ';' { - $$ = new ast_expression_statement($1); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_expression_statement($1); $$->set_location(yylloc); } ; @@ -1216,7 +1289,8 @@ expression_statement: selection_statement_matched: IF '(' expression ')' statement_matched ELSE statement_matched { - $$ = new ast_selection_statement($3, $5, $7); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_selection_statement($3, $5, $7); $$->set_location(yylloc); } ; @@ -1224,17 +1298,20 @@ selection_statement_matched: selection_statement_unmatched: IF '(' expression ')' statement_matched { - $$ = new ast_selection_statement($3, $5, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_selection_statement($3, $5, NULL); $$->set_location(yylloc); } | IF '(' expression ')' statement_unmatched { - $$ = new ast_selection_statement($3, $5, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_selection_statement($3, $5, NULL); $$->set_location(yylloc); } | IF '(' expression ')' statement_matched ELSE statement_unmatched { - $$ = new ast_selection_statement($3, $5, $7); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_selection_statement($3, $5, $7); $$->set_location(yylloc); } ; @@ -1246,8 +1323,9 @@ condition: } | fully_specified_type IDENTIFIER '=' initializer { - ast_declaration *decl = new ast_declaration($2, false, NULL, $4); - ast_declarator_list *declarator = new ast_declarator_list($1); + void *ctx = talloc_parent(state); + ast_declaration *decl = new(ctx) ast_declaration($2, false, NULL, $4); + ast_declarator_list *declarator = new(ctx) ast_declarator_list($1); decl->set_location(yylloc); declarator->set_location(yylloc); @@ -1268,20 +1346,23 @@ case_label: iteration_statement: WHILE '(' condition ')' statement_no_new_scope { - $$ = new ast_iteration_statement(ast_iteration_statement::ast_while, - NULL, $3, NULL, $5); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_while, + NULL, $3, NULL, $5); $$->set_location(yylloc); } | DO statement WHILE '(' expression ')' ';' { - $$ = new ast_iteration_statement(ast_iteration_statement::ast_do_while, - NULL, $5, NULL, $2); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_do_while, + NULL, $5, NULL, $2); $$->set_location(yylloc); } | FOR '(' for_init_statement for_rest_statement ')' statement_no_new_scope { - $$ = new ast_iteration_statement(ast_iteration_statement::ast_for, - $3, $4.cond, $4.rest, $6); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_iteration_statement(ast_iteration_statement::ast_for, + $3, $4.cond, $4.rest, $6); $$->set_location(yylloc); } ; @@ -1316,27 +1397,32 @@ for_rest_statement: jump_statement: CONTINUE ';' { - $$ = new ast_jump_statement(ast_jump_statement::ast_continue, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_continue, NULL); $$->set_location(yylloc); } | BREAK ';' { - $$ = new ast_jump_statement(ast_jump_statement::ast_break, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_break, NULL); $$->set_location(yylloc); } | RETURN ';' { - $$ = new ast_jump_statement(ast_jump_statement::ast_return, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, NULL); $$->set_location(yylloc); } | RETURN expression ';' { - $$ = new ast_jump_statement(ast_jump_statement::ast_return, $2); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_return, $2); $$->set_location(yylloc); } | DISCARD ';' // Fragment shader only. { - $$ = new ast_jump_statement(ast_jump_statement::ast_discard, NULL); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_jump_statement(ast_jump_statement::ast_discard, NULL); $$->set_location(yylloc); } ; @@ -1349,7 +1435,8 @@ external_declaration: function_definition: function_prototype compound_statement_no_new_scope { - $$ = new ast_function_definition(); + void *ctx = talloc_parent(state); + $$ = new(ctx) ast_function_definition(); $$->set_location(yylloc); $$->prototype = $1; $$->body = $2; -- cgit v1.2.3 From 1660a2954797e056caba319c5d6c70b0d4be22fe Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 18:11:51 -0700 Subject: exec_node: Add new talloc-based new() And fix all callers to use the tallbac-based new for exec_node construction. We make ready use of talloc_parent in order to get valid, (and appropriate) talloc owners for everything we construct without having to add new 'ctx' parameters up and down all the call trees. This closes the majority of the memory leaks in the glsl-orangebook-ch06-bump.frag test: total heap usage: 55,623 allocs, 42,672 frees (was 14,533 frees) Now 76.7% leak-free. Woo-hoo! --- ast_function.cpp | 53 +++++++------ ast_to_hir.cpp | 181 +++++++++++++++++++++++-------------------- glsl_types.cpp | 128 ++++++++++++++++-------------- hir_field_selection.cpp | 5 +- ir.cpp | 25 ++++-- ir_clone.cpp | 47 +++++++---- ir_constant_expression.cpp | 11 ++- ir_copy_propagation.cpp | 3 +- ir_dead_code.cpp | 3 +- ir_dead_code_local.cpp | 3 +- ir_expression_flattening.cpp | 11 +-- ir_function_inlining.cpp | 15 ++-- ir_reader.cpp | 50 ++++++++---- ir_variable.cpp | 2 +- ir_vec_index_to_swizzle.cpp | 4 +- list.h | 25 ++++++ s_expression.cpp | 16 ++-- s_expression.h | 4 +- 18 files changed, 351 insertions(+), 235 deletions(-) diff --git a/ast_function.cpp b/ast_function.cpp index ff2dfa502f..866cbc4ecd 100644 --- a/ast_function.cpp +++ b/ast_function.cpp @@ -54,6 +54,8 @@ process_call(exec_list *instructions, ir_function *f, YYLTYPE *loc, exec_list *actual_parameters, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); + const ir_function_signature *sig = f->matching_signature(actual_parameters); @@ -93,7 +95,7 @@ process_call(exec_list *instructions, ir_function *f, /* FINISHME: The list of actual parameters needs to be modified to * FINISHME: include any necessary conversions. */ - return new ir_call(sig, actual_parameters); + return new(ctx) ir_call(sig, actual_parameters); } else { /* FINISHME: Log a better error message here. G++ will show the types * FINISHME: of the actual parameters and the set of candidate @@ -132,6 +134,7 @@ match_function_by_name(exec_list *instructions, const char *name, static ir_rvalue * convert_component(ir_rvalue *src, const glsl_type *desired_type) { + void *ctx = talloc_parent(src); const unsigned a = desired_type->base_type; const unsigned b = src->type->base_type; ir_expression *result = NULL; @@ -149,22 +152,22 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) case GLSL_TYPE_UINT: case GLSL_TYPE_INT: if (b == GLSL_TYPE_FLOAT) - result = new ir_expression(ir_unop_f2i, desired_type, src, NULL); + result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL); else { assert(b == GLSL_TYPE_BOOL); - result = new ir_expression(ir_unop_b2i, desired_type, src, NULL); + result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL); } break; case GLSL_TYPE_FLOAT: switch (b) { case GLSL_TYPE_UINT: - result = new ir_expression(ir_unop_u2f, desired_type, src, NULL); + result = new(ctx) ir_expression(ir_unop_u2f, desired_type, src, NULL); break; case GLSL_TYPE_INT: - result = new ir_expression(ir_unop_i2f, desired_type, src, NULL); + result = new(ctx) ir_expression(ir_unop_i2f, desired_type, src, NULL); break; case GLSL_TYPE_BOOL: - result = new ir_expression(ir_unop_b2f, desired_type, src, NULL); + result = new(ctx) ir_expression(ir_unop_b2f, desired_type, src, NULL); break; } break; @@ -172,12 +175,12 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) ir_constant *zero = NULL; switch (b) { - case GLSL_TYPE_UINT: zero = new ir_constant(unsigned(0)); break; - case GLSL_TYPE_INT: zero = new ir_constant(int(0)); break; - case GLSL_TYPE_FLOAT: zero = new ir_constant(0.0f); break; + case GLSL_TYPE_UINT: zero = new(ctx) ir_constant(unsigned(0)); break; + case GLSL_TYPE_INT: zero = new(ctx) ir_constant(int(0)); break; + case GLSL_TYPE_FLOAT: zero = new(ctx) ir_constant(0.0f); break; } - result = new ir_expression(ir_binop_nequal, desired_type, src, zero); + result = new(ctx) ir_expression(ir_binop_nequal, desired_type, src, zero); } } @@ -194,6 +197,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type) static ir_rvalue * dereference_component(ir_rvalue *src, unsigned component) { + void *ctx = talloc_parent(src); assert(component < src->type->components()); /* If the source is a constant, just create a new constant instead of a @@ -201,12 +205,12 @@ dereference_component(ir_rvalue *src, unsigned component) */ ir_constant *constant = src->as_constant(); if (constant) - return new ir_constant(constant, component); + return new(ctx) ir_constant(constant, component); if (src->type->is_scalar()) { return src; } else if (src->type->is_vector()) { - return new ir_swizzle(src, component, 0, 0, 0, 1); + return new(ctx) ir_swizzle(src, component, 0, 0, 0, 1); } else { assert(src->type->is_matrix()); @@ -215,8 +219,8 @@ dereference_component(ir_rvalue *src, unsigned component) */ const int c = component / src->type->column_type()->vector_elements; const int r = component % src->type->column_type()->vector_elements; - ir_constant *const col_index = new ir_constant(c); - ir_dereference *const col = new ir_dereference_array(src, col_index); + ir_constant *const col_index = new(ctx) ir_constant(c); + ir_dereference *const col = new(ctx) ir_dereference_array(src, col_index); col->type = src->type->column_type(); @@ -306,6 +310,7 @@ constant_record_constructor(const glsl_type *constructor_type, YYLTYPE *loc, exec_list *parameters, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); bool all_parameters_are_constant = true; exec_node *node = parameters->head; @@ -338,7 +343,7 @@ constant_record_constructor(const glsl_type *constructor_type, if (!all_parameters_are_constant) return NULL; - return new ir_constant(constructor_type, parameters); + return new(ctx) ir_constant(constructor_type, parameters); } @@ -440,6 +445,7 @@ ir_rvalue * ast_function_expression::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); /* There are three sorts of function calls. * * 1. contstructors - The first subexpression is an ast_type_specifier. @@ -574,11 +580,13 @@ ast_function_expression::hir(exec_list *instructions, * glsl-vs-constructor-call.shader_test. */ if (result->type->components() >= 1 && !result->as_constant()) { - result_var = new ir_variable(result->type, "constructor_tmp"); + result_var = new(ctx) ir_variable(result->type, + "constructor_tmp"); ir_dereference_variable *lhs; - lhs = new ir_dereference_variable(result_var); - instructions->push_tail(new ir_assignment(lhs, result, NULL)); + lhs = new(ctx) ir_dereference_variable(result_var); + instructions->push_tail(new(ctx) ir_assignment(lhs, + result, NULL)); } /* Process each of the components of the parameter. Dereference @@ -592,7 +600,7 @@ ast_function_expression::hir(exec_list *instructions, ir_rvalue *component; if (result_var) { - ir_dereference *d = new ir_dereference_variable(result_var); + ir_dereference *d = new(ctx) ir_dereference_variable(result_var); component = dereference_component(d, i); } else { component = dereference_component(result, i); @@ -674,7 +682,8 @@ ast_function_expression::hir(exec_list *instructions, */ if (all_parameters_are_constant) { if (components_used >= type_components) - return new ir_constant(sig->return_type, & actual_parameters); + return new(ctx) ir_constant(sig->return_type, + & actual_parameters); assert(sig->return_type->is_vector() || sig->return_type->is_matrix()); @@ -695,9 +704,9 @@ ast_function_expression::hir(exec_list *instructions, generate_constructor_vector(sig->return_type, initializer, &data); - return new ir_constant(sig->return_type, &data); + return new(ctx) ir_constant(sig->return_type, &data); } else - return new ir_call(sig, & actual_parameters); + return new(ctx) ir_call(sig, & actual_parameters); } else { /* FINISHME: Log a better error message here. G++ will show the * FINSIHME: types of the actual parameters and the set of diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index c70f0f9de9..eafc9e8114 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -87,6 +87,7 @@ static bool apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); if (to->base_type == from->type->base_type) return true; @@ -111,13 +112,13 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, switch (from->type->base_type) { case GLSL_TYPE_INT: - from = new ir_expression(ir_unop_i2f, to, from, NULL); + from = new(ctx) ir_expression(ir_unop_i2f, to, from, NULL); break; case GLSL_TYPE_UINT: - from = new ir_expression(ir_unop_u2f, to, from, NULL); + from = new(ctx) ir_expression(ir_unop_u2f, to, from, NULL); break; case GLSL_TYPE_BOOL: - from = new ir_expression(ir_unop_b2f, to, from, NULL); + from = new(ctx) ir_expression(ir_unop_b2f, to, from, NULL); break; default: assert(0); @@ -467,6 +468,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, ir_rvalue *lhs, ir_rvalue *rhs, YYLTYPE lhs_loc) { + void *ctx = talloc_parent(state); bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); if (!error_emitted) { @@ -519,16 +521,16 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, * temporary and return a deref of that temporary. If the rvalue * ends up not being used, the temp will get copy-propagated out. */ - ir_variable *var = new ir_variable(rhs->type, "assignment_tmp"); - instructions->push_tail(new ir_assignment(new ir_dereference_variable(var), - rhs, - NULL)); + ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp"); + instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), + rhs, + NULL)); - instructions->push_tail(new ir_assignment(lhs, - new ir_dereference_variable(var), - NULL)); + instructions->push_tail(new(ctx) ir_assignment(lhs, + new(ctx) ir_dereference_variable(var), + NULL)); - return new ir_dereference_variable(var); + return new(ctx) ir_dereference_variable(var); } @@ -539,12 +541,13 @@ static ir_variable * generate_temporary(const glsl_type *type, exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); char *name = (char *) malloc(sizeof(char) * 13); snprintf(name, 13, "tmp_%08X", state->temp_index); state->temp_index++; - ir_variable *const var = new ir_variable(type, name); + ir_variable *const var = new(ctx) ir_variable(type, name); instructions->push_tail(var); return var; @@ -554,21 +557,22 @@ generate_temporary(const glsl_type *type, exec_list *instructions, static ir_rvalue * get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) { + void *ctx = talloc_parent(lvalue); ir_variable *var; /* FINISHME: Give unique names to the temporaries. */ - var = new ir_variable(lvalue->type, "_post_incdec_tmp"); + var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp"); var->mode = ir_var_auto; - instructions->push_tail(new ir_assignment(new ir_dereference_variable(var), - lvalue, NULL)); + instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), + lvalue, NULL)); /* Once we've created this temporary, mark it read only so it's no * longer considered an lvalue. */ var->read_only = true; - return new ir_dereference_variable(var); + return new(ctx) ir_dereference_variable(var); } @@ -587,6 +591,7 @@ ir_rvalue * ast_expression::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); static const int operations[AST_NUM_OPERATORS] = { -1, /* ast_assign doesn't convert to ir_expression. */ -1, /* ast_plus doesn't convert to ir_expression. */ @@ -679,8 +684,8 @@ ast_expression::hir(exec_list *instructions, error_emitted = type->is_error(); - result = new ir_expression(operations[this->oper], type, - op[0], NULL); + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], NULL); break; case ast_add: @@ -695,8 +700,8 @@ ast_expression::hir(exec_list *instructions, state, & loc); error_emitted = type->is_error(); - result = new ir_expression(operations[this->oper], type, - op[0], op[1]); + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); break; case ast_mod: @@ -707,8 +712,8 @@ ast_expression::hir(exec_list *instructions, assert(operations[this->oper] == ir_binop_mod); - result = new ir_expression(operations[this->oper], type, - op[0], op[1]); + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); error_emitted = type->is_error(); break; @@ -734,8 +739,8 @@ ast_expression::hir(exec_list *instructions, || ((type->base_type == GLSL_TYPE_BOOL) && type->is_scalar())); - result = new ir_expression(operations[this->oper], type, - op[0], op[1]); + result = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); error_emitted = type->is_error(); break; @@ -766,8 +771,8 @@ ast_expression::hir(exec_list *instructions, error_emitted = true; } - result = new ir_expression(operations[this->oper], glsl_type::bool_type, - op[0], op[1]); + result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, + op[0], op[1]); type = glsl_type::bool_type; assert(result->type == glsl_type::bool_type); @@ -811,7 +816,7 @@ ast_expression::hir(exec_list *instructions, } type = glsl_type::bool_type; } else { - ir_if *const stmt = new ir_if(op[0]); + ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); op[1] = this->subexpressions[1]->hir(&stmt->then_instructions, state); @@ -828,17 +833,17 @@ ast_expression::hir(exec_list *instructions, ir_variable *const tmp = generate_temporary(glsl_type::bool_type, instructions, state); - ir_dereference *const then_deref = new ir_dereference_variable(tmp); + ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = - new ir_assignment(then_deref, op[1], NULL); + new(ctx) ir_assignment(then_deref, op[1], NULL); stmt->then_instructions.push_tail(then_assign); - ir_dereference *const else_deref = new ir_dereference_variable(tmp); + ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = - new ir_assignment(else_deref, new ir_constant(false), NULL); + new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL); stmt->else_instructions.push_tail(else_assign); - result = new ir_dereference_variable(tmp); + result = new(ctx) ir_dereference_variable(tmp); type = tmp->type; } break; @@ -874,7 +879,7 @@ ast_expression::hir(exec_list *instructions, } type = glsl_type::bool_type; } else { - ir_if *const stmt = new ir_if(op[0]); + ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); ir_variable *const tmp = generate_temporary(glsl_type::bool_type, @@ -890,17 +895,17 @@ ast_expression::hir(exec_list *instructions, error_emitted = true; } - ir_dereference *const then_deref = new ir_dereference_variable(tmp); + ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = - new ir_assignment(then_deref, new ir_constant(true), NULL); + new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL); stmt->then_instructions.push_tail(then_assign); - ir_dereference *const else_deref = new ir_dereference_variable(tmp); + ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = - new ir_assignment(else_deref, op[1], NULL); + new(ctx) ir_assignment(else_deref, op[1], NULL); stmt->else_instructions.push_tail(else_assign); - result = new ir_dereference_variable(tmp); + result = new(ctx) ir_dereference_variable(tmp); type = tmp->type; } break; @@ -911,8 +916,8 @@ ast_expression::hir(exec_list *instructions, op[1] = this->subexpressions[1]->hir(instructions, state); - result = new ir_expression(operations[this->oper], glsl_type::bool_type, - op[0], op[1]); + result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, + op[0], op[1]); type = glsl_type::bool_type; break; @@ -927,8 +932,8 @@ ast_expression::hir(exec_list *instructions, error_emitted = true; } - result = new ir_expression(operations[this->oper], glsl_type::bool_type, - op[0], NULL); + result = new(ctx) ir_expression(operations[this->oper], glsl_type::bool_type, + op[0], NULL); type = glsl_type::bool_type; break; @@ -943,8 +948,8 @@ ast_expression::hir(exec_list *instructions, (this->oper == ast_mul_assign), state, & loc); - ir_rvalue *temp_rhs = new ir_expression(operations[this->oper], type, - op[0], op[1]); + ir_rvalue *temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); result = do_assignment(instructions, state, (ir_rvalue *)op[0]->clone(NULL), temp_rhs, @@ -969,8 +974,8 @@ ast_expression::hir(exec_list *instructions, assert(operations[this->oper] == ir_binop_mod); struct ir_rvalue *temp_rhs; - temp_rhs = new ir_expression(operations[this->oper], type, - op[0], op[1]); + temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); result = do_assignment(instructions, state, (ir_rvalue *)op[0]->clone(NULL), temp_rhs, @@ -1056,22 +1061,24 @@ ast_expression::hir(exec_list *instructions, ir_variable *const tmp = generate_temporary(type, instructions, state); - ir_if *const stmt = new ir_if(op[0]); + ir_if *const stmt = new(ctx) ir_if(op[0]); instructions->push_tail(stmt); then_instructions.move_nodes_to(& stmt->then_instructions); - ir_dereference *const then_deref = new ir_dereference_variable(tmp); + ir_dereference *const then_deref = + new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = - new ir_assignment(then_deref, op[1], NULL); + new(ctx) ir_assignment(then_deref, op[1], NULL); stmt->then_instructions.push_tail(then_assign); else_instructions.move_nodes_to(& stmt->else_instructions); - ir_dereference *const else_deref = new ir_dereference_variable(tmp); + ir_dereference *const else_deref = + new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = - new ir_assignment(else_deref, op[2], NULL); + new(ctx) ir_assignment(else_deref, op[2], NULL); stmt->else_instructions.push_tail(else_assign); - result = new ir_dereference_variable(tmp); + result = new(ctx) ir_dereference_variable(tmp); } break; } @@ -1080,15 +1087,15 @@ ast_expression::hir(exec_list *instructions, case ast_pre_dec: { op[0] = this->subexpressions[0]->hir(instructions, state); if (op[0]->type->base_type == GLSL_TYPE_FLOAT) - op[1] = new ir_constant(1.0f); + op[1] = new(ctx) ir_constant(1.0f); else - op[1] = new ir_constant(1); + op[1] = new(ctx) ir_constant(1); type = arithmetic_result_type(op[0], op[1], false, state, & loc); struct ir_rvalue *temp_rhs; - temp_rhs = new ir_expression(operations[this->oper], type, - op[0], op[1]); + temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); result = do_assignment(instructions, state, (ir_rvalue *)op[0]->clone(NULL), temp_rhs, @@ -1102,17 +1109,17 @@ ast_expression::hir(exec_list *instructions, case ast_post_dec: { op[0] = this->subexpressions[0]->hir(instructions, state); if (op[0]->type->base_type == GLSL_TYPE_FLOAT) - op[1] = new ir_constant(1.0f); + op[1] = new(ctx) ir_constant(1.0f); else - op[1] = new ir_constant(1); + op[1] = new(ctx) ir_constant(1); error_emitted = op[0]->type->is_error() || op[1]->type->is_error(); type = arithmetic_result_type(op[0], op[1], false, state, & loc); struct ir_rvalue *temp_rhs; - temp_rhs = new ir_expression(operations[this->oper], type, - op[0], op[1]); + temp_rhs = new(ctx) ir_expression(operations[this->oper], type, + op[0], op[1]); /* Get a temporary of a copy of the lvalue before it's modified. * This may get thrown away later. @@ -1143,7 +1150,7 @@ ast_expression::hir(exec_list *instructions, ir_rvalue *const array = op[0]; - result = new ir_dereference_array(op[0], op[1]); + result = new(ctx) ir_dereference_array(op[0], op[1]); /* Do not use op[0] after this point. Use array. */ @@ -1259,7 +1266,7 @@ ast_expression::hir(exec_list *instructions, ir_variable *var = state->symbols->get_variable(this->primary_expression.identifier); - result = new ir_dereference_variable(var); + result = new(ctx) ir_dereference_variable(var); if (var != NULL) { type = result->type; @@ -1274,22 +1281,22 @@ ast_expression::hir(exec_list *instructions, case ast_int_constant: type = glsl_type::int_type; - result = new ir_constant(this->primary_expression.int_constant); + result = new(ctx) ir_constant(this->primary_expression.int_constant); break; case ast_uint_constant: type = glsl_type::uint_type; - result = new ir_constant(this->primary_expression.uint_constant); + result = new(ctx) ir_constant(this->primary_expression.uint_constant); break; case ast_float_constant: type = glsl_type::float_type; - result = new ir_constant(this->primary_expression.float_constant); + result = new(ctx) ir_constant(this->primary_expression.float_constant); break; case ast_bool_constant: type = glsl_type::bool_type; - result = new ir_constant(bool(this->primary_expression.bool_constant)); + result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant)); break; case ast_sequence: { @@ -1528,6 +1535,7 @@ ir_rvalue * ast_declarator_list::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); const struct glsl_type *decl_type; const char *type_name = NULL; ir_rvalue *result = NULL; @@ -1588,7 +1596,7 @@ ast_declarator_list::hir(exec_list *instructions, var_type = decl_type; } - var = new ir_variable(var_type, decl->identifier); + var = new(ctx) ir_variable(var_type, decl->identifier); /* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification; * @@ -1788,7 +1796,7 @@ ast_declarator_list::hir(exec_list *instructions, ? "attribute" : "varying"); } - ir_dereference *const lhs = new ir_dereference_variable(var); + ir_dereference *const lhs = new(ctx) ir_dereference_variable(var); ir_rvalue *rhs = decl->initializer->hir(instructions, state); /* Calculate the constant value if this is a const or uniform @@ -1866,6 +1874,7 @@ ir_rvalue * ast_parameter_declarator::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); const struct glsl_type *type; const char *name = NULL; YYLTYPE loc = this->get_location(); @@ -1913,7 +1922,7 @@ ast_parameter_declarator::hir(exec_list *instructions, } is_void = false; - ir_variable *var = new ir_variable(type, this->identifier); + ir_variable *var = new(ctx) ir_variable(type, this->identifier); /* FINISHME: Handle array declarations. Note that this requires * FINISHME: complete handling of constant expressions. @@ -1966,6 +1975,7 @@ ir_rvalue * ast_function::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); ir_function *f = NULL; ir_function_signature *sig = NULL; exec_list hir_parameters; @@ -2025,7 +2035,7 @@ ast_function::hir(exec_list *instructions, "non-function", name); sig = NULL; } else { - f = new ir_function(name); + f = new(ctx) ir_function(name); state->symbols->add_function(f->name, f); /* Emit the new function header */ @@ -2050,7 +2060,7 @@ ast_function::hir(exec_list *instructions, /* Finish storing the information about this new function in its signature. */ if (sig == NULL) { - sig = new ir_function_signature(return_type); + sig = new(ctx) ir_function_signature(return_type); f->add_signature(sig); } @@ -2115,6 +2125,7 @@ ir_rvalue * ast_jump_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); switch (mode) { case ast_return: { @@ -2140,7 +2151,7 @@ ast_jump_statement::hir(exec_list *instructions, * FINISHME: type of the enclosing function. */ - inst = new ir_return(ret); + inst = new(ctx) ir_return(ret); } else { if (state->current_function->return_type->base_type != GLSL_TYPE_VOID) { @@ -2151,7 +2162,7 @@ ast_jump_statement::hir(exec_list *instructions, "non-void", state->current_function->function_name()); } - inst = new ir_return; + inst = new(ctx) ir_return; } instructions->push_tail(inst); @@ -2188,9 +2199,9 @@ ast_jump_statement::hir(exec_list *instructions, if (loop != NULL) { ir_loop_jump *const jump = - new ir_loop_jump((mode == ast_break) - ? ir_loop_jump::jump_break - : ir_loop_jump::jump_continue); + new(ctx) ir_loop_jump((mode == ast_break) + ? ir_loop_jump::jump_break + : ir_loop_jump::jump_continue); instructions->push_tail(jump); } } @@ -2208,6 +2219,8 @@ ir_rvalue * ast_selection_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); + ir_rvalue *const condition = this->condition->hir(instructions, state); /* From page 66 (page 72 of the PDF) of the GLSL 1.50 spec: @@ -2226,7 +2239,7 @@ ast_selection_statement::hir(exec_list *instructions, "boolean"); } - ir_if *const stmt = new ir_if(condition); + ir_if *const stmt = new(ctx) ir_if(condition); if (then_statement != NULL) then_statement->hir(& stmt->then_instructions, state); @@ -2246,6 +2259,8 @@ void ast_iteration_statement::condition_to_hir(ir_loop *stmt, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); + if (condition != NULL) { ir_rvalue *const cond = condition->hir(& stmt->body_instructions, state); @@ -2261,13 +2276,13 @@ ast_iteration_statement::condition_to_hir(ir_loop *stmt, * like 'if (!condition) break;' as the loop termination condition. */ ir_rvalue *const not_cond = - new ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond, - NULL); + new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond, + NULL); - ir_if *const if_stmt = new ir_if(not_cond); + ir_if *const if_stmt = new(ctx) ir_if(not_cond); ir_jump *const break_stmt = - new ir_loop_jump(ir_loop_jump::jump_break); + new(ctx) ir_loop_jump(ir_loop_jump::jump_break); if_stmt->then_instructions.push_tail(break_stmt); stmt->body_instructions.push_tail(if_stmt); @@ -2280,6 +2295,8 @@ ir_rvalue * ast_iteration_statement::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); + /* For-loops and while-loops start a new scope, but do-while loops do not. */ if (mode != ast_do_while) @@ -2288,7 +2305,7 @@ ast_iteration_statement::hir(exec_list *instructions, if (init_statement != NULL) init_statement->hir(instructions, state); - ir_loop *const stmt = new ir_loop(); + ir_loop *const stmt = new(ctx) ir_loop(); instructions->push_tail(stmt); /* Track the current loop and / or switch-statement nesting. diff --git a/glsl_types.cpp b/glsl_types.cpp index ca19de6bec..fcc77458b2 100644 --- a/glsl_types.cpp +++ b/glsl_types.cpp @@ -150,14 +150,16 @@ const glsl_type *glsl_type::get_base_type() const ir_function * glsl_type::generate_constructor(glsl_symbol_table *symtab) const { + void *ctx = symtab; + /* Generate the function name and add it to the symbol table. */ - ir_function *const f = new ir_function(name); + ir_function *const f = new(ctx) ir_function(name); bool added = symtab->add_function(name, f); assert(added); - ir_function_signature *const sig = new ir_function_signature(this); + ir_function_signature *const sig = new(ctx) ir_function_signature(this); f->add_signature(sig); ir_variable **declarations = @@ -168,8 +170,8 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const snprintf(param_name, 10, "p%08X", i); ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY) - ? new ir_variable(fields.array, param_name) - : new ir_variable(fields.structure[i].type, param_name); + ? new(ctx) ir_variable(fields.array, param_name) + : new(ctx) ir_variable(fields.structure[i].type, param_name); var->mode = ir_var_in; declarations[i] = var; @@ -181,24 +183,26 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const * the same type as the constructor. After initializing __retval, * __retval is returned. */ - ir_variable *retval = new ir_variable(this, "__retval"); + ir_variable *retval = new(ctx) ir_variable(this, "__retval"); sig->body.push_tail(retval); for (unsigned i = 0; i < length; i++) { ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY) - ? (ir_dereference *) new ir_dereference_array(retval, new ir_constant(i)) - : (ir_dereference *) new ir_dereference_record(retval, fields.structure[i].name); + ? (ir_dereference *) new(ctx) ir_dereference_array(retval, + new(ctx) ir_constant(i)) + : (ir_dereference *) new(ctx) ir_dereference_record(retval, + fields.structure[i].name); - ir_dereference *const rhs = new ir_dereference_variable(declarations[i]); - ir_instruction *const assign = new ir_assignment(lhs, rhs, NULL); + ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]); + ir_instruction *const assign = new(ctx) ir_assignment(lhs, rhs, NULL); sig->body.push_tail(assign); } free(declarations); - ir_dereference *const retref = new ir_dereference_variable(retval); - ir_instruction *const inst = new ir_return(retref); + ir_dereference *const retref = new(ctx) ir_dereference_variable(retval); + ir_instruction *const inst = new(ctx) ir_return(retref); sig->body.push_tail(inst); return f; @@ -223,6 +227,8 @@ static ir_function_signature * generate_constructor_intro(const glsl_type *type, unsigned parameter_count, ir_variable **declarations) { + /* NULL is wrong here and leaks. */ + void *ctx = NULL; /* Names of parameters used in vector and matrix constructors */ static const char *const names[] = { @@ -234,10 +240,10 @@ generate_constructor_intro(const glsl_type *type, unsigned parameter_count, const glsl_type *const parameter_type = type->get_base_type(); - ir_function_signature *const signature = new ir_function_signature(type); + ir_function_signature *const signature = new(ctx) ir_function_signature(type); for (unsigned i = 0; i < parameter_count; i++) { - ir_variable *var = new ir_variable(parameter_type, names[i]); + ir_variable *var = new(ctx) ir_variable(parameter_type, names[i]); var->mode = ir_var_in; signature->parameters.push_tail(var); @@ -245,7 +251,7 @@ generate_constructor_intro(const glsl_type *type, unsigned parameter_count, declarations[i] = var; } - ir_variable *retval = new ir_variable(type, "__retval"); + ir_variable *retval = new(ctx) ir_variable(type, "__retval"); signature->body.push_tail(retval); declarations[16] = retval; @@ -260,26 +266,28 @@ static void generate_vec_body_from_scalar(exec_list *instructions, ir_variable **declarations) { + /* NULL is wrong here and leaks. */ + void *ctx = NULL; ir_instruction *inst; /* Generate a single assignment of the parameter to __retval.x and return * __retval.xxxx for however many vector components there are. */ ir_dereference *const lhs_ref = - new ir_dereference_variable(declarations[16]); - ir_dereference *const rhs = new ir_dereference_variable(declarations[0]); + new(ctx) ir_dereference_variable(declarations[16]); + ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]); - ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); + ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); - inst = new ir_assignment(lhs, rhs, NULL); + inst = new(ctx) ir_assignment(lhs, rhs, NULL); instructions->push_tail(inst); - ir_dereference *const retref = new ir_dereference_variable(declarations[16]); + ir_dereference *const retref = new(ctx) ir_dereference_variable(declarations[16]); - ir_swizzle *retval = new ir_swizzle(retref, 0, 0, 0, 0, - declarations[16]->type->vector_elements); + ir_swizzle *retval = new(ctx) ir_swizzle(retref, 0, 0, 0, 0, + declarations[16]->type->vector_elements); - inst = new ir_return(retval); + inst = new(ctx) ir_return(retval); instructions->push_tail(inst); } @@ -291,27 +299,28 @@ static void generate_vec_body_from_N_scalars(exec_list *instructions, ir_variable **declarations) { + /* NULL is wrong here and leaks. */ + void *ctx = NULL; ir_instruction *inst; const glsl_type *const vec_type = declarations[16]->type; - /* Generate an assignment of each parameter to a single component of * __retval.x and return __retval. */ for (unsigned i = 0; i < vec_type->vector_elements; i++) { ir_dereference *const lhs_ref = - new ir_dereference_variable(declarations[16]); - ir_dereference *const rhs = new ir_dereference_variable(declarations[i]); + new(ctx) ir_dereference_variable(declarations[16]); + ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[i]); - ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1); + ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1); - inst = new ir_assignment(lhs, rhs, NULL); + inst = new(ctx) ir_assignment(lhs, rhs, NULL); instructions->push_tail(inst); } - ir_dereference *retval = new ir_dereference_variable(declarations[16]); + ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]); - inst = new ir_return(retval); + inst = new(ctx) ir_return(retval); instructions->push_tail(inst); } @@ -323,6 +332,8 @@ static void generate_mat_body_from_scalar(exec_list *instructions, ir_variable **declarations) { + /* NULL is wrong here and leaks. */ + void *ctx = NULL; ir_instruction *inst; /* Generate an assignment of the parameter to the X component of a @@ -347,49 +358,50 @@ generate_mat_body_from_scalar(exec_list *instructions, */ const glsl_type *const column_type = declarations[16]->type->column_type(); const glsl_type *const row_type = declarations[16]->type->row_type(); - ir_variable *const column = new ir_variable(column_type, "v"); + + ir_variable *const column = new(ctx) ir_variable(column_type, "v"); instructions->push_tail(column); - ir_dereference *const lhs_ref = new ir_dereference_variable(column); - ir_dereference *const rhs = new ir_dereference_variable(declarations[0]); + ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column); + ir_dereference *const rhs = new(ctx) ir_dereference_variable(declarations[0]); - ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); + ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, 0, 0, 0, 0, 1); - inst = new ir_assignment(lhs, rhs, NULL); + inst = new(ctx) ir_assignment(lhs, rhs, NULL); instructions->push_tail(inst); for (unsigned i = 1; i < column_type->vector_elements; i++) { - ir_dereference *const lhs_ref = new ir_dereference_variable(column); - ir_constant *const zero = new ir_constant(0.0f); + ir_dereference *const lhs_ref = new(ctx) ir_dereference_variable(column); + ir_constant *const zero = new(ctx) ir_constant(0.0f); - ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1); + ir_swizzle *lhs = new(ctx) ir_swizzle(lhs_ref, i, 0, 0, 0, 1); - inst = new ir_assignment(lhs, zero, NULL); + inst = new(ctx) ir_assignment(lhs, zero, NULL); instructions->push_tail(inst); } for (unsigned i = 0; i < row_type->vector_elements; i++) { static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 }; - ir_dereference *const rhs_ref = new ir_dereference_variable(column); + ir_dereference *const rhs_ref = new(ctx) ir_dereference_variable(column); /* This will be .xyyy when i=0, .yxyy when i=1, etc. */ - ir_swizzle *rhs = new ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i], - swiz[5 - i], swiz[6 - i], - column_type->vector_elements); + ir_swizzle *rhs = new(ctx) ir_swizzle(rhs_ref, swiz[3 - i], swiz[4 - i], + swiz[5 - i], swiz[6 - i], + column_type->vector_elements); - ir_constant *const idx = new ir_constant(int(i)); + ir_constant *const idx = new(ctx) ir_constant(int(i)); ir_dereference *const lhs = - new ir_dereference_array(declarations[16], idx); + new(ctx) ir_dereference_array(declarations[16], idx); - inst = new ir_assignment(lhs, rhs, NULL); + inst = new(ctx) ir_assignment(lhs, rhs, NULL); instructions->push_tail(inst); } - ir_dereference *const retval = new ir_dereference_variable(declarations[16]); - inst = new ir_return(retval); + ir_dereference *const retval = new(ctx) ir_dereference_variable(declarations[16]); + inst = new(ctx) ir_return(retval); instructions->push_tail(inst); } @@ -401,35 +413,36 @@ static void generate_mat_body_from_N_scalars(exec_list *instructions, ir_variable **declarations) { + /* NULL is wrong here and leaks. */ + void *ctx = NULL; ir_instruction *inst; const glsl_type *const row_type = declarations[16]->type->row_type(); const glsl_type *const column_type = declarations[16]->type->column_type(); - /* Generate an assignment of each parameter to a single component of * of a particular column of __retval and return __retval. */ for (unsigned i = 0; i < column_type->vector_elements; i++) { for (unsigned j = 0; j < row_type->vector_elements; j++) { - ir_constant *row_index = new ir_constant(int(i)); + ir_constant *row_index = new(ctx) ir_constant(int(i)); ir_dereference *const row_access = - new ir_dereference_array(declarations[16], row_index); + new(ctx) ir_dereference_array(declarations[16], row_index); - ir_swizzle *component_access = new ir_swizzle(row_access, - j, 0, 0, 0, 1); + ir_swizzle *component_access = new(ctx) ir_swizzle(row_access, + j, 0, 0, 0, 1); const unsigned param = (i * row_type->vector_elements) + j; ir_dereference *const rhs = - new ir_dereference_variable(declarations[param]); + new(ctx) ir_dereference_variable(declarations[param]); - inst = new ir_assignment(component_access, rhs, NULL); + inst = new(ctx) ir_assignment(component_access, rhs, NULL); instructions->push_tail(inst); } } - ir_dereference *retval = new ir_dereference_variable(declarations[16]); + ir_dereference *retval = new(ctx) ir_dereference_variable(declarations[16]); - inst = new ir_return(retval); + inst = new(ctx) ir_return(retval); instructions->push_tail(inst); } @@ -444,6 +457,7 @@ static void generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types, unsigned num_types, exec_list *instructions) { + void *ctx = symtab; ir_variable *declarations[17]; for (unsigned i = 0; i < num_types; i++) { @@ -459,7 +473,7 @@ generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types, /* Generate the function block, add it to the symbol table, and emit it. */ - ir_function *const f = new ir_function(types[i].name); + ir_function *const f = new(ctx) ir_function(types[i].name); bool added = symtab->add_function(types[i].name, f); assert(added); diff --git a/hir_field_selection.cpp b/hir_field_selection.cpp index e60ea30d7f..6da14925b9 100644 --- a/hir_field_selection.cpp +++ b/hir_field_selection.cpp @@ -33,6 +33,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr, exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); ir_rvalue *result = NULL; ir_rvalue *op; @@ -62,8 +63,8 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr, expr->primary_expression.identifier); } } else if (op->type->base_type == GLSL_TYPE_STRUCT) { - result = new ir_dereference_record(op, - expr->primary_expression.identifier); + result = new(ctx) ir_dereference_record(op, + expr->primary_expression.identifier); if (result->type->is_error()) { _mesa_glsl_error(& loc, state, "Cannot access field `%s' of " diff --git a/ir.cpp b/ir.cpp index 98b085e91b..26cd475552 100644 --- a/ir.cpp +++ b/ir.cpp @@ -300,15 +300,17 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) ir_instruction * ir_constant::clone(struct hash_table *ht) const { + void *ctx = talloc_parent(this); + switch (this->type->base_type) { case GLSL_TYPE_UINT: case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: case GLSL_TYPE_BOOL: - return new ir_constant(this->type, &this->value); + return new(ctx) ir_constant(this->type, &this->value); case GLSL_TYPE_STRUCT: { - ir_constant *c = new ir_constant; + ir_constant *c = new(ctx)ir_constant; c->type = this->type; for (exec_node *node = this->components.head @@ -497,8 +499,10 @@ ir_dereference_array::ir_dereference_array(ir_rvalue *value, ir_dereference_array::ir_dereference_array(ir_variable *var, ir_rvalue *array_index) { + void *ctx = talloc_parent(var); + this->array_index = array_index; - this->set_array(new ir_dereference_variable(var)); + this->set_array(new(ctx) ir_dereference_variable(var)); } @@ -535,7 +539,9 @@ ir_dereference_record::ir_dereference_record(ir_rvalue *value, ir_dereference_record::ir_dereference_record(ir_variable *var, const char *field) { - this->record = new ir_dereference_variable(var); + void *ctx = talloc_parent(var); + + this->record = new(ctx) ir_dereference_variable(var); this->field = field; this->type = (this->record != NULL) ? this->record->type->field_type(field) : glsl_type::error_type; @@ -646,6 +652,8 @@ ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) ir_swizzle * ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length) { + void *ctx = talloc_parent(val); + /* For each possible swizzle character, this table encodes the value in * \c idx_map that represents the 0th element of the vector. For invalid * swizzle characters (e.g., 'k'), a special value is used that will allow @@ -710,8 +718,8 @@ ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length) if (str[i] != '\0') return NULL; - return new ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2], - swiz_idx[3], i); + return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2], + swiz_idx[3], i); } #undef X @@ -811,7 +819,6 @@ ir_function_signature::replace_parameters(exec_list *new_params) assert(((ir_instruction *) iter.get())->as_variable() != NULL); iter.remove(); - delete (ir_instruction*) iter.get(); } new_params->move_nodes_to(¶meters); @@ -828,7 +835,9 @@ ir_function::ir_function(const char *name) ir_call * ir_call::get_error_instruction() { - ir_call *call = new ir_call; + /* NULL is wrong and leaks */ + void *ctx = NULL; + ir_call *call = new(ctx) ir_call; call->type = glsl_type::error_type; return call; diff --git a/ir_clone.cpp b/ir_clone.cpp index c810fe8616..5ffd3fc00b 100644 --- a/ir_clone.cpp +++ b/ir_clone.cpp @@ -36,7 +36,8 @@ ir_instruction * ir_variable::clone(struct hash_table *ht) const { - ir_variable *var = new ir_variable(type, name); + void *ctx = talloc_parent(this); + ir_variable *var = new(ctx) ir_variable(type, name); var->max_array_access = this->max_array_access; var->read_only = this->read_only; @@ -55,32 +56,36 @@ ir_variable::clone(struct hash_table *ht) const ir_instruction * ir_swizzle::clone(struct hash_table *ht) const { - return new ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask); + void *ctx = talloc_parent(this); + return new(ctx) ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask); } ir_instruction * ir_return::clone(struct hash_table *ht) const { + void *ctx = talloc_parent(this); ir_rvalue *new_value = NULL; if (this->value) new_value = (ir_rvalue *)this->value->clone(ht); - return new ir_return(new_value); + return new(ctx) ir_return(new_value); } ir_instruction * ir_loop_jump::clone(struct hash_table *ht) const { + void *ctx = talloc_parent(this); (void)ht; - return new ir_loop_jump(this->mode); + return new(ctx) ir_loop_jump(this->mode); } ir_instruction * ir_if::clone(struct hash_table *ht) const { - ir_if *new_if = new ir_if((ir_rvalue *)this->condition->clone(ht)); + void *ctx = talloc_parent(this); + ir_if *new_if = new(ctx) ir_if((ir_rvalue *)this->condition->clone(ht)); foreach_iter(exec_list_iterator, iter, this->then_instructions) { ir_instruction *ir = (ir_instruction *)iter.get(); @@ -98,7 +103,8 @@ ir_if::clone(struct hash_table *ht) const ir_instruction * ir_loop::clone(struct hash_table *ht) const { - ir_loop *new_loop = new ir_loop(); + void *ctx = talloc_parent(this); + ir_loop *new_loop = new(ctx) ir_loop(); if (this->from) new_loop->from = (ir_rvalue *)this->from->clone(ht); @@ -119,6 +125,7 @@ ir_loop::clone(struct hash_table *ht) const ir_instruction * ir_call::clone(struct hash_table *ht) const { + void *ctx = talloc_parent(this); exec_list new_parameters; foreach_iter(exec_list_iterator, iter, this->actual_parameters) { @@ -126,12 +133,13 @@ ir_call::clone(struct hash_table *ht) const new_parameters.push_tail(ir->clone(ht)); } - return new ir_call(this->callee, &new_parameters); + return new(ctx) ir_call(this->callee, &new_parameters); } ir_instruction * ir_expression::clone(struct hash_table *ht) const { + void *ctx = talloc_parent(this); ir_rvalue *op[2] = {NULL, NULL}; unsigned int i; @@ -139,12 +147,13 @@ ir_expression::clone(struct hash_table *ht) const op[i] = (ir_rvalue *)this->operands[i]->clone(ht); } - return new ir_expression(this->operation, this->type, op[0], op[1]); + return new(ctx) ir_expression(this->operation, this->type, op[0], op[1]); } ir_instruction * ir_dereference_variable::clone(struct hash_table *ht) const { + void *ctx = talloc_parent(this); ir_variable *new_var; if (ht) { @@ -155,27 +164,30 @@ ir_dereference_variable::clone(struct hash_table *ht) const new_var = this->var; } - return new ir_dereference_variable(new_var); + return new(ctx) ir_dereference_variable(new_var); } ir_instruction * ir_dereference_array::clone(struct hash_table *ht) const { - return new ir_dereference_array((ir_rvalue *)this->array->clone(ht), - (ir_rvalue *)this->array_index->clone(ht)); + void *ctx = talloc_parent(this); + return new(ctx) ir_dereference_array((ir_rvalue *)this->array->clone(ht), + (ir_rvalue *)this->array_index->clone(ht)); } ir_instruction * ir_dereference_record::clone(struct hash_table *ht) const { - return new ir_dereference_record((ir_rvalue *)this->record->clone(ht), - this->field); + void *ctx = talloc_parent(this); + return new(ctx) ir_dereference_record((ir_rvalue *)this->record->clone(ht), + this->field); } ir_instruction * ir_texture::clone(struct hash_table *ht) const { - ir_texture *new_tex = new ir_texture(this->op); + void *ctx = talloc_parent(this); + ir_texture *new_tex = new(ctx) ir_texture(this->op); new_tex->sampler = (ir_dereference *)this->sampler->clone(ht); new_tex->coordinate = (ir_rvalue *)this->coordinate->clone(ht); @@ -218,9 +230,10 @@ ir_assignment::clone(struct hash_table *ht) const if (this->condition) new_condition = (ir_rvalue *)this->condition->clone(ht); - return new ir_assignment((ir_rvalue *)this->lhs->clone(ht), - (ir_rvalue *)this->rhs->clone(ht), - new_condition); + void *ctx = talloc_parent(this); + return new(ctx) ir_assignment((ir_rvalue *)this->lhs->clone(ht), + (ir_rvalue *)this->rhs->clone(ht), + new_condition); } ir_instruction * diff --git a/ir_constant_expression.cpp b/ir_constant_expression.cpp index effb88844e..4010e46267 100644 --- a/ir_constant_expression.cpp +++ b/ir_constant_expression.cpp @@ -127,6 +127,7 @@ ir_constant_visitor::visit(ir_function *ir) void ir_constant_visitor::visit(ir_expression *ir) { + void *ctx = talloc_parent(ir); value = NULL; ir_constant *op[2]; unsigned int operand, c; @@ -497,7 +498,7 @@ ir_constant_visitor::visit(ir_expression *ir) return; } - this->value = new ir_constant(ir->type, &data); + this->value = new(ctx) ir_constant(ir->type, &data); } @@ -513,6 +514,7 @@ ir_constant_visitor::visit(ir_texture *ir) void ir_constant_visitor::visit(ir_swizzle *ir) { + void *ctx = talloc_parent(ir); ir_constant *v = ir->val->constant_expression_value(); this->value = NULL; @@ -534,7 +536,7 @@ ir_constant_visitor::visit(ir_swizzle *ir) } } - this->value = new ir_constant(ir->type, &data); + this->value = new(ctx) ir_constant(ir->type, &data); } } @@ -553,6 +555,7 @@ ir_constant_visitor::visit(ir_dereference_variable *ir) void ir_constant_visitor::visit(ir_dereference_array *ir) { + void *ctx = talloc_parent(ir); ir_constant *array = ir->array->constant_expression_value(); ir_constant *idx = ir->array_index->constant_expression_value(); @@ -592,11 +595,11 @@ ir_constant_visitor::visit(ir_dereference_array *ir) break; } - this->value = new ir_constant(column_type, &data); + this->value = new(ctx) ir_constant(column_type, &data); } else if (array->type->is_vector()) { const unsigned component = idx->value.u[0]; - this->value = new ir_constant(array, component); + this->value = new(ctx) ir_constant(array, component); } else { /* FINISHME: Handle access of constant arrays. */ } diff --git a/ir_copy_propagation.cpp b/ir_copy_propagation.cpp index 16a2ba79bf..46ef6679d9 100644 --- a/ir_copy_propagation.cpp +++ b/ir_copy_propagation.cpp @@ -197,6 +197,7 @@ kill_invalidated_copies(ir_assignment *ir, exec_list *acp) static void add_copy(ir_assignment *ir, exec_list *acp) { + void *ctx = talloc_parent(ir); acp_entry *entry; if (ir->condition) { @@ -209,7 +210,7 @@ add_copy(ir_assignment *ir, exec_list *acp) ir_variable *rhs_var = ir->rhs->whole_variable_referenced(); if ((lhs_var != NULL) && (rhs_var != NULL)) { - entry = new acp_entry(lhs_var, rhs_var); + entry = new(ctx) acp_entry(lhs_var, rhs_var); acp->push_tail(entry); } } diff --git a/ir_dead_code.cpp b/ir_dead_code.cpp index 8465d863aa..01b7d2d832 100644 --- a/ir_dead_code.cpp +++ b/ir_dead_code.cpp @@ -77,6 +77,7 @@ public: variable_entry * ir_dead_code_visitor::get_variable_entry(ir_variable *var) { + void *ctx = talloc_parent(var); assert(var); foreach_iter(exec_list_iterator, iter, this->variable_list) { variable_entry *entry = (variable_entry *)iter.get(); @@ -84,7 +85,7 @@ ir_dead_code_visitor::get_variable_entry(ir_variable *var) return entry; } - variable_entry *entry = new variable_entry(var); + variable_entry *entry = new(ctx) variable_entry(var); this->variable_list.push_tail(entry); return entry; } diff --git a/ir_dead_code_local.cpp b/ir_dead_code_local.cpp index d3b3858617..e01877077c 100644 --- a/ir_dead_code_local.cpp +++ b/ir_dead_code_local.cpp @@ -113,6 +113,7 @@ public: static bool process_assignment(ir_assignment *ir, exec_list *assignments) { + void *ctx = talloc_parent(ir); ir_variable *var = NULL; bool progress = false; kill_for_derefs_visitor v(assignments); @@ -157,7 +158,7 @@ process_assignment(ir_assignment *ir, exec_list *assignments) } /* Add this instruction to the assignment list. */ - assignment_entry *entry = new assignment_entry(var, ir); + assignment_entry *entry = new(ctx) assignment_entry(var, ir); assignments->push_tail(entry); if (debug) { diff --git a/ir_expression_flattening.cpp b/ir_expression_flattening.cpp index 3089f17ae1..5ba24e390b 100644 --- a/ir_expression_flattening.cpp +++ b/ir_expression_flattening.cpp @@ -80,18 +80,19 @@ do_expression_flattening(exec_list *instructions, static ir_rvalue * operand_to_temp(ir_instruction *base_ir, ir_rvalue *ir) { + void *ctx = talloc_parent(base_ir); ir_variable *var; ir_assignment *assign; - var = new ir_variable(ir->type, "flattening_tmp"); + var = new(ctx) ir_variable(ir->type, "flattening_tmp"); base_ir->insert_before(var); - assign = new ir_assignment(new ir_dereference_variable(var), - ir, - NULL); + assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), + ir, + NULL); base_ir->insert_before(assign); - return new ir_dereference_variable(var); + return new(ctx) ir_dereference_variable(var); } ir_visitor_status diff --git a/ir_function_inlining.cpp b/ir_function_inlining.cpp index effb01c8f6..8a1cf4f1d2 100644 --- a/ir_function_inlining.cpp +++ b/ir_function_inlining.cpp @@ -94,6 +94,7 @@ do_function_inlining(exec_list *instructions) ir_rvalue * ir_call::generate_inline(ir_instruction *next_ir) { + void *ctx = talloc_parent(this); ir_variable **parameters; int num_parameters; int i; @@ -110,7 +111,7 @@ ir_call::generate_inline(ir_instruction *next_ir) /* Generate storage for the return value. */ if (this->callee->return_type) { - retval = new ir_variable(this->callee->return_type, "__retval"); + retval = new(ctx) ir_variable(this->callee->return_type, "__retval"); next_ir->insert_before(retval); } @@ -133,8 +134,8 @@ ir_call::generate_inline(ir_instruction *next_ir) parameters[i]->mode == ir_var_inout) { ir_assignment *assign; - assign = new ir_assignment(new ir_dereference_variable(parameters[i]), - param, NULL); + assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]), + param, NULL); next_ir->insert_before(assign); } @@ -162,9 +163,9 @@ ir_call::generate_inline(ir_instruction *next_ir) parameters[i]->mode == ir_var_inout) { ir_assignment *assign; - assign = new ir_assignment(param->as_rvalue(), - new ir_dereference_variable(parameters[i]), - NULL); + assign = new(ctx) ir_assignment(param->as_rvalue(), + new(ctx) ir_dereference_variable(parameters[i]), + NULL); next_ir->insert_before(assign); } @@ -176,7 +177,7 @@ ir_call::generate_inline(ir_instruction *next_ir) hash_table_dtor(ht); if (retval) - return new ir_dereference_variable(retval); + return new(ctx) ir_dereference_variable(retval); else return NULL; } diff --git a/ir_reader.cpp b/ir_reader.cpp index ee320ddac2..d6985c4981 100644 --- a/ir_reader.cpp +++ b/ir_reader.cpp @@ -70,7 +70,8 @@ void _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions, const char *src) { - s_expression *expr = s_expression::read_expression(src); + void *ctx = talloc_parent(state); + s_expression *expr = s_expression::read_expression(ctx, src); if (expr == NULL) { ir_read_error(state, NULL, "couldn't parse S-Expression."); return; @@ -190,6 +191,7 @@ scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions, static ir_function * read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body) { + void *ctx = talloc_parent(st); if (list->length() < 3) { ir_read_error(st, list, "Expected (function (signature ...) ...)"); return NULL; @@ -203,7 +205,7 @@ read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body) ir_function *f = st->symbols->get_function(name->value()); if (f == NULL) { - f = new ir_function(name->value()); + f = new(ctx) ir_function(name->value()); bool added = st->symbols->add_function(name->value(), f); assert(added); } @@ -233,6 +235,7 @@ static void read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list, bool skip_body) { + void *ctx = talloc_parent(st); if (list->length() != 4) { ir_read_error(st, list, "Expected (signature (parameters ...) " "( ...))"); @@ -286,7 +289,7 @@ read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list, return; } } else { - sig = new ir_function_signature(return_type); + sig = new(ctx) ir_function_signature(return_type); f->add_signature(sig); } @@ -331,12 +334,13 @@ static ir_instruction * read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, ir_loop *loop_ctx) { + void *ctx = talloc_parent(st); s_symbol *symbol = SX_AS_SYMBOL(expr); if (symbol != NULL) { if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL) - return new ir_loop_jump(ir_loop_jump::jump_break); + return new(ctx) ir_loop_jump(ir_loop_jump::jump_break); if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL) - return new ir_loop_jump(ir_loop_jump::jump_continue); + return new(ctx) ir_loop_jump(ir_loop_jump::jump_continue); } s_list *list = SX_AS_LIST(expr); @@ -372,6 +376,7 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, static ir_variable * read_declaration(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 4) { ir_read_error(st, list, "expected (declare () " ")"); @@ -395,7 +400,7 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - ir_variable *var = new ir_variable(type, var_name->value()); + ir_variable *var = new(ctx) ir_variable(type, var_name->value()); foreach_iter(exec_list_iterator, it, quals->subexpressions) { s_symbol *qualifier = SX_AS_SYMBOL(it.get()); @@ -443,6 +448,7 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list) static ir_if * read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx) { + void *ctx = talloc_parent(st); if (list->length() != 4) { ir_read_error(st, list, "expected (if ( ...) " "( ...))"); @@ -459,7 +465,7 @@ read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx) s_expression *then_expr = (s_expression*) cond_expr->next; s_expression *else_expr = (s_expression*) then_expr->next; - ir_if *iff = new ir_if(condition); + ir_if *iff = new(ctx) ir_if(condition); read_instructions(st, &iff->then_instructions, then_expr, loop_ctx); read_instructions(st, &iff->else_instructions, else_expr, loop_ctx); @@ -474,6 +480,7 @@ read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx) static ir_loop * read_loop(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 6) { ir_read_error(st, list, "expected (loop " " )"); @@ -488,7 +495,7 @@ read_loop(_mesa_glsl_parse_state *st, s_list *list) // FINISHME: actually read the count/from/to fields. - ir_loop *loop = new ir_loop; + ir_loop *loop = new(ctx) ir_loop; read_instructions(st, &loop->body_instructions, body_expr, loop); if (st->error) { delete loop; @@ -501,6 +508,7 @@ read_loop(_mesa_glsl_parse_state *st, s_list *list) static ir_return * read_return(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 2) { ir_read_error(st, list, "expected (return )"); return NULL; @@ -514,7 +522,7 @@ read_return(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - return new ir_return(retval); + return new(ctx) ir_return(retval); } @@ -556,6 +564,7 @@ read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr) static ir_assignment * read_assignment(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 4) { ir_read_error(st, list, "expected (assign )"); return NULL; @@ -584,12 +593,13 @@ read_assignment(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - return new ir_assignment(lhs, rhs, condition); + return new(ctx) ir_assignment(lhs, rhs, condition); } static ir_call * read_call(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 3) { ir_read_error(st, list, "expected (call ( ...))"); return NULL; @@ -628,12 +638,13 @@ read_call(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - return new ir_call(callee, ¶meters); + return new(ctx) ir_call(callee, ¶meters); } static ir_expression * read_expression(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); const unsigned list_length = list->length(); if (list_length < 4) { ir_read_error(st, list, "expected (expression " @@ -693,7 +704,7 @@ read_expression(_mesa_glsl_parse_state *st, s_list *list) } } - return new ir_expression(op, type, arg1, arg2); + return new(ctx) ir_expression(op, type, arg1, arg2); } static ir_swizzle * @@ -738,6 +749,7 @@ read_swizzle(_mesa_glsl_parse_state *st, s_list *list) static ir_constant * read_constant(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 3) { ir_read_error(st, list, "expected (constant ( ... ))"); return NULL; @@ -803,7 +815,7 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list) ++k; } - return new ir_constant(type, &data); + return new(ctx) ir_constant(type, &data); } static ir_dereference * @@ -828,6 +840,7 @@ read_dereference(_mesa_glsl_parse_state *st, s_expression *expr) static ir_dereference * read_var_ref(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 2) { ir_read_error(st, list, "expected (var_ref )"); return NULL; @@ -844,12 +857,13 @@ read_var_ref(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - return new ir_dereference_variable(var); + return new(ctx) ir_dereference_variable(var); } static ir_dereference * read_array_ref(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 3) { ir_read_error(st, list, "expected (array_ref )"); return NULL; @@ -864,12 +878,13 @@ read_array_ref(_mesa_glsl_parse_state *st, s_list *list) s_expression *idx_expr = (s_expression*) subj_expr->next; ir_rvalue *idx = read_rvalue(st, idx_expr); - return new ir_dereference_array(subject, idx); + return new(ctx) ir_dereference_array(subject, idx); } static ir_dereference * read_record_ref(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); if (list->length() != 3) { ir_read_error(st, list, "expected (record_ref )"); return NULL; @@ -887,7 +902,7 @@ read_record_ref(_mesa_glsl_parse_state *st, s_list *list) ir_read_error(st, list, "expected (record_ref ... )"); return NULL; } - return new ir_dereference_record(subject, field->value()); + return new(ctx) ir_dereference_record(subject, field->value()); } static bool @@ -905,6 +920,7 @@ valid_texture_list_length(ir_texture_opcode op, s_list *list) static ir_texture * read_texture(_mesa_glsl_parse_state *st, s_list *list) { + void *ctx = talloc_parent(st); s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head); assert(tag != NULL); @@ -917,7 +933,7 @@ read_texture(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - ir_texture *tex = new ir_texture(op); + ir_texture *tex = new(ctx) ir_texture(op); // Read sampler (must be a deref) s_expression *sampler_expr = (s_expression *) tag->next; diff --git a/ir_variable.cpp b/ir_variable.cpp index efebe9199f..fabd856591 100644 --- a/ir_variable.cpp +++ b/ir_variable.cpp @@ -35,7 +35,7 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot, const glsl_type *type, exec_list *instructions, glsl_symbol_table *symtab) { - ir_variable *var = new ir_variable(type, name); + ir_variable *var = new(symtab) ir_variable(type, name); var->mode = mode; switch (var->mode) { diff --git a/ir_vec_index_to_swizzle.cpp b/ir_vec_index_to_swizzle.cpp index eb0e556c9d..bbd873791a 100644 --- a/ir_vec_index_to_swizzle.cpp +++ b/ir_vec_index_to_swizzle.cpp @@ -60,6 +60,7 @@ public: ir_rvalue * ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir) { + void *ctx = talloc_parent(ir); ir_dereference_array *deref = ir->as_dereference_array(); ir_constant *ir_constant; @@ -75,7 +76,8 @@ ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir) return ir; this->progress = true; - return new ir_swizzle(deref->array, ir_constant->value.i[0], 0, 0, 0, 1); + return new(ctx) ir_swizzle(deref->array, + ir_constant->value.i[0], 0, 0, 0, 1); } ir_visitor_status diff --git a/list.h b/list.h index 0b91647be4..7732d66d7a 100644 --- a/list.h +++ b/list.h @@ -66,7 +66,13 @@ #ifndef __cplusplus #include +#include +#else +extern "C" { +#include +} #endif + #include struct exec_node { @@ -74,6 +80,25 @@ struct exec_node { struct exec_node *prev; #ifdef __cplusplus + /* 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 *node; + + node = talloc_size(ctx, size); + assert(node != NULL); + + return node; + } + + /* If the user *does* call delete, that's OK, we will just + * talloc_free in that case. */ + static void operator delete(void *node) + { + talloc_free(node); + } + exec_node() : next(NULL), prev(NULL) { /* empty */ diff --git a/s_expression.cpp b/s_expression.cpp index 0fb296ef67..875d739d84 100644 --- a/s_expression.cpp +++ b/s_expression.cpp @@ -49,7 +49,7 @@ s_list::length() const } static s_expression * -read_atom(const char *& src) +read_atom(void *ctx, const char *& src) { char buf[101]; int n; @@ -65,20 +65,20 @@ read_atom(const char *& src) int i = strtol(buf, &int_end, 10); // If strtod matched more characters, it must have a decimal part if (float_end > int_end) - return new s_float(f); + return new(ctx) s_float(f); - return new s_int(i); + return new(ctx) s_int(i); } // Not a number; return a symbol. - return new s_symbol(buf); + return new(ctx) s_symbol(buf); } s_expression * -s_expression::read_expression(const char *&src) +s_expression::read_expression(void *ctx, const char *&src) { assert(src != NULL); - s_expression *atom = read_atom(src); + s_expression *atom = read_atom(ctx, src); if (atom != NULL) return atom; @@ -87,10 +87,10 @@ s_expression::read_expression(const char *&src) if (sscanf(src, " %c%n", &c, &n) == 1 && c == '(') { src += n; - s_list *list = new s_list; + s_list *list = new(ctx) s_list; s_expression *expr; - while ((expr = read_expression(src)) != NULL) { + while ((expr = read_expression(ctx, src)) != NULL) { list->subexpressions.push_tail(expr); } if (sscanf(src, " %c%n", &c, &n) != 1 || c != ')') { diff --git a/s_expression.h b/s_expression.h index 8a4eda28da..1a0c03c218 100644 --- a/s_expression.h +++ b/s_expression.h @@ -49,8 +49,10 @@ public: /** * Read an S-Expression from the given string. * Advances the supplied pointer to just after the expression read. + * + * Any allocation will be performed with 'ctx' as the talloc owner. */ - static s_expression *read_expression(const char *&src); + static s_expression *read_expression(void *ctx, const char *&src); /** * Print out an S-Expression. Useful for debugging. -- cgit v1.2.3 From 522de3f5ecbfe3f84e92ac03d1438a44eb1beae7 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 18:19:46 -0700 Subject: Close memory leaks from generate_constructor_intro By simply propagating a 'ctx' parameter through these function calls. (We do this because these function are otherwise only receiving an exec_list, which is not a valid talloc context.) This closes 1611 leaks in the glsl-orangebook-ch06-bump.frag test: total heap usage: 55,623 allocs, 44,283 frees (was 42,672 frees) --- glsl_types.cpp | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/glsl_types.cpp b/glsl_types.cpp index fcc77458b2..7dcb4a4caf 100644 --- a/glsl_types.cpp +++ b/glsl_types.cpp @@ -224,11 +224,10 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const * the symbol table. */ static ir_function_signature * -generate_constructor_intro(const glsl_type *type, unsigned parameter_count, +generate_constructor_intro(void *ctx, + const glsl_type *type, unsigned parameter_count, ir_variable **declarations) { - /* NULL is wrong here and leaks. */ - void *ctx = NULL; /* Names of parameters used in vector and matrix constructors */ static const char *const names[] = { @@ -263,11 +262,10 @@ generate_constructor_intro(const glsl_type *type, unsigned parameter_count, * Generate the body of a vector constructor that takes a single scalar */ static void -generate_vec_body_from_scalar(exec_list *instructions, +generate_vec_body_from_scalar(void *ctx, + exec_list *instructions, ir_variable **declarations) { - /* NULL is wrong here and leaks. */ - void *ctx = NULL; ir_instruction *inst; /* Generate a single assignment of the parameter to __retval.x and return @@ -296,11 +294,10 @@ generate_vec_body_from_scalar(exec_list *instructions, * Generate the body of a vector constructor that takes multiple scalars */ static void -generate_vec_body_from_N_scalars(exec_list *instructions, +generate_vec_body_from_N_scalars(void *ctx, + exec_list *instructions, ir_variable **declarations) { - /* NULL is wrong here and leaks. */ - void *ctx = NULL; ir_instruction *inst; const glsl_type *const vec_type = declarations[16]->type; @@ -329,11 +326,10 @@ generate_vec_body_from_N_scalars(exec_list *instructions, * Generate the body of a matrix constructor that takes a single scalar */ static void -generate_mat_body_from_scalar(exec_list *instructions, +generate_mat_body_from_scalar(void *ctx, + exec_list *instructions, ir_variable **declarations) { - /* NULL is wrong here and leaks. */ - void *ctx = NULL; ir_instruction *inst; /* Generate an assignment of the parameter to the X component of a @@ -410,11 +406,10 @@ generate_mat_body_from_scalar(exec_list *instructions, * Generate the body of a vector constructor that takes multiple scalars */ static void -generate_mat_body_from_N_scalars(exec_list *instructions, +generate_mat_body_from_N_scalars(void *ctx, + exec_list *instructions, ir_variable **declarations) { - /* NULL is wrong here and leaks. */ - void *ctx = NULL; ir_instruction *inst; const glsl_type *const row_type = declarations[16]->type->row_type(); const glsl_type *const column_type = declarations[16]->type->column_type(); @@ -498,31 +493,33 @@ generate_constructor(glsl_symbol_table *symtab, const struct glsl_type *types, * appropriate from-scalars constructor. */ ir_function_signature *const sig = - generate_constructor_intro(&types[i], 1, declarations); + generate_constructor_intro(ctx, &types[i], 1, declarations); f->add_signature(sig); if (types[i].is_vector()) { - generate_vec_body_from_scalar(&sig->body, declarations); + generate_vec_body_from_scalar(ctx, &sig->body, declarations); ir_function_signature *const vec_sig = - generate_constructor_intro(&types[i], types[i].vector_elements, + generate_constructor_intro(ctx, + &types[i], types[i].vector_elements, declarations); f->add_signature(vec_sig); - generate_vec_body_from_N_scalars(&vec_sig->body, declarations); + generate_vec_body_from_N_scalars(ctx, &vec_sig->body, declarations); } else { assert(types[i].is_matrix()); - generate_mat_body_from_scalar(&sig->body, declarations); + generate_mat_body_from_scalar(ctx, &sig->body, declarations); ir_function_signature *const mat_sig = - generate_constructor_intro(&types[i], + generate_constructor_intro(ctx, + &types[i], (types[i].vector_elements * types[i].matrix_columns), declarations); f->add_signature(mat_sig); - generate_mat_body_from_N_scalars(&mat_sig->body, declarations); + generate_mat_body_from_N_scalars(ctx, &mat_sig->body, declarations); } } } -- cgit v1.2.3 From e01193af325cbdde51b3219c85c58f19d5a87f1b Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 18:25:04 -0700 Subject: Close memory leak in ir_call::get_error_instruction. By propagating a 'ctx' parameter through these calls. This fix happens to have no impact on glsl-orangebook-ch06-bump.frag, (since it doesn't trigger any errors). --- ast_function.cpp | 32 +++++++++++++++++--------------- hir_field_selection.cpp | 2 +- ir.cpp | 4 +--- ir.h | 4 +++- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/ast_function.cpp b/ast_function.cpp index 866cbc4ecd..9550d4d2f0 100644 --- a/ast_function.cpp +++ b/ast_function.cpp @@ -104,7 +104,7 @@ process_call(exec_list *instructions, ir_function *f, */ _mesa_glsl_error(loc, state, "no matching function for call to `%s'", f->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } } @@ -114,11 +114,12 @@ match_function_by_name(exec_list *instructions, const char *name, YYLTYPE *loc, exec_list *actual_parameters, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); ir_function *f = state->symbols->get_function(name); if (f == NULL) { _mesa_glsl_error(loc, state, "function `%s' undeclared", name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } /* Once we've determined that the function being called might exist, try @@ -238,6 +239,7 @@ process_array_constructor(exec_list *instructions, YYLTYPE *loc, exec_list *parameters, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); /* Array constructors come in two forms: sized and unsized. Sized array * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4 * variables. In this case the number of parameters must exactly match the @@ -272,7 +274,7 @@ process_array_constructor(exec_list *instructions, "parameter%s", (constructor_type->length != 0) ? "at least" : "exactly", min_param, (min_param <= 1) ? "" : "s"); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } if (constructor_type->length == 0) { @@ -468,14 +470,14 @@ ast_function_expression::hir(exec_list *instructions, if (constructor_type->is_sampler()) { _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } if (constructor_type->is_array()) { if (state->language_version <= 110) { _mesa_glsl_error(& loc, state, "array constructors forbidden in GLSL 1.10"); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } return process_array_constructor(instructions, constructor_type, @@ -525,7 +527,7 @@ ast_function_expression::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "too few components to construct " "`%s'", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } foreach_list (n, &this->expressions) { @@ -555,14 +557,14 @@ ast_function_expression::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "too many parameters to `%s' " "constructor", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } if (!result->type->is_numeric() && !result->type->is_boolean()) { _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " "non-numeric data type", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } /* Count the number of matrix and nonmatrix parameters. This @@ -637,7 +639,7 @@ ast_function_expression::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " "matrix in GLSL 1.10", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec: @@ -651,7 +653,7 @@ ast_function_expression::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, " "matrix must be only parameter", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec: @@ -664,14 +666,14 @@ ast_function_expression::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "too few components to construct " "`%s'", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } ir_function *f = state->symbols->get_function(constructor_type->name); if (f == NULL) { _mesa_glsl_error(& loc, state, "no constructor for type `%s'", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } const ir_function_signature *sig = @@ -715,11 +717,11 @@ ast_function_expression::hir(exec_list *instructions, */ _mesa_glsl_error(& loc, state, "no matching constructor for `%s'", constructor_type->name); - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } } - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } else { const ast_expression *id = subexpressions[0]; YYLTYPE loc = id->get_location(); @@ -744,5 +746,5 @@ ast_function_expression::hir(exec_list *instructions, &actual_parameters, state); } - return ir_call::get_error_instruction(); + return ir_call::get_error_instruction(ctx); } diff --git a/hir_field_selection.cpp b/hir_field_selection.cpp index 6da14925b9..e2efff60d3 100644 --- a/hir_field_selection.cpp +++ b/hir_field_selection.cpp @@ -77,5 +77,5 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr, expr->primary_expression.identifier); } - return result ? result : ir_call::get_error_instruction(); + return result ? result : ir_call::get_error_instruction(ctx); } diff --git a/ir.cpp b/ir.cpp index 26cd475552..6286d874e6 100644 --- a/ir.cpp +++ b/ir.cpp @@ -833,10 +833,8 @@ ir_function::ir_function(const char *name) ir_call * -ir_call::get_error_instruction() +ir_call::get_error_instruction(void *ctx) { - /* NULL is wrong and leaks */ - void *ctx = NULL; ir_call *call = new(ctx) ir_call; call->type = glsl_type::error_type; diff --git a/ir.h b/ir.h index 68e90653ed..1c95512fb1 100644 --- a/ir.h +++ b/ir.h @@ -645,8 +645,10 @@ public: /** * Get a generic ir_call object when an error occurs + * + * Any allocation will be performed with 'ctx' as talloc owner. */ - static ir_call *get_error_instruction(); + static ir_call *get_error_instruction(void *ctx); /** * Get an iterator for the set of acutal parameters -- cgit v1.2.3 From 007efe50fdd87c8ceb2a700b6105ce6f00ba56e8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 18:30:55 -0700 Subject: s_symbol: Close memory leak of symbol name. Easily done now that s_expression is allocated with talloc. Simply switch from new to talloc_strdup and the job is done. This closes the great majority (11263) of the remaining leaks in the glsl-orangebook-ch06-bump.frag test: total heap usage: 55,623 allocs, 55,546 frees (was 44,283 frees) This test is now 99.86% leak-free. --- s_expression.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/s_expression.cpp b/s_expression.cpp index 875d739d84..26be23ea8f 100644 --- a/s_expression.cpp +++ b/s_expression.cpp @@ -30,8 +30,8 @@ s_symbol::s_symbol(const char *tmp) { - this->str = new char [strlen(tmp) + 1]; - strcpy(this->str, tmp); + this->str = talloc_strdup (this, tmp); + assert(this->str != NULL); } s_list::s_list() -- cgit v1.2.3 From a9696e79fb3afc6a4724bd16ee1ccdfebebfd0fd Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 18 Jun 2010 17:37:02 -0700 Subject: main: Close memory leak of shader string from load_text_file. Could have just added a call to free() to main, but since we're using talloc everywhere else, we might as well just use it here too. So pass a new 'ctx' argument to load_text_file. This removes a single memory leak from all invocations of the standalone glsl compiler. --- main.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index dcd4b8f672..dfed4a30e8 100644 --- a/main.cpp +++ b/main.cpp @@ -36,9 +36,9 @@ #include "ir_print_visitor.h" #include "program.h" - +/* Returned string will have 'ctx' as its talloc owner. */ static char * -load_text_file(const char *file_name, size_t *size) +load_text_file(void *ctx, const char *file_name, size_t *size) { char *text = NULL; struct stat st; @@ -51,7 +51,7 @@ load_text_file(const char *file_name, size_t *size) } if (fstat(fd, & st) == 0) { - text = (char *) malloc(st.st_size + 1); + text = (char *) talloc_size(ctx, st.st_size + 1); if (text != NULL) { do { ssize_t bytes = read(fd, text + total_read, @@ -229,7 +229,8 @@ main(int argc, char **argv) else usage_fail(argv[0]); - shader->Source = load_text_file(argv[optind], &shader->SourceLen); + shader->Source = load_text_file(whole_program, + argv[optind], &shader->SourceLen); if (shader->Source == NULL) { printf("File \"%s\" does not exist.\n", argv[optind]); exit(EXIT_FAILURE); -- cgit v1.2.3 From dc5811fd0c7600b165ddd4e04a0ccae69bb19ec8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 18 Jun 2010 17:43:40 -0700 Subject: Close memory leak in lexer. Simply call talloc_strdup rather than strdup, (using the talloc_parent of our 'state' object, (known here as yyextra). This fix now makes glsl-orangebook-ch06-bump.frag 99.97% leak free: total heap usage: 55,623 allocs, 55,609 frees Only 14 missing frees now. --- glsl_lexer.lpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/glsl_lexer.lpp b/glsl_lexer.lpp index c15c99c4b0..fa439f1278 100644 --- a/glsl_lexer.lpp +++ b/glsl_lexer.lpp @@ -312,7 +312,9 @@ highp return HIGHP; precision return PRECISION; [_a-zA-Z][_a-zA-Z0-9]* { - yylval->identifier = strdup(yytext); + struct _mesa_glsl_parse_state *state = yyextra; + void *ctx = talloc_parent(state); + yylval->identifier = talloc_strdup(ctx, yytext); return IDENTIFIER; } -- cgit v1.2.3 From 12c411504ca86341f8b96c349c15413ee198cc71 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 18 Jun 2010 17:52:59 -0700 Subject: Close memory leaks in glsl_type (constructor and get_array_instance) Add a talloc ctx to both get_array_instance and the glsl_type constructor in order to be able to call talloc_size instead of malloc. This fix now makes glsl-orangebook-ch06-bump.frag 99.99% leak free: total heap usage: 55,623 allocs, 55,615 Only 8 missing frees now. --- ast_function.cpp | 3 ++- ast_to_hir.cpp | 5 +++-- glsl_types.cpp | 11 ++++++----- glsl_types.h | 5 +++-- ir_reader.cpp | 2 +- ir_variable.cpp | 17 ++++++++++------- 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/ast_function.cpp b/ast_function.cpp index 9550d4d2f0..761af00b95 100644 --- a/ast_function.cpp +++ b/ast_function.cpp @@ -279,7 +279,8 @@ process_array_constructor(exec_list *instructions, if (constructor_type->length == 0) { constructor_type = - glsl_type::get_array_instance(constructor_type->element_type(), + glsl_type::get_array_instance(state, + constructor_type->element_type(), parameter_count); assert(constructor_type != NULL); assert(constructor_type->length == parameter_count); diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index eafc9e8114..38e344f0d2 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -506,7 +506,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, var->max_array_access); } - var->type = glsl_type::get_array_instance(lhs->type->element_type(), + var->type = glsl_type::get_array_instance(state, + lhs->type->element_type(), rhs->type->array_size()); } } @@ -1409,7 +1410,7 @@ process_array_type(const glsl_type *base, ast_node *array_size, } } - return glsl_type::get_array_instance(base, length); + return glsl_type::get_array_instance(state, base, length); } diff --git a/glsl_types.cpp b/glsl_types.cpp index 7dcb4a4caf..d1b9dc6412 100644 --- a/glsl_types.cpp +++ b/glsl_types.cpp @@ -574,7 +574,7 @@ _mesa_glsl_initialize_constructors(exec_list *instructions, } -glsl_type::glsl_type(const glsl_type *array, unsigned length) : +glsl_type::glsl_type(void *ctx, const glsl_type *array, unsigned length) : base_type(GLSL_TYPE_ARRAY), sampler_dimensionality(0), sampler_shadow(0), sampler_array(0), sampler_type(0), @@ -588,7 +588,7 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) : * NUL. */ const unsigned name_length = strlen(array->name) + 10 + 3; - char *const n = (char *) malloc(name_length); + char *const n = (char *) talloc_size(ctx, name_length); if (length == 0) snprintf(n, name_length, "%s[]", array->name); @@ -691,9 +691,10 @@ glsl_type::array_key_hash(const void *a) const glsl_type * -glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) +glsl_type::get_array_instance(void *ctx, const glsl_type *base, + unsigned array_size) { - const glsl_type key(base, array_size); + const glsl_type key(ctx, base, array_size); if (array_types == NULL) { array_types = hash_table_ctor(64, array_key_hash, array_key_compare); @@ -701,7 +702,7 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size) const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key); if (t == NULL) { - t = new glsl_type(base, array_size); + t = new glsl_type(ctx, base, array_size); hash_table_insert(array_types, (void *) t, t); } diff --git a/glsl_types.h b/glsl_types.h index 939c173fd4..baec763c42 100644 --- a/glsl_types.h +++ b/glsl_types.h @@ -198,7 +198,8 @@ struct glsl_type { /** * Get the instance of an array type */ - static const glsl_type *get_array_instance(const glsl_type *base, + static const glsl_type *get_array_instance(void *ctx, + const glsl_type *base, unsigned elements); /** @@ -387,7 +388,7 @@ private: /** * Constructor for array types */ - glsl_type(const glsl_type *array, unsigned length); + glsl_type(void *ctx, const glsl_type *array, unsigned length); /** Hash table containing the known array types. */ static struct hash_table *array_types; diff --git a/ir_reader.cpp b/ir_reader.cpp index d6985c4981..7383c42cbc 100644 --- a/ir_reader.cpp +++ b/ir_reader.cpp @@ -138,7 +138,7 @@ read_type(_mesa_glsl_parse_state *st, s_expression *expr) return NULL; } - return glsl_type::get_array_instance(base_type, size->value()); + return glsl_type::get_array_instance(st, base_type, size->value()); } else if (strcmp(type_sym->value(), "struct") == 0) { assert(false); // FINISHME } else { diff --git a/ir_variable.cpp b/ir_variable.cpp index fabd856591..15a4a92f62 100644 --- a/ir_variable.cpp +++ b/ir_variable.cpp @@ -104,7 +104,7 @@ generate_110_uniforms(exec_list *instructions, * FINISHME: for now. */ const glsl_type *const mat4_array_type = - glsl_type::get_array_instance(glsl_type::mat4_type, 4); + glsl_type::get_array_instance(symtab, glsl_type::mat4_type, 4); add_variable("gl_TextureMatrix", ir_var_uniform, -1, mat4_array_type, instructions, symtab); @@ -122,7 +122,8 @@ generate_110_uniforms(exec_list *instructions, * FINISHME: at least 8, so hard-code 8 for now. */ const glsl_type *const light_source_array_type = - glsl_type::get_array_instance(symtab->get_type("gl_LightSourceParameters"), 8); + glsl_type::get_array_instance(symtab, + symtab->get_type("gl_LightSourceParameters"), 8); add_variable("gl_LightSource", ir_var_uniform, -1, light_source_array_type, instructions, symtab); @@ -157,7 +158,7 @@ generate_110_vs_variables(exec_list *instructions, * FINISHME: for now. */ const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, 4); + glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4); add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type, instructions, symtab); @@ -179,6 +180,7 @@ static void generate_130_vs_variables(exec_list *instructions, glsl_symbol_table *symtab) { + void *ctx = symtab; generate_120_vs_variables(instructions, symtab); for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) { @@ -190,7 +192,7 @@ generate_130_vs_variables(exec_list *instructions, * FINISHME: the value of GL_MAX_CLIP_DISTANCES. */ const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(glsl_type::float_type, 8); + glsl_type::get_array_instance(ctx, glsl_type::float_type, 8); /* FINISHME: gl_ClipDistance needs a real location assigned. */ add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type, @@ -240,7 +242,7 @@ generate_110_fs_variables(exec_list *instructions, * FINISHME: for now. */ const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, 4); + glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 4); add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type, instructions, symtab); @@ -256,7 +258,7 @@ generate_ARB_draw_buffers_fs_variables(exec_list *instructions, * FINISHME: at least 1, so hard-code 1 for now. */ const glsl_type *const vec4_array_type = - glsl_type::get_array_instance(glsl_type::vec4_type, 1); + glsl_type::get_array_instance(symtab, glsl_type::vec4_type, 1); ir_variable *const fd = add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0, @@ -279,13 +281,14 @@ static void generate_130_fs_variables(exec_list *instructions, glsl_symbol_table *symtab) { + void *ctx = symtab; generate_120_fs_variables(instructions, symtab); /* FINISHME: The size of this array is implementation dependent based on * FINISHME: the value of GL_MAX_CLIP_DISTANCES. */ const glsl_type *const clip_distance_array_type = - glsl_type::get_array_instance(glsl_type::float_type, 8); + glsl_type::get_array_instance(ctx, glsl_type::float_type, 8); /* FINISHME: gl_ClipDistance needs a real location assigned. */ add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type, -- cgit v1.2.3 From b3bd77da56ce8aa225ee91565e4d1e640685728c Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 19:04:45 -0700 Subject: glsl_type: Add a talloc-based new And hook it up at the two sites it's called. Note that with this change we still don't use glsl_type* objects as talloc contexts, (see things like get_array_instance that accept both a talloc 'ctx' as well as a glsl_type*). The reason for this is that the code is still using many instance of glsl_type objects not created with new. This closes 3 leaks in the glsl-orangebook-ch06-bump.frag test: total heap usage: 55,623 allocs, 55,618 Leaving only 5 leaks to go. --- ast_to_hir.cpp | 3 ++- glsl_types.cpp | 2 +- glsl_types.h | 23 +++++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp index 38e344f0d2..ddd4b73266 100644 --- a/ast_to_hir.cpp +++ b/ast_to_hir.cpp @@ -2354,6 +2354,7 @@ ir_rvalue * ast_struct_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { + void *ctx = talloc_parent(state); unsigned decl_count = 0; /* Make an initial pass over the list of structure fields to determine how @@ -2416,7 +2417,7 @@ ast_struct_specifier::hir(exec_list *instructions, name = this->name; } - glsl_type *t = new glsl_type(fields, decl_count, name); + glsl_type *t = new(ctx) glsl_type(fields, decl_count, name); YYLTYPE loc = this->get_location(); if (!state->symbols->add_type(name, t)) { diff --git a/glsl_types.cpp b/glsl_types.cpp index d1b9dc6412..bef267fa6b 100644 --- a/glsl_types.cpp +++ b/glsl_types.cpp @@ -702,7 +702,7 @@ glsl_type::get_array_instance(void *ctx, const glsl_type *base, const glsl_type *t = (glsl_type *) hash_table_find(array_types, & key); if (t == NULL) { - t = new glsl_type(ctx, base, array_size); + t = new(ctx) glsl_type(ctx, base, array_size); hash_table_insert(array_types, (void *) t, t); } diff --git a/glsl_types.h b/glsl_types.h index baec763c42..39e6ac970a 100644 --- a/glsl_types.h +++ b/glsl_types.h @@ -29,6 +29,10 @@ #include #include +extern "C" { +#include +} + #define GLSL_TYPE_UINT 0 #define GLSL_TYPE_INT 1 #define GLSL_TYPE_FLOAT 2 @@ -61,6 +65,25 @@ struct glsl_type { * and \c GLSL_TYPE_UINT are valid. */ + /* 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 *type; + + type = talloc_size(ctx, size); + assert(type != NULL); + + return type; + } + + /* If the user *does* call delete, that's OK, we will just + * talloc_free in that case. */ + static void operator delete(void *type) + { + talloc_free(type); + } + /** * \name Vector and matrix element counts * -- cgit v1.2.3 From 26bbfb7917a71d46d9227bbf960606cb673636d3 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 19:09:56 -0700 Subject: glsl2 main: Switch from realloc to talloc_realloc to construct program source. This closes 1 leak in the glsl-orangebook-ch06-bump.frag test leaving 4 to go, (all of which are inside hash_table.c). --- main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index dfed4a30e8..dcd9bd69c0 100644 --- a/main.cpp +++ b/main.cpp @@ -206,8 +206,8 @@ main(int argc, char **argv) for (/* empty */; argc > optind; optind++) { whole_program->Shaders = (struct glsl_shader **) - realloc(whole_program->Shaders, - sizeof(struct glsl_shader *) * (whole_program->NumShaders + 1)); + talloc_realloc(whole_program, whole_program->Shaders, + struct glsl_shader *, whole_program->NumShaders + 1); assert(whole_program->Shaders != NULL); struct glsl_shader *shader = talloc_zero(whole_program, glsl_shader); -- cgit v1.2.3