Garbage collector memory leak "feature"?

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Thu Oct 11 04:44:04 PDT 2007


Vladimir Panteleev wrote:
> On Thu, 11 Oct 2007 03:22:24 +0300, Frits van Bommel <fvbommel at remwovexcapss.nl> wrote:
> 
>> Couldn't this be implemented as a lookup table, with elements like
>> (start addr, end addr, (pointer to) stack frame description)? Since this
>> is only needed when the GC paused all threads (assuming a stop-the-world
>> collector) this would allow the GC to walk over all stack frames and use
>> the stack frame descriptions to determine which cells contain pointers.
> 
> Maybe I'm missing some pieces of the picture, but this mean that every time a value is pushed onto the stack, or the meaning of a value changes, that some bit somewhere is set/reset, possibly involving synchronization? That would be quite a performance penalty (up to 100% in stack-heavy programs), no?

First of all, the size and layout of a stack frame are usually pretty 
constant throughout the execution of a function. DMD and IIRC GDC as 
well just subtract a constant from the stack pointer at the beginning of 
a function to allocate all local variables[0]. Only function calls can 
sometimes change the layout (if their parameters are pushed instead of 
MOVed into place). The latter will be even less of an issue on 
architectures (such as amd64) where several parameters are passed in 
registers.
If we allow typeless "gaps" in the stack (such as frames for non-D 
functions and perhaps function parameters that aren't included in the 
stack frame descriptions of the calling functions) those will 
unfortunately also need to be treated conservatively.

On architectures I'm aware of (mostly x86 & amd64) the address of the 
current stack frame is held in a register where it can be easily found 
by the GC, and the current instruction pointer can be used to perform 
the lookup in the table I described. This does mean that things like 
GCCs -fomit-frame-pointer shouldn't be used (which it isn't by default), 
but other than that it should work with all existing code without 
modification. If there are architectures[1] where the address of the 
current stack frame can't be defined in a way that remains constant 
throughout the execution of a function[2] some other solution may have 
to be found there.


[0] Of course, if we model this as "one description per function" there 
may be some false positives if the GC pauses the thread before all local 
variables are initialized, but this should only happen for a single 
function per thread per GC run.
[1] Including x86/amd64 gcc with -fomit-frame-pointer
[2] Or at least throughout large sections of functions



More information about the Digitalmars-d mailing list