GC.sizeOf(array.ptr)

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue Sep 30 07:01:17 PDT 2014


On 9/30/14 9:42 AM, Dicebot wrote:
> There is one issue I have encountered during CDGC porting I may need
> advice with.
> Consider this simple snippet:
>
> ```
> import core.memory;
>
> void main()
> {
>      ubyte[] result;
>      result.length = 4096;
>      assert(GC.sizeOf(result.ptr) > 0);
> }
> ``
>
> Assertion passes with D1/Tango runtime but fails with current D2
> runtime. This happens because `result.ptr` is not actually a pointer
> returned by gc_qalloc from array reallocation, but interior pointer 16
> bytes from the start of that block. Druntime stores some metadata
> (length/capacity I presume) in the very beginning.

This is accurate, it stores the "used" size of the array. But it's only 
the case for arrays, not general GC.malloc blocks.

Alternative is to use result.capacity, which essentially looks up the 
same thing (and should be more accurate). But it doesn't cover the same 
inputs.

Trivial note that you only need to allocate 2047 bytes to get this behavior.

>
> As a result GC.sizeOf(array.ptr) results in 0 (being an interior pointer).
>
> Interesting side effect is that this code:
>
> ```
> void main()
> {
>      ubyte[] result;
>      result.length = 4096;
>      GC.free(result.ptr);
> }
> ```
>
> ..does not actually free anything for the very same reason (result.ptr
> is interior pointer), it just silently succeeds doing nothing.

This is a problem. We should provide a definitive way to dealloc an 
array, if it's not already present (assuming delete goes away).

> Is such behaviour intended?

Depends on what part you are talking about ;)

But kidding aside, when I added the array appending update, I didn't 
intend to affect these functions, nor did I consider the cases above. So 
it was not intended to break these things, but I think we can repair 
them, or at least provide alternate means to create the same result.

Interestingly, I think any lookup of block information for an interior 
pointer costs the same as looking up block info for a base pointer. I 
think adding a flag that allows performing operations on interior 
pointers might make this more palatable.

But we absolutely need a way to free an array that does not require the 
knowledge of the inner workings of the runtime.

-Steve


More information about the Digitalmars-d mailing list