[Mesa-dev] [PATCH] glsl: fix loop_variable_state->var_hash leak

Marcin Slusarz marcin.slusarz at gmail.com
Thu Jun 7 20:07:49 CEST 2012


On Tue, Jun 05, 2012 at 03:58:20PM -0700, Kenneth Graunke wrote:
> On 06/05/2012 02:49 PM, Marcin Slusarz wrote:
> > 
> > ---
> >  src/glsl/loop_analysis.cpp |    6 ++++++
> >  1 files changed, 6 insertions(+), 0 deletions(-)
> > 
> > diff --git a/src/glsl/loop_analysis.cpp b/src/glsl/loop_analysis.cpp
> > index 6a0e4da..6548e15 100644
> > --- a/src/glsl/loop_analysis.cpp
> > +++ b/src/glsl/loop_analysis.cpp
> > @@ -42,8 +42,14 @@ loop_state::loop_state()
> >  }
> >  
> >  
> > +static void destroy_loop_var_state(const void *key, void *data, void *closure)
> > +{
> > +   delete (loop_variable_state *)data;
> > +}
> > +
> >  loop_state::~loop_state()
> >  {
> > +   hash_table_call_foreach(this->ht, destroy_loop_var_state, NULL);
> >     hash_table_dtor(this->ht);
> >     ralloc_free(this->mem_ctx);
> >  }
> 
> This makes me nervous.  They're allocated via ralloc:
> 
>    loop_variable_state *ls = new(this->mem_ctx) loop_variable_state;
> 
> which internally uses malloc/calloc and friends, not new/delete.
> 
> ~loop_state() already calls ralloc_free(this->mem_ctx), which frees all
> the loop_variable_state objects.  However, the loop_variable_state
> destructor isn't hooked up, so hash_table_dtor(this->var_hash) is never
> getting called.
> 
> I'll reply in a moment with a patch to use ralloc invoke the destructor.
> 
> It may be possible to rework ralloc such that C++ destructors just work.
>  I'll have to think about that.

Not possible to "just work" without adding reflection to C++ first.
Below is a patch which "works", but needs one line boilerplate to all
classes which are ralloc'able.

---
From: Marcin Slusarz <marcin.slusarz at gmail.com>
Subject: [PATCH] ralloc: call c++ class destructors on free

... and uninline new and delete operators
... which shrinks libglsl.so by 136kB (3%)
---
 src/glsl/ast.h                                     |   42 ++++++-----
 src/glsl/ast_type.cpp                              |   25 +++++++
 src/glsl/glsl_parser_extras.cpp                    |    2 +
 src/glsl/glsl_parser_extras.h                      |   19 +-----
 src/glsl/glsl_symbol_table.cpp                     |   18 +----
 src/glsl/glsl_symbol_table.h                       |   31 +--------
 src/glsl/ir.cpp                                    |   25 +++++++
 src/glsl/ir.h                                      |   21 ++++++
 src/glsl/ir_function_detect_recursion.cpp          |   22 +-----
 src/glsl/ir_variable_refcount.cpp                  |    2 +
 src/glsl/ir_variable_refcount.h                    |    1 +
 src/glsl/list.h                                    |   42 +----------
 src/glsl/loop_analysis.cpp                         |    4 +
 src/glsl/loop_analysis.h                           |   20 +-----
 src/glsl/opt_array_splitting.cpp                   |    1 +
 src/glsl/opt_constant_propagation.cpp              |    2 +
 src/glsl/opt_copy_propagation.cpp                  |    2 +
 src/glsl/opt_copy_propagation_elements.cpp         |    2 +
 src/glsl/opt_dead_code_local.cpp                   |    1 +
 src/glsl/opt_dead_functions.cpp                    |    1 +
 src/glsl/opt_structure_splitting.cpp               |    1 +
 src/glsl/ralloc.h                                  |   73 ++++++++++++++++++++
 src/glsl/s_expression.cpp                          |    7 ++
 src/glsl/s_expression.h                            |    6 ++
 src/mesa/drivers/dri/i965/brw_fs.cpp               |    3 +
 src/mesa/drivers/dri/i965/brw_fs.h                 |   26 +-------
 src/mesa/drivers/dri/i965/brw_fs_cfg.cpp           |    5 ++
 src/mesa/drivers/dri/i965/brw_fs_cfg.h             |   23 +------
 .../drivers/dri/i965/brw_fs_copy_propagation.cpp   |    2 +
 src/mesa/drivers/dri/i965/brw_fs_cse.cpp           |    2 +
 .../drivers/dri/i965/brw_fs_live_variables.cpp     |    2 +
 src/mesa/drivers/dri/i965/brw_fs_live_variables.h  |   11 +---
 .../dri/i965/brw_fs_schedule_instructions.cpp      |    1 +
 .../drivers/dri/i965/brw_fs_vector_splitting.cpp   |    1 +
 src/mesa/drivers/dri/i965/brw_vec4.cpp             |    4 +
 src/mesa/drivers/dri/i965/brw_vec4.h               |   38 +---------
 src/mesa/program/ir_to_mesa.cpp                    |   14 +---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp         |   15 +---
 38 files changed, 252 insertions(+), 265 deletions(-)

diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index b096c83..33ac78f 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -48,26 +48,8 @@ struct YYLTYPE;
  * Base class of all abstract syntax tree nodes
  */
 class ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS(ast_node);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
-   /* If the user *does* call delete, that's OK, we will just
-    * ralloc_free in that case. */
-   static void operator delete(void *table)
-   {
-      ralloc_free(table);
-   }
-
    /**
     * Print an AST node in something approximating the original GLSL code
     */
@@ -196,6 +178,7 @@ enum ast_operators {
  * Representation of any sort of expression.
  */
 class ast_expression : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_expression);
 public:
    ast_expression(int oper, ast_expression *,
 		  ast_expression *, ast_expression *);
@@ -250,6 +233,7 @@ public:
 };
 
 class ast_expression_bin : public ast_expression {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_expression_bin);
 public:
    ast_expression_bin(int oper, ast_expression *, ast_expression *);
 
@@ -260,6 +244,7 @@ public:
  * Subclass of expressions for function calls
  */
 class ast_function_expression : public ast_expression {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_function_expression);
 public:
    ast_function_expression(ast_expression *callee)
       : ast_expression(ast_function_call, callee,
@@ -304,6 +289,7 @@ private:
 
 
 class ast_compound_statement : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_compound_statement);
 public:
    ast_compound_statement(int new_scope, ast_node *statements);
    virtual void print(void) const;
@@ -316,6 +302,7 @@ public:
 };
 
 class ast_declaration : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_declaration);
 public:
    ast_declaration(const char *identifier, int is_array, ast_expression *array_size,
 		   ast_expression *initializer);
@@ -418,6 +405,7 @@ struct ast_type_qualifier {
 };
 
 class ast_struct_specifier : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_struct_specifier);
 public:
    ast_struct_specifier(const char *identifier, ast_node *declarator_list);
    virtual void print(void) const;
@@ -432,6 +420,7 @@ public:
 
 
 class ast_type_specifier : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_type_specifier);
 public:
    /** Construct a type specifier from a type name */
    ast_type_specifier(const char *name) 
@@ -472,6 +461,7 @@ public:
 
 
 class ast_fully_specified_type : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_fully_specified_type);
 public:
    virtual void print(void) const;
    bool has_qualifiers() const;
@@ -482,6 +472,7 @@ public:
 
 
 class ast_declarator_list : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_declarator_list);
 public:
    ast_declarator_list(ast_fully_specified_type *);
    virtual void print(void) const;
@@ -504,6 +495,7 @@ public:
 
 
 class ast_parameter_declarator : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_parameter_declarator);
 public:
    ast_parameter_declarator()
    {
@@ -540,6 +532,7 @@ private:
 
 
 class ast_function : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_function);
 public:
    ast_function(void);
 
@@ -579,6 +572,7 @@ private:
 
 
 class ast_expression_statement : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_expression_statement);
 public:
    ast_expression_statement(ast_expression *);
    virtual void print(void) const;
@@ -591,6 +585,7 @@ public:
 
 
 class ast_case_label : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_case_label);
 public:
    ast_case_label(ast_expression *test_value);
    virtual void print(void) const;
@@ -606,6 +601,7 @@ public:
 
 
 class ast_case_label_list : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_case_label_list);
 public:
    ast_case_label_list(void);
    virtual void print(void) const;
@@ -621,6 +617,7 @@ public:
 
 
 class ast_case_statement : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_case_statement);
 public:
    ast_case_statement(ast_case_label_list *labels);
    virtual void print(void) const;
@@ -638,6 +635,7 @@ public:
 
 
 class ast_case_statement_list : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_case_statement_list);
 public:
    ast_case_statement_list(void);
    virtual void print(void) const;
@@ -653,6 +651,7 @@ public:
 
 
 class ast_switch_body : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_switch_body);
 public:
    ast_switch_body(ast_case_statement_list *stmts);
    virtual void print(void) const;
@@ -665,6 +664,7 @@ public:
 
 
 class ast_selection_statement : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_selection_statement);
 public:
    ast_selection_statement(ast_expression *condition,
 			   ast_node *then_statement,
@@ -681,6 +681,7 @@ public:
 
 
 class ast_switch_statement : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_switch_statement);
 public:
    ast_switch_statement(ast_expression *test_expression,
 			ast_node *body);
@@ -697,6 +698,7 @@ protected:
 };
 
 class ast_iteration_statement : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_iteration_statement);
 public:
    ast_iteration_statement(int mode, ast_node *init, ast_node *condition,
 			   ast_expression *rest_expression, ast_node *body);
@@ -730,6 +732,7 @@ private:
 
 
 class ast_jump_statement : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_jump_statement);
 public:
    ast_jump_statement(int mode, ast_expression *return_value);
    virtual void print(void) const;
