[Mesa-dev] [RFC PATCH 0/5] Safer way to ralloc C++ objects.

Francisco Jerez currojerez at riseup.net
Thu Oct 10 18:17:21 CEST 2013

Francisco Jerez <currojerez at riseup.net> writes:

> This patch series tries out a different approach to allocating C++
> objects from an ralloc context.  It's independent to the last series I
> sent earlier today [1] -- which probably makes sense on its own
> because it's a more incremental improvement and is likely to take less
> time to discuss and review.
> Overriding operator new and delete to allocate from a hierarchical
> allocation context is inherently unsafe because there's no reasonable
> way for the placement new operator to find out what the actual type of
> the object being allocated is, and there's no reasonable way to call
> the destructor when the object released.  The following code from the
> | static void _ralloc_destructor(void *p)
> | {
> |    reinterpret_cast<TYPE *>(p)->~TYPE();
> | }
> has undefined behavior because if the original TYPE has been
> subclassed TYPE is likely not to be the actual allocation type of the
> object, and we will be reinterpreting a void pointer to the derived
> type as a pointer to the base type, which is wrong and will almost
> certainly cause a crash if the conversion requires a pointer
> adjustment -- This is especially dangerous in presence of multiple or
> virtual inheritance, but it's not guaranteed to work in any case.
> Another problem arises if the ralloc operator overrides are defined in
> a non-polymorphic base class, say 'exec_node', and the derived class,
> say 'ir_instruction', implements a non-trivial destructor.  The
> correct destructor will never be called because for ralloc the object
> type is always just 'exec_node'.
> To solve this I've replaced all uses of the overridden new and delete
> operators with calls to new helper functions ralloc_new<>() and
> ralloc_delete<>().  Allocating an object now looks like:
> | T *object = ralloc_new<T>(ralloc_context, first_constructor_argument, ...);
> | ...
> | ralloc_delete(object);
> This has other advantages: The most obvious one is that it reduces the
> amount of boilerplate code that is required for ralloc even further,
> classes no longer need to be decorated with
> DECLARE_RALLOC_CXX_OPERATORS in order to be allocated with ralloc, any
> object type can be instantiated with ralloc_new -- memory management
> is completely decoupled of the object definition itself, and the
> normal and placement built-in new and delete operators are usable
> again on objects that used to be ralloc'ed.
> The C++11 features I've used seem to be supported on GCC 4.3 or later
> [I haven't tested that yet, I don't have such an old version at hand].
> The dependency on C++11 is not fundamental though, and if it seems
> unreasonable it could be removed by use of the HAS_TRIVIAL_DESTRUCTOR
> patch I sent earlier [1] and by making the implementation of
> ralloc_new considerably uglier.
> Thanks.
> [1] http://lists.freedesktop.org/archives/mesa-dev/2013-October/046011.html
> [RFC PATCH 1/5] mesa: Compile all C++ users of ralloc as C++11.
> [RFC PATCH 2/5] ralloc: Add ralloc_new/delete functions for allocation of C++ objects.
> [RFC PATCH 3/5] ralloc: Replace usage of new and delete operator overloads with new helper functions.
> [RFC PATCH 4/5] ralloc: Remove overloads of the placement new and delete operator.
> [RFC PATCH 5/5] glsl: Remove the virtual destructor of ir_instruction.

PATCH 3 was apparently too large for this mailing list...  I've pushed
the whole series here:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 229 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20131010/3856abff/attachment-0001.pgp>

More information about the mesa-dev mailing list