[Mesa-dev] [PATCH 04/24] ralloc: Unify overloads of the new operator and guarantee object destruction.
Chad Versace
chad.versace at linux.intel.com
Tue Sep 17 15:30:40 PDT 2013
I like this patch. It removes a lot of boilerplate. And, it makes object
destruction easier to reason about, making it easier to reason about tricky
destruction bugs.
On 09/17/2013 11:59 AM, Paul Berry wrote:
> On 15 September 2013 00:10, Francisco Jerez <currojerez at riseup.net> wrote:
>
>> This patch introduces a pair of helper functions providing a common
>> implementation of the "new" and "delete" operators for all C++ classes
>> that are allocated by ralloc via placement new. The 'ralloc_new'
>> helper function takes care of setting up an ralloc destructor callback
>> that will call the appropriate destructor before the memory allocated
>> to an object is released.
>>
>> Until now objects needed to call 'ralloc_set_destructor' explicitly
>> with a pointer to a static method which in turn called the actual
>> destructor in order to get something that should be transparent to
>> them. After this patch they'll only need to call 'ralloc_new' from
>> the new operator and 'ralloc_delete' from the delete operator, turning
>> all overloads of new and delete into one-liners.
>> ---
>> src/glsl/ast.h | 26 +++----------
>> src/glsl/glsl_parser_extras.h | 9 +----
>> src/glsl/glsl_symbol_table.cpp | 7 +---
>> src/glsl/glsl_symbol_table.h | 23 +----------
>> src/glsl/glsl_types.h | 11 +-----
>> src/glsl/ir_function_detect_recursion.cpp | 11 +-----
>> src/glsl/list.h | 22 ++---------
>> src/glsl/loop_analysis.h | 14 +------
>> src/glsl/ralloc.h | 44
>> ++++++++++++++++++++++
>> src/mesa/drivers/dri/i965/brw_cfg.h | 14 +------
>> src/mesa/drivers/dri/i965/brw_fs.h | 21 ++---------
>> src/mesa/drivers/dri/i965/brw_fs_live_variables.h | 7 +---
>> src/mesa/drivers/dri/i965/brw_vec4.h | 21 ++---------
>> .../drivers/dri/i965/brw_vec4_live_variables.h | 7 +---
>> src/mesa/program/ir_to_mesa.cpp | 7 +---
>> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 7 +---
>> 16 files changed, 77 insertions(+), 174 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/brw_cfg.h
>> b/src/mesa/drivers/dri/i965/brw_cfg.h
>> index 95a18e9..f8037a9 100644
>> --- a/src/mesa/drivers/dri/i965/brw_cfg.h
>> +++ b/src/mesa/drivers/dri/i965/brw_cfg.h
>> @@ -41,12 +41,7 @@ class bblock_t {
>> public:
>> static void* operator new(size_t size, void *ctx)
>> {
>> - void *node;
>> -
>> - node = rzalloc_size(ctx, size);
>> - assert(node != NULL);
>> -
>> - return node;
>> + return ralloc_new<bblock_t>(size, ctx);
>> }
>>
>> bblock_link *make_list(void *mem_ctx);
Post-patch, it's safe for bblock_t to lack an override of operator delete
only because it's destructor is a no-op. However, it remains a no-op only if
the exec_list destructor remains a no-op. I'd like to see bblock_t future-proofed
now against any double-destructor bugs by overriding operator delete.
>> @@ -70,12 +65,7 @@ class cfg_t {
>> public:
>> static void* operator new(size_t size, void *ctx)
>> {
>> - void *node;
>> -
>> - node = rzalloc_size(ctx, size);
>> - assert(node != NULL);
>> -
>> - return node;
>> + return ralloc_new<cfg_t>(size, ctx);
>> }
>>
>
> I'm worried about this one--it introduces a behavioural change.
> Previously, if a cfg_t object was reclaimed through the standard ralloc
> mechanism, cfg_t::~cfg_t() would *not* be called. Now it will be. Since
> cfg_t::~cfg_t() calls ralloc_free(mem_ctx), and since cfg_t's mem_ctx is
> usually (always?) the same mem_ctx that the cfg_t is contained in, I think
> that will result in double-freeing of the mem_ctx.
>
> However, looking further into the users of cfg_t, it looks like they all
> pass it a "borrowed" mem_ctx (in other words, the caller always retains
> responsibility for freeing the mem_ctx. So I believe we have a
> pre-existing double-free bug. The correct solution is probably to get rid
> of the cfg_t destructor entirely.
Whatever you do with cfg_t's destructor, I'd like to an override of operator
delete for the same reason I stated for bblock_t.
Actually, for each class that this patch touches, I want to see an override
of operator delete if one does not already exist, lest a future someone introduces
a bug by changing that class's destructor from trivial to non-trivial but forgets
to override delete as well.
More information about the mesa-dev
mailing list