@@ -749,6 +752,7 @@ public:
 
 
 class ast_function_definition : public ast_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ast_function_definition);
 public:
    virtual void print(void) const;
 
diff --git a/src/glsl/ast_type.cpp b/src/glsl/ast_type.cpp
index 6c44f8c..cbeedc1 100644
--- a/src/glsl/ast_type.cpp
+++ b/src/glsl/ast_type.cpp
@@ -71,3 +71,28 @@ ast_type_qualifier::interpolation_string() const
    else
       return NULL;
 }
+
+RALLOC_DEFINE_CLASS_HELPERS(ast_node);
+
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_expression);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_expression_bin);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_function_expression);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_compound_statement);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_declaration);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_struct_specifier);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_type_specifier);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_fully_specified_type);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_declarator_list);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_parameter_declarator);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_function);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_expression_statement);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_case_label);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_case_label_list);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_case_statement);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_case_statement_list);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_switch_body);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_selection_statement);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_switch_statement);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_iteration_statement);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_jump_statement);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ast_function_definition);
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index 46f21dd..da5d1a9 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -1106,3 +1106,5 @@ _mesa_destroy_shader_compiler_caches(void)
 }
 
 }
+
+RALLOC_DEFINE_CLASS_HELPERS(_mesa_glsl_parse_state);
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 1a909c6..727d247 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -57,26 +57,11 @@ struct glsl_switch_state {
 };
 
 struct _mesa_glsl_parse_state {
+   RALLOC_DECLARE_CLASS_HELPERS(_mesa_glsl_parse_state);
+public:
    _mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target,
 			  void *mem_ctx);
 
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *mem = rzalloc_size(ctx, size);
-      assert(mem != NULL);
-
-      return mem;
-   }
-
-   /* If the user *does* call delete, that's OK, we will just
-    * ralloc_free in that case. */
-   static void operator delete(void *mem)
-   {
-      ralloc_free(mem);
-   }
-
    struct gl_context *const ctx;
    void *scanner;
    exec_list translation_unit;
diff --git a/src/glsl/glsl_symbol_table.cpp b/src/glsl/glsl_symbol_table.cpp
index bcb65d3..e0c7344 100644
--- a/src/glsl/glsl_symbol_table.cpp
+++ b/src/glsl/glsl_symbol_table.cpp
@@ -25,22 +25,8 @@
 #include "glsl_symbol_table.h"
 
 class symbol_table_entry {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS(symbol_table_entry);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *entry = ralloc_size(ctx, size);
-      assert(entry != NULL);
-      return entry;
-   }
-
-   /* If the user *does* call delete, that's OK, we will just ralloc_free. */
-   static void operator delete(void *entry)
-   {
-      ralloc_free(entry);
-   }
-
    symbol_table_entry(ir_variable *v)                     : v(v), f(0), t(0) {}
    symbol_table_entry(ir_function *f)                     : v(0), f(f), t(0) {}
    symbol_table_entry(const glsl_type *t)                 : v(0), f(0), t(t) {}
@@ -163,3 +149,5 @@ symbol_table_entry *glsl_symbol_table::get_entry(const char *name)
    return (symbol_table_entry *)
       _mesa_symbol_table_find_symbol(table, -1, name);
 }
+
+RALLOC_DEFINE_CLASS_HELPERS(glsl_symbol_table);
diff --git a/src/glsl/glsl_symbol_table.h b/src/glsl/glsl_symbol_table.h
index 637bc03..10007da 100644
--- a/src/glsl/glsl_symbol_table.h
+++ b/src/glsl/glsl_symbol_table.h
@@ -43,37 +43,8 @@ class symbol_table_entry;
  * type safe and some symbol table invariants.
  */
 struct glsl_symbol_table {
-private:
-   static void
-   _glsl_symbol_table_destructor (glsl_symbol_table *table)
-   {
-      table->~glsl_symbol_table();
-   }
-
+   RALLOC_DECLARE_CLASS_HELPERS(glsl_symbol_table);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *table;
-
-      table = ralloc_size(ctx, size);
-      assert(table != NULL);
-
-      ralloc_set_destructor(table, (void (*)(void*)) _glsl_symbol_table_destructor);
-
-      return table;
-   }
-
-   /* If the user *does* call delete, that's OK, we will just
-    * ralloc_free in that case. Here, C++ will have already called the
-    * destructor so tell ralloc not to do that again. */
-   static void operator delete(void *table)
-   {
-      ralloc_set_destructor(table, NULL);
-      ralloc_free(table);
-   }
-   
    glsl_symbol_table();
    ~glsl_symbol_table();
 
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 970d8f3..7cd16fe 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1676,3 +1676,28 @@ ir_rvalue::as_rvalue_to_saturate()
 
    return NULL;
 }
