On Dec-31, Jerome Vouillon wrote:
> On Mon, Dec 30, 2002 at 04:00:55PM -0800, Steve Fink wrote:
> > =head1 Solution 3: Explicity root set augmentation
> > 
> > A final possible solution is to provide a mechanism to temporarily
> > anchor an otherwise unanchored object to the root set. (eg, have an
> > array of objects associated with the interpreter that are all
> > considered to be part of the root set.) This has pretty much the same
> > advantages and disadvantages of explicit neonate flag setting:
> > 
> >  + Simple
> >  + Fast DOD
> >  - Slow for unanchored temporaries
> >  - Sometimes slow for anchored objects (depending on whether they need
> >    to be temporarily anchored before the final anchoring)
> 
> What do you mean by slow here?

For both of those, "slow" refers to the need to append/push infant
objects onto the root set. This will slow down the common case of no
DOD, because they'll need to be added to the root set and removed,
without their membership ever being looked at. Objects which end up
anchored may or may not have to pay that cost, because you may be able
to anchor them before there is any possibility of a DOD run.

As to whether that is truly slow or not -- well, I personally probably
wouldn't worry about it, but I think this very concern has caused this
proposal to be rejected in the past. It's certainly a good candidate
for better benchmarking. If all objects have space for a pointer in
them (eg the next_for_GC link), then it seems quick enough to push
them onto the beginning of a list during allocation. Removing them
from the list is harder, since you'd need to traverse the whole stack.
Although you might be able to eliminate that problem by using both
temporary anchoring and flags, so that you could mark them as "no
longer temporarily anchored" with a single bit flip and strip them all
out in one pass during DOD...

Oops, I think I'm overdoing it again. Your later comment seems correct
-- they'll always be manipulated LIFO anyway, so you can just keep a
top-of-stack pointer before doing anything with them.

> >  - Easy to forget to remove temporaries from the root set
> >  - Easy to double-anchor objects and forget to remove the temporary
> >    anchoring
> >  - longjmp() can bypass the unanchoring
> 
> The temporary objects could be stored in a stack, which is popped when
> leaving the current function (both with normal exits and longjmp).
> This should make it a lot less likely to forget the unanchoring.

How do you do this with longjmp? I could see chaining another handler
onto the longjmp context so that longjmp would backtrack through all
of these allocations, but that would require allocating space for
another context. And allocating space further slows down the common
case...

longjmp is really the major blocker for this option, so if you can
work around it, then maybe we'll have something. Your stack-based
approach sounds plausible as a way to make it easier to handle the
bookkeeping, as long as you don't do it with macros. :-) Maybe wrapper
functions?

  static inline retval some_op()...

  retval wrap_some_op(interp, args...)
  {
    Pobj *stacktop = interp->infants;
    retval rv = some_op(interp, args);
    interp->infants = stacktop;
    return rv;
  }

Reply via email to