From 1660a2954797e056caba319c5d6c70b0d4be22fe Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 23 Jun 2010 18:11:51 -0700 Subject: [PATCH] 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 ff2dfa502f3..866cbc4ecdf 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 c70f0f9de9f..eafc9e81145 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 ca19de6bec3..fcc77458b28 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 e60ea30d7ff..6da14925b98 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 98b085e91bf..26cd4755520 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 c810fe86164..5ffd3fc00b2 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 effb88844ee..4010e462674 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 16a2ba79bf6..46ef6679d9f 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 8465d863aa3..01b7d2d832a 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 d3b3858617d..e01877077c9 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 3089f17ae14..5ba24e390b4 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 effb01c8f68..8a1cf4f1d24 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 ee320ddac28..d6985c4981c 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 efebe9199fa..fabd856591a 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 eb0e556c9db..bbd873791a1 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 0b91647be4f..7732d66d7a6 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 0fb296ef671..875d739d842 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 8a4eda28dae..1a0c03c2189 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. -- 2.30.2