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

Reply via email to