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

Francisco Jerez currojerez at riseup.net
Wed Oct 16 00:19:47 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
> DECLARE_RALLOC_CXX_OPERATORS macro:
>
> | 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.
>

I've removed the dependency on C++11 as promised and tried to minimize
the use of templates considerably as requested by Ian.  Please see the
following branch:

http://cgit.freedesktop.org/~currojerez/mesa/log/?h=ralloc-new-less-fancy

Thank you.

> 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.
-------------- 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/20131015/f5a19025/attachment.pgp>


More information about the mesa-dev mailing list