How to destruct class instances allocated by a Region-allocator over a single GC block

Eduard Staniloiu edi33416 at gmail.com
Tue Apr 3 09:14:28 UTC 2018


On Monday, 2 April 2018 at 21:32:47 UTC, Steven Schveighoffer 
wrote:
> On 4/2/18 5:16 PM, Per Nordlöw wrote:
>> On Monday, 2 April 2018 at 20:43:01 UTC, Alexandru Jercaianu 
>> wrote:
>>> I am not completely sure how to solve this, but maybe we can 
>>> find some clues here [1].
>>> It seems like we should use addRoot on the buffer returned by 
>>> GC.instance.allocate to keep it alive.
>>> Then, we can use addRange on each node after allocation and 
>>> somehow use 'TypeInfo' to trigger destructors.
>>> I'll dig into this more tomorrow and come back with a better 
>>> answer.
>> 
>> How can there not be a documented answer for this question, 
>> given that std.experimental.allocator has been in Phobos for 2 
>> years?
>> 
>> Has std.experimental.allocator only been used for allocating 
>> `struct`s?
>> 
>> Is the Region allocator especially misfit for constructing 
>> classes?
>
> Since a while, the GC also calls struct destructors, so it's 
> likely to be a problem for both.
>
> Note, addRoot and addRange will NOT call the destructors 
> appropriately. It will just prevent those memory areas from 
> getting collected. The memory shouldn't be collected anyway 
> because RegionAllocator should have a reference to it.
>
> The only way it will get destroyed is removing the root/range, 
> and then it will get collected just like any other GC block -- 
> same as it is now.
>
> It looks like std.experimental.allocator assumes you will 
> manually destroy items (possibly via dispose), it has no 
> mechanism to say "here's how to destroy this memory I'm 
> allocating if you happen to collect it".
>
> -Steve

The GCAllocator from std.experimental uses the druntime 
core.memory.GC, and allocates with a call to GC.malloc [1]

The GC doesn't know how you are using the memory chunk that he 
provided you with.
He only keeps a track of this chunk and will collect it when 
there are no more references
to it; you could also manually free it, if you wish so, with a 
call to
`GCAllocator.instance.deallocate`.

As Steve has said, you will have to manually destroy the items. I 
recommend using dispose
as it checks if the destroyed object has an explicit destructor, 
which it calls, before deallocating the memory.

So, say `reg` is your allocator, your workflow would be

auto obj = reg.make!Type(args);
/* do stuff */
reg.dispose(obj); // If Type has a __dtor, it will call obj.__dtor
                   // and then reg.deallocate(obj)

Hope this helps.

Cheers,
Edi

[1] - https://dlang.org/library/core/memory/gc.malloc.html


More information about the Digitalmars-d-learn mailing list