Componentizing D's garbage collector

Rainer Schuetze r.sagitario at gmx.de
Wed Jan 15 00:48:28 PST 2014


On Monday, 13 January 2014 at 17:45:26 UTC, Dmitry Olshansky
wrote:
> 13-Jan-2014 13:20, Rainer Schuetze пишет:
>> On Sunday, 12 January 2014 at 10:40:50 UTC, Benjamin Thaut 
>> wrote:
>> Having to explicitely pin every pointer passed to C functions 
>> would be
>> very expensive.
>
> How would it be expensive? I don't see a need to do anything to 
> "pin" a memory block, at the time of scanning there will be a 
> potential pointer to it (in the stack space of C function or 
> registers).

The stack reference can be moved outside the memory visible to
the GC:

// D
extern(C) void funC(const char* s);
void main()
{
       funC("Hello".dup.ptr);
}

// C
void funC(const char* s)
{
       SomeStruct* struc = malloc(sizeof(SomeStruct));
       struc->ptr = s;
       s = 0;
       struc->doSomething();
       free(struc);
}

The "s = 0;" will remove the last reference to the passed string
visible to the GC. The duped string might get collected during
execution of "doSomething". This is a problem with the current GC
already, though it is pretty unlikely that both this kind of
operation is used in the C function (or similar) and there are no
other references in the D program.

With a moving GC, references in the D code no longer pin the
object, so the problem appears if the C function just works as
above.

Another bad use case in the C function: the passed stack
parameter is used to iterate to the end of an array and then back
later. The pointer to the end might not be within the GC
allocated memory block anymore, but pointing to the next.


More information about the Digitalmars-d mailing list