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