Thread overview | ||||||
---|---|---|---|---|---|---|
|
July 05, 2016 Dynamic arrays, emplace and GC | ||||
---|---|---|---|---|
| ||||
Hello, I've been working on some kind of allocator using a dynamic array as a memory pool. I used emplace to allocate class instances within that array, and I was surprised to see I had to use GC.addRange() to avoid the GC to destroy stuff referenced in that array. Here's a chunk of code[1]: struct Pool(T) { public: T alloc(Args...)(Args args) { mData.length++; import core.memory : GC; //GC.addRange(mData[$ - 1].data.ptr, mData[$ - 1].data.length); import std.conv : emplace; auto t = emplace!T(mData[$ - 1].data, args); return t; } private: struct Storage { ubyte[__traits(classInstanceSize, T)] data; } Storage[] mData; } class Foo { this(int a) { aa = a; } ~this() { import std.stdio; writefln("DTOR"); aa = 0; } int aa; } class Blob { this(int b) { foo = new Foo(b); } Foo foo; } void main() { Pool!Blob pool; Blob blob; foreach(a; 0 .. 10000) { blob = pool.alloc(6); } while(true){} import std.stdio; writefln("END"); } Basically Blob instances are allocated in the array using emplace. And Blob creates references to Foo. If I comment out GC.addRange(), I see that Foo destructor is called by the GC[2]. If I leave it uncommented, the GC leaves the array alone. So here's my question: Is it normal??? I thought that allocating memory in a dynamic array using "mData.length++;" was GC-compliant (unlike core.stdc.stdlib.malloc()), and I did not have to explictly use GC.addRange(). [1] I left out alignment management code. It's not the issue here. [2] I used the helpful destructor tracker function of p0nce there: https://p0nce.github.io/d-idioms/#GC-proof-resource-class |
July 05, 2016 Re: Dynamic arrays, emplace and GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Claude | On Tuesday, 5 July 2016 at 10:04:05 UTC, Claude wrote:
> So here's my question: Is it normal???
yes. `ubyte` arrays by definition cannot hold pointers, so GC doesn't bother to scan 'em.
|
July 05, 2016 Re: Dynamic arrays, emplace and GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Tuesday, 5 July 2016 at 12:43:14 UTC, ketmar wrote:
> On Tuesday, 5 July 2016 at 10:04:05 UTC, Claude wrote:
>> So here's my question: Is it normal???
>
> yes. `ubyte` arrays by definition cannot hold pointers, so GC doesn't bother to scan 'em.
Ah ok. I tried using void[size] static array and it seems to work without having to use GC.addRange().
|
July 05, 2016 Re: Dynamic arrays, emplace and GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Claude | On Tuesday, 5 July 2016 at 13:48:46 UTC, Claude wrote:
> Ah ok. I tried using void[size] static array and it seems to work without having to use GC.addRange().
Correct. void[] means the type of the data is unknown, so the GC has to assume it can contain pointers.
This also means that _everything_ in any void buffer has to be treated as a potential pointer. In other words, if you allocate a void buffer and fill it with ints, and one of those ints happens to have a value equal to the address of a GC-allocated object, the GC will assume the int is a pointer to that object and not free it.
|
Copyright © 1999-2021 by the D Language Foundation