+
+RALLOC_DEFINE_CLASS_HELPERS(exec_node);
+RALLOC_DEFINE_CLASS_HELPERS(exec_list);
+
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_instruction);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_rvalue);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_variable);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_function_signature);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_function);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_if);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_loop);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_assignment);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_expression);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_call);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_jump);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_return);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_loop_jump);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_discard);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_texture);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_swizzle);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_dereference);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_dereference_variable);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_dereference_array);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_dereference_record);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_constant);
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 9c7961a..19a973f 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -86,6 +86,7 @@ enum ir_node_type {
  * Base class of all IR instructions
  */
 class ir_instruction : public exec_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_instruction);
 public:
    enum ir_node_type ir_type;
 
@@ -134,6 +135,7 @@ protected:
  * The base class for all "values"/expression trees.
  */
 class ir_rvalue : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_rvalue);
 public:
    const struct glsl_type *type;
 
@@ -277,6 +279,7 @@ struct ir_state_slot {
 };
 
 class ir_variable : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_variable);
 public:
    ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
 
@@ -483,6 +486,7 @@ public:
  * simply a prototype.
  */
 class ir_function_signature : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_function_signature);
    /* An ir_function_signature will be part of the list of signatures in
     * an ir_function.
     */
@@ -600,6 +604,7 @@ private:
  * actual functions.
  */
 class ir_function : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_function);
 public:
    ir_function(const char *name);
 
@@ -675,6 +680,7 @@ inline const char *ir_function_signature::function_name() const
  * IR instruction representing high-level if-statements
  */
 class ir_if : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_if);
 public:
    ir_if(ir_rvalue *condition)
       : condition(condition)
@@ -708,6 +714,7 @@ public:
  * IR instruction representing a high-level loop structure.
  */
 class ir_loop : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_loop);
 public:
    ir_loop();
 
@@ -767,6 +774,7 @@ public:
 
 
 class ir_assignment : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_assignment);
 public:
    ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL);
 
