I'm remailing this idea since we haven't discussed it in a while.
I would like an elegant, easy to use solution for making the GC
play nicely.
I propose a solution that allows us to draw a electric fence around
the current scope by using some call as follows:
gc_crit();
....
....
gc_leave_crit();
These could be called recursively, and they would result in "generations"
of objects.
Here is how I would implement it, and yes it does add an overhead word
to the headers.
In the interpreter struct we keep
struct interp {
int gc_cur_gen;
int gc_bottom_gen;
int gc_top_gen;
...
}
gc_crit() {
if(cur_gen < top_gen) {
cur_gen = top_gen;
}
cur_gen++;
top_gen++;
}
gc_leave_crit() {
cur_gen--;
if(cur_gen == bottom_gen)
# We are out of all nested calls, release this window
bottom_gen = top_gen;
}
}
gc_alloc_mem() {
obj->gen = interp->cur_gen;
}
gc_collect() {
while(obj = next_obj()) {
if(in_window(obj, interp->bottom_gen, interp->top_gen))
continue;
....
}
}
This creates a sliding scope window that GC must not peep through,
and provides a clean interface for internals writers.
I've done kernel internal work with Linux and critical sections are the norm,
and I think the idiom applies well to GC.
Lets hammer this one design issue out for good because I'm tired of worrying
about it and I think its hindering current Parrot developers and
confusing potential newcomers.
As Bryan Warnock said (I think), this stuff is for internals programmers only,
but the fact that everyone has a different opinion of how to get around GC
bugs me. Lets define a solution, document it, and enforce its usage.
If it is not what I propose, lets at least discuss alternatives.
-Melvin