Thanks for the replies!
As for the helpful "pointer" tohttp://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
- Thanks, but that doesn't give any hints on how to actually DO it,
not DESIGN it. (And I've probably read that at least 30 or so times by
now
)
I'll look into the Boehm GC; I hadn't thought of that.
And... I don't think I understood the, "(Beavis & Butthead) He said
"stack"!!!"...- Hide quoted text -
Emacs also has a conservative scan of the stack as a compile-time
option to find GC roots. The code is IMHO a little easier to
understand than Boehm.
A technique I have seen to get at registers is to use setjmp() and
then scan the jump buffer conservatively.
For what it's worth, a consensus seems to be developing that for
serious projects you cannot rely on conservative GC used with language
implementations that aren't designed for it from the outset.
I have been experimenting with augmenting and preprocessing C to allow
for perfect discovery of pointers on the stack. This augmented
language has structure like this (obviously my test case is a little
lisp interpreter)...
@defun PTR eval(PTR expr, ENV_PTR env, int line_no)
{
PTR p;
if (expr->type == O_CONS)
p = eval(cons(expr), env, line_no);
}
is rewritten to
struct __eval_stack_frame_s {
struct __stack_frame_s *prev;
PTR expr;
ENV_PTR env;
PTR p;
};
PTR __eval(struct __eval_stack_frame *__o, int line_no);
PTR eval(struct __stack_frame_s *prev, PTR expr, ENV_PTR env, int
line_no)
{
struct __eval_stack_frame_s __o = { prev, expr, env, NIL };
return __eval(&__o, line_no);
}
PTR __eval(struct __eval_stack_frame *__o, int line_no)
{
if (__o->expr->type == O_CONS)
__o->p = eval( (struct __stack_frame_s*)__o, line_no);
}
In this manner you always have access to all pointers in all stack
records through the __o stack frame chain. The method has the
overhead of passing one additional pointer per function call and also
threatening high quality register allocation of pointer variables.
The interesting thing is that the top eval() call is automatically
inlined by 3 of 3 optimizers I've tried. Then in some cases the
struct fields are fused with the original parameters so there is no
copying or extra stack space required.
This is not a new idea. I discovered after "inventing" it that it was
tried in a Smalltalk implementation with good success several years
ago.