@@ -988,6 +996,7 @@ enum ir_expression_operation {
 };
 
 class ir_expression : public ir_rvalue {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_expression);
 public:
    /**
     * Constructor for unary operation expressions
@@ -1074,6 +1083,7 @@ public:
  * of parameters and returning a value in the supplied temporary.
  */
 class ir_call : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_call);
 public:
    ir_call(ir_function_signature *callee,
 	   ir_dereference_variable *return_deref,
@@ -1150,6 +1160,7 @@ public:
  */
 /*@{*/
 class ir_jump : public ir_instruction {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_jump);
 protected:
    ir_jump()
    {
@@ -1158,6 +1169,7 @@ protected:
 };
 
 class ir_return : public ir_jump {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_return);
 public:
    ir_return()
       : value(NULL)
@@ -1203,6 +1215,7 @@ public:
  * \sa ir_switch_jump
  */
 class ir_loop_jump : public ir_jump {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_loop_jump);
 public:
    enum jump_mode {
       jump_break,
@@ -1246,6 +1259,7 @@ private:
  * IR instruction representing discard statements.
  */
 class ir_discard : public ir_jump {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_discard);
 public:
    ir_discard()
    {
@@ -1311,6 +1325,7 @@ enum ir_texture_opcode {
  * (txs <type> <sampler> <lod>)
  */
 class ir_texture : public ir_rvalue {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_texture);
 public:
    ir_texture(enum ir_texture_opcode op)
       : op(op), projector(NULL), shadow_comparitor(NULL), offset(NULL)
@@ -1402,6 +1417,7 @@ struct ir_swizzle_mask {
 
 
 class ir_swizzle : public ir_rvalue {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_swizzle);
 public:
    ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
               unsigned count);
@@ -1455,6 +1471,7 @@ private:
 
 
 class ir_dereference : public ir_rvalue {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_dereference);
 public:
    virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0;
 
@@ -1482,6 +1499,7 @@ public:
 
 
 class ir_dereference_variable : public ir_dereference {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_dereference_variable);
 public:
    ir_dereference_variable(ir_variable *var);
 
@@ -1538,6 +1556,7 @@ public:
 
 
 class ir_dereference_array : public ir_dereference {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_dereference_array);
 public:
    ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index);
 
@@ -1586,6 +1605,7 @@ private:
 
 
 class ir_dereference_record : public ir_dereference {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_dereference_record);
 public:
    ir_dereference_record(ir_rvalue *value, const char *field);
 
@@ -1637,6 +1657,7 @@ union ir_constant_data {
 
 
 class ir_constant : public ir_rvalue {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_constant);
 public:
    ir_constant(const struct glsl_type *type, const ir_constant_data *data);
    ir_constant(bool b);
diff --git a/src/glsl/ir_function_detect_recursion.cpp b/src/glsl/ir_function_detect_recursion.cpp
index 0a5e647..d502d6f 100644
--- a/src/glsl/ir_function_detect_recursion.cpp
+++ b/src/glsl/ir_function_detect_recursion.cpp
@@ -128,10 +128,13 @@
 #include "program.h"
 
 struct call_node : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(call_node);
+public:
    class function *func;
 };
 
 class function {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS(function);
 public:
    function(ir_function_signature *sig)
       : sig(sig)
@@ -140,25 +143,6 @@ public:
    }
 
 
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = ralloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
-   /* If the user *does* call delete, that's OK, we will just
-    * ralloc_free in that case. */
-   static void operator delete(void *node)
-   {
-      ralloc_free(node);
-   }
-
    ir_function_signature *sig;
 
    /** List of functions called by this function. */
diff --git a/src/glsl/ir_variable_refcount.cpp b/src/glsl/ir_variable_refcount.cpp
index 1633a73..c14001d 100644
--- a/src/glsl/ir_variable_refcount.cpp
+++ b/src/glsl/ir_variable_refcount.cpp
@@ -111,3 +111,5 @@ ir_variable_refcount_visitor::visit_leave(ir_assignment *ir)
 
    return visit_continue;
 }
+
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(ir_variable_refcount_entry);
diff --git a/src/glsl/ir_variable_refcount.h b/src/glsl/ir_variable_refcount.h
index 51a4945..17c02a4 100644
--- a/src/glsl/ir_variable_refcount.h
+++ b/src/glsl/ir_variable_refcount.h
@@ -35,6 +35,7 @@
 
 class ir_variable_refcount_entry : public exec_node
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(ir_variable_refcount_entry);
 public:
    ir_variable_refcount_entry(ir_variable *var);
 
diff --git a/src/glsl/list.h b/src/glsl/list.h
index 1d46365..b65b401 100644
--- a/src/glsl/list.h
+++ b/src/glsl/list.h
@@ -76,25 +76,8 @@ struct exec_node {
    struct exec_node *prev;
 
 #ifdef __cplusplus
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = ralloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
-   /* If the user *does* call delete, that's OK, we will just
-    * ralloc_free in that case. */
-   static void operator delete(void *node)
-   {
-      ralloc_free(node);
-   }
-
+   RALLOC_DECLARE_CLASS_HELPERS(exec_node);
+public:
    exec_node() : next(NULL), prev(NULL)
    {
       /* empty */
@@ -285,25 +268,8 @@ struct exec_list {
    struct exec_node *tail_pred;
 
 #ifdef __cplusplus
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = ralloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
-   /* If the user *does* call delete, that's OK, we will just
-    * ralloc_free in that case. */
-   static void operator delete(void *node)
-   {
-      ralloc_free(node);
-   }
-
+   RALLOC_DECLARE_CLASS_HELPERS(exec_list);
+public:
    exec_list()
    {
       make_empty();
diff --git a/src/glsl/loop_analysis.cpp b/src/glsl/loop_analysis.cpp
index 6a0e4da..18dd009 100644
--- a/src/glsl/loop_analysis.cpp
+++ b/src/glsl/loop_analysis.cpp
@@ -526,3 +526,7 @@ analyze_loop_variables(exec_list *instructions)
    v.run(instructions);
    return v.loops;
 }
+
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(loop_variable_state);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(loop_variable);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(loop_terminator);
diff --git a/src/glsl/loop_analysis.h b/src/glsl/loop_analysis.h
index 05c982f..40877bd 100644
--- a/src/glsl/loop_analysis.h
+++ b/src/glsl/loop_analysis.h
@@ -64,6 +64,7 @@ unroll_loops(exec_list *instructions, loop_state *ls, unsigned max_iterations);
  * Tracking for all variables used in a loop
  */
 class loop_variable_state : public exec_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(loop_variable_state);
 public:
    class loop_variable *get(const ir_variable *);
    class loop_variable *insert(ir_variable *);
@@ -140,27 +141,11 @@ public:
    {
       hash_table_dtor(this->var_hash);
    }
-
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *lvs = ralloc_size(ctx, size);
-      assert(lvs != NULL);
-
-      ralloc_set_destructor(lvs, (void (*)(void*)) destructor);
-
-      return lvs;
-   }
-
-private:
-   static void
-   destructor(loop_variable_state *lvs)
-   {
-      lvs->~loop_variable_state();
-   }
 };
 
 
 class loop_variable : public exec_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(loop_variable);
 public:
    /** The variable in question. */
    ir_variable *var;
@@ -221,6 +206,7 @@ public:
 
 
 class loop_terminator : public exec_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(loop_terminator);
 public:
    ir_if *ir;
 };
diff --git a/src/glsl/opt_array_splitting.cpp b/src/glsl/opt_array_splitting.cpp
index 67733ca..d8e8d40 100644
--- a/src/glsl/opt_array_splitting.cpp
+++ b/src/glsl/opt_array_splitting.cpp
@@ -45,6 +45,7 @@ namespace opt_array_splitting {
 
 class variable_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(variable_entry);
 public:
    variable_entry(ir_variable *var)
    {
diff --git a/src/glsl/opt_constant_propagation.cpp b/src/glsl/opt_constant_propagation.cpp
index 2601b52..ec1ebd2 100644
--- a/src/glsl/opt_constant_propagation.cpp
+++ b/src/glsl/opt_constant_propagation.cpp
@@ -43,6 +43,7 @@
 
 class acp_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(acp_entry);
 public:
    acp_entry(ir_variable *var, unsigned write_mask, ir_constant *constant)
    {
@@ -73,6 +74,7 @@ public:
 
 class kill_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(kill_entry);
 public:
    kill_entry(ir_variable *var, unsigned write_mask)
    {
diff --git a/src/glsl/opt_copy_propagation.cpp b/src/glsl/opt_copy_propagation.cpp
index 923619d..658ce09 100644
--- a/src/glsl/opt_copy_propagation.cpp
+++ b/src/glsl/opt_copy_propagation.cpp
@@ -40,6 +40,7 @@
 
 class acp_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(acp_entry);
 public:
    acp_entry(ir_variable *lhs, ir_variable *rhs)
    {
@@ -56,6 +57,7 @@ public:
 
 class kill_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(kill_entry);
 public:
    kill_entry(ir_variable *var)
    {
diff --git a/src/glsl/opt_copy_propagation_elements.cpp b/src/glsl/opt_copy_propagation_elements.cpp
index 11d9d7b..ce48061 100644
--- a/src/glsl/opt_copy_propagation_elements.cpp
+++ b/src/glsl/opt_copy_propagation_elements.cpp
@@ -51,6 +51,7 @@ static bool debug = false;
 
 class acp_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(acp_entry);
 public:
    acp_entry(ir_variable *lhs, ir_variable *rhs, int write_mask, int swizzle[4])
    {
@@ -77,6 +78,7 @@ public:
 
 class kill_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(kill_entry);
 public:
    kill_entry(ir_variable *var, int write_mask)
    {
diff --git a/src/glsl/opt_dead_code_local.cpp b/src/glsl/opt_dead_code_local.cpp
index 4af78a7..92fad22 100644
--- a/src/glsl/opt_dead_code_local.cpp
+++ b/src/glsl/opt_dead_code_local.cpp
@@ -42,6 +42,7 @@ static bool debug = false;
 
 class assignment_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(assignment_entry);
 public:
    assignment_entry(ir_variable *lhs, ir_assignment *ir)
    {
diff --git a/src/glsl/opt_dead_functions.cpp b/src/glsl/opt_dead_functions.cpp
index f503493..dc81446 100644
--- a/src/glsl/opt_dead_functions.cpp
+++ b/src/glsl/opt_dead_functions.cpp
@@ -34,6 +34,7 @@
 
 class signature_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(signature_entry);
 public:
    signature_entry(ir_function_signature *sig)
    {
diff --git a/src/glsl/opt_structure_splitting.cpp b/src/glsl/opt_structure_splitting.cpp
index a21238d..b173013 100644
--- a/src/glsl/opt_structure_splitting.cpp
+++ b/src/glsl/opt_structure_splitting.cpp
@@ -46,6 +46,7 @@ static bool debug = false;
 // here go away?
 class variable_entry2 : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(variable_entry2);
 public:
    variable_entry2(ir_variable *var)
    {
diff --git a/src/glsl/ralloc.h b/src/glsl/ralloc.h
index 86306b1..9fd90e6 100644
--- a/src/glsl/ralloc.h
+++ b/src/glsl/ralloc.h
@@ -48,6 +48,79 @@
 #define RALLOC_H
 
 #ifdef __cplusplus
+
+#define RALLOC_DECLARE_CLASS_HELPERS_INHERITED(TYPE)                   \
+public:                                                                \
+   /* Callers of this ralloc-based new need not call delete. It's      \
+    * easier to just ralloc_free 'ctx' (or any of its ancestors). */   \
+   static void* operator new(size_t size, void *ctx);                  \
+private:
+
+#define RALLOC_DECLARE_CLASS_HELPERS(TYPE)                             \
+public:                                                                \
+   /* If the user *does* call delete, that's OK, we will just          \
+    * ralloc_free in that case. Here, C++ will have already called the \
+    * destructor so tell ralloc not to do that again. */               \
+   static void operator delete(void *obj);                             \
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(TYPE)
+
+#define RALLOC_DEFINE_CLASS_HELPERS_INHERITED(TYPE)                    \
+static void TYPE##_destructor(TYPE *obj)                               \
+{                                                                      \
+   obj->~TYPE();                                                       \
+}                                                                      \
+void* TYPE::operator new(size_t size, void *ctx)                       \
+{                                                                      \
+   void *obj;                                                          \
+                                                                       \
+   obj = ralloc_size(ctx, size);                                       \
+   assert(obj != NULL);                                                \
+   ralloc_set_destructor(obj, (void (*)(void*)) TYPE##_destructor);    \
+                                                                       \
+   return obj;                                                         \
+}
+
+#define RALLOC_DEFINE_CLASS_HELPERS(TYPE)                              \
+void TYPE::operator delete(void *obj)                                  \
+{                                                                      \
+   ralloc_set_destructor(obj, NULL);                                   \
+   ralloc_free(obj);                                                   \
+}                                                                      \
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(TYPE)
+
+#define RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(TYPE)             \
+public:                                                                \
+   /* Callers of this ralloc-based new need not call delete. It's      \
+    * easier to just ralloc_free 'ctx' (or any of its ancestors). */   \
+   static void* operator new(size_t size, void *ctx)                   \
+   {                                                                   \
+      void *obj;                                                       \
+                                                                       \
+      obj = ralloc_size(ctx, size);                                    \
+      assert(obj != NULL);                                             \
+      ralloc_set_destructor(obj, (void (*)(void*)) TYPE::destructor);  \
+                                                                       \
+      return obj;                                                      \
+   }                                                                   \
+                                                                       \
+private:                                                               \
+   static void destructor(TYPE *obj)                                   \
+   {                                                                   \
+      obj->~TYPE();                                                    \
+   }
+
+#define RALLOC_DEFINE_INLINE_CLASS_HELPERS(TYPE)                       \
+public:                                                                \
+   /* If the user *does* call delete, that's OK, we will just          \
+    * ralloc_free in that case. Here, C++ will have already called the \
+    * destructor so tell ralloc not to do that again. */               \
+   static void operator delete(void *obj)                              \
+   {                                                                   \
+      ralloc_set_destructor(obj, NULL);                                \
+      ralloc_free(obj);                                                \
+   }                                                                   \
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(TYPE)
+
 extern "C" {
 #endif
 
diff --git a/src/glsl/s_expression.cpp b/src/glsl/s_expression.cpp
index 57de9d3..f329077 100644
--- a/src/glsl/s_expression.cpp
+++ b/src/glsl/s_expression.cpp
@@ -217,3 +217,10 @@ s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial)
 
    return true;
 }
+
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(s_expression);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(s_number);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(s_int);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(s_float);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(s_symbol);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(s_list);
diff --git a/src/glsl/s_expression.h b/src/glsl/s_expression.h
index 642af19..e556b88 100644
--- a/src/glsl/s_expression.h
+++ b/src/glsl/s_expression.h
@@ -52,6 +52,7 @@
  */
 class s_expression : public exec_node
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(s_expression);
 public:
    /**
     * Read an S-Expression from the given string.
@@ -79,6 +80,7 @@ protected:
 
 class s_number : public s_expression
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(s_number);
 public:
    bool is_number() const { return true; }
 
@@ -90,6 +92,7 @@ protected:
 
 class s_int : public s_number
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(s_int);
 public:
    s_int(int x) : val(x) { }
 
@@ -106,6 +109,7 @@ private:
 
 class s_float : public s_number
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(s_float);
 public:
    s_float(float x) : val(x) { }
 
@@ -119,6 +123,7 @@ private:
 
 class s_symbol : public s_expression
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(s_symbol);
 public:
    s_symbol(const char *, size_t);
 
@@ -135,6 +140,7 @@ private:
 /* Lists of expressions: (expr1 ... exprN) */
 class s_list : public s_expression
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(s_list);
 public:
    s_list();
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 313e720..680c3b8 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1909,3 +1909,6 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
 
    return success;
 }
+
+RALLOC_DEFINE_CLASS_HELPERS(fs_reg);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(fs_inst);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 0c6c3e4..8327b5e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -62,19 +62,8 @@ enum register_file {
 };
 
 class fs_reg {
+   RALLOC_DECLARE_CLASS_HELPERS(fs_reg);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = ralloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
    void init()
    {
       memset(this, 0, sizeof(*this));
@@ -176,19 +165,8 @@ static const fs_reg reg_null_f(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_F);
 static const fs_reg reg_null_d(ARF, BRW_ARF_NULL, BRW_REGISTER_TYPE_D);
 
 class fs_inst : public exec_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(fs_inst);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
    void init()
    {
       memset(this, 0, sizeof(*this));
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cfg.cpp b/src/mesa/drivers/dri/i965/brw_fs_cfg.cpp
index acc0085..528bc73 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cfg.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cfg.cpp
@@ -248,3 +248,8 @@ fs_cfg::make_block_array()
    }
    assert(i == num_blocks);
 }
+
+RALLOC_DEFINE_CLASS_HELPERS(fs_bblock);
+RALLOC_DEFINE_CLASS_HELPERS(fs_cfg);
+
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(fs_bblock_link);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cfg.h b/src/mesa/drivers/dri/i965/brw_fs_cfg.h
index 0038f92..e9efa79 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cfg.h
+++ b/src/mesa/drivers/dri/i965/brw_fs_cfg.h
@@ -28,6 +28,7 @@
 #include "brw_fs.h"
 
 class fs_bblock_link : public exec_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(fs_bblock_link);
 public:
    fs_bblock_link(fs_bblock *block)
       : block(block)
@@ -38,17 +39,8 @@ public:
 };
 
 class fs_bblock {
+   RALLOC_DECLARE_CLASS_HELPERS(fs_bblock);
 public:
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
    fs_bblock_link *make_list(void *mem_ctx);
 
    fs_bblock();
@@ -67,17 +59,8 @@ public:
 };
 
 class fs_cfg {
+   RALLOC_DECLARE_CLASS_HELPERS(fs_cfg);
 public:
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
    fs_cfg(fs_visitor *v);
    ~fs_cfg();
    fs_bblock *new_block();
diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
index 2396051..e0b6f81 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -26,6 +26,8 @@
 
 namespace { /* avoid conflict with opt_copy_propagation_elements */
 struct acp_entry : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(acp_entry);
+public:
    fs_reg dst;
    fs_reg src;
 };
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
index fd28e14..3497f92 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
@@ -34,6 +34,8 @@
 
 namespace {
 struct aeb_entry : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(aeb_entry);
+public:
    /** The instruction that generates the expression value. */
    fs_inst *generator;
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
index 46408da..07507f8 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
@@ -265,3 +265,5 @@ fs_visitor::virtual_grf_interferes(int a, int b)
 
    return start < end;
 }
+
+RALLOC_DEFINE_CLASS_HELPERS(fs_live_variables);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
index 17e7553..9e631d3 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
@@ -51,17 +51,8 @@ struct block_data {
 };
 
 class fs_live_variables {
+   RALLOC_DECLARE_CLASS_HELPERS(fs_live_variables);
 public:
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
    fs_live_variables(fs_visitor *v, fs_cfg *cfg);
    ~fs_live_variables();
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp b/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp
index 910f329..e5c34b0 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp
@@ -54,6 +54,7 @@
 
 class schedule_node : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(schedule_node);
 public:
    schedule_node(fs_inst *inst)
    {
diff --git a/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp b/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
index 7a12e08..88a348e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_vector_splitting.cpp
@@ -51,6 +51,7 @@ static bool debug = false;
 
 class variable_entry : public exec_node
 {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(variable_entry);
 public:
    variable_entry(ir_variable *var)
    {
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 5238ff5..0bcbd35 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -709,4 +709,8 @@ vec4_visitor::opt_compute_to_mrf()
    return progress;
 }
 
+RALLOC_DEFINE_CLASS_HELPERS(reg);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(src_reg);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(dst_reg);
+RALLOC_DEFINE_CLASS_HELPERS_INHERITED(vec4_instruction);
 } /* namespace brw */
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index bc8b392..6e766f6 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -74,6 +74,7 @@ enum register_file {
 
 class reg
 {
+   RALLOC_DECLARE_CLASS_HELPERS(reg);
 public:
    /** Register file: ARF, GRF, MRF, IMM. */
    enum register_file file;
@@ -95,18 +96,8 @@ public:
 
 class src_reg : public reg
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(src_reg);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = ralloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
 
    void init()
    {
@@ -177,19 +168,8 @@ public:
 
 class dst_reg : public reg
 {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(dst_reg);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = ralloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
-
    void init()
    {
       memset(this, 0, sizeof(*this));
@@ -238,18 +218,8 @@ public:
 };
 
 class vec4_instruction : public exec_node {
+   RALLOC_DECLARE_CLASS_HELPERS_INHERITED(vec4_instruction);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
 
    vec4_instruction(vec4_visitor *v, enum opcode opcode,
 		    dst_reg dst = dst_reg(),
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index c021c69..d57b3d7 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -149,18 +149,8 @@ dst_reg::dst_reg(src_reg reg)
 }
 
 class ir_to_mesa_instruction : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(ir_to_mesa_instruction);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
 
    enum prog_opcode op;
    dst_reg dst;
@@ -175,6 +165,7 @@ public:
 };
 
 class variable_storage : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(variable_storage);
 public:
    variable_storage(ir_variable *var, gl_register_file file, int index)
       : file(file), index(index), var(var)
@@ -188,6 +179,7 @@ public:
 };
 
 class function_entry : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(function_entry);
 public:
    ir_function_signature *sig;
 
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index e8d60f8..eed049c 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -197,18 +197,8 @@ st_dst_reg::st_dst_reg(st_src_reg reg)
 }
 
 class glsl_to_tgsi_instruction : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(glsl_to_tgsi_instruction);
 public:
-   /* Callers of this ralloc-based new need not call delete. It's
-    * easier to just ralloc_free 'ctx' (or any of its ancestors). */
-   static void* operator new(size_t size, void *ctx)
-   {
-      void *node;
-
-      node = rzalloc_size(ctx, size);
-      assert(node != NULL);
-
-      return node;
-   }
 
    unsigned op;
    st_dst_reg dst;
@@ -228,6 +218,7 @@ public:
 };
 
 class variable_storage : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(variable_storage);
 public:
    variable_storage(ir_variable *var, gl_register_file file, int index)
       : file(file), index(index), var(var)
@@ -241,6 +232,7 @@ public:
 };
 
 class immediate_storage : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(immediate_storage);
 public:
    immediate_storage(gl_constant_value *values, int size, int type)
    {
@@ -255,6 +247,7 @@ public:
 };
 
 class function_entry : public exec_node {
+   RALLOC_DEFINE_INLINE_CLASS_HELPERS_INHERITED(function_entry);
 public:
    ir_function_signature *sig;
 
-- 
1.7.8.6



More information about the mesa-dev mailing list