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