Benjamin Goldberg <[EMAIL PROTECTED]> writes:

> But suppose that at the end of DoD, the object we're weakly referring to
> gets marked as alive?  Now, we would need to look through that object's
> list of destroy-functions, and remove all of the weakref-callbacks.

At the end of DoD nobody gets marked alive anymore. The calling of
destroy-functions is done at sweep-time. There might be a problem when
you destroy referent and referee at the same DoD run. Then the
weakref-callback can be called on a dead but not destroyed object. It
is a matter of destruction ordering to destroy the referee first,
which destroyes the weakref.

> But if the weakref-callbacks are stored in a seperate data structure,
> created during DoD, then there's no problem; this data structure will
> get re-created for each DoD pass, and thus always start empty.

This is unnecessary complicated. And it slows down the DoD run by
creating a datastructure.

> Also, by keeping them seperate, we can walk all the callback functions
> before destructing the dead objects.

This is a problem of destruction ordering. You try to solve it by
introducing a seperate step, which works in this special case. But
destruction ordering is a much harder problem.

> (But you're right -- it is too complicated to do a lookup table.  A
> simple linked list should do fine.)
> 
> > But one other thing, what happens if the object holding the weakref
> > dies before the refrenced object? Then the callback-function will be
> > called for a dead object.
> 
> Each callback-function "belongs" to a pmc.  The DoD should be able to
> know this, and act on it.  So if the pmc which registered the callback
> is dead, (or if the object weakly referred has since then come alive),
> then the callback isn't called.
> 
> > So pobject_weakref() needs to return a handle
> > for the weakref and there needs to be a function
> > weakref_destroy(weakref_handle *handle).
> > 
> > Other issue is who owns the data_structure of the weakref? The
> > referent, the referee, or will this be garbage-collected (which makes
> > the weakref_handle a PObj* and weakref_destroy its custom destroy
> > function.
> 
> The garbage collector owns everything except for callback_info, which
> belongs to the pmc which registered the weakref-callback.

This is one possiblity. Therefor the destroy-function of the
registering PMC must be extended with freeing the callback_info. As we
already extend the destroy function of the PMC referenced by the
weakref this needs no new mechanics.

> > > After DOD finishes, the lookup table is walked; for each entry whose
> > > Pobj* hasn't been marked as alive, the callbacks are called.
> > >
> > > The effect of this of course is that a WeakRef has no cost except
> > > during Dead Object Detection.
> > 
> > It only has a cost at object destroy-time. (If the weakrefs are
> > garbagecollected they have an effect on DOD in the way that there are
> > more objects to trace)
> 
> *blink* More objects?  Oh, you're assuming that pobject_weakref is
> returning a Pobj* handle.

Returning a PObj* handle is the other possibility. The registering PMC
holds a hard reference to the callback_info, and the callback_info
deregisters itself when it gets destroyed. The advantage of this
approach is there is no need to malloc/free the memory for
callback_info, it just uses the standard gc-allocator.

> Keeping the callback data in a seperate list which only exists for the
> duration of the dod prevents this.  Or rather, you do have to clean up
> the linked list, of course, but there's no extra bookkeeping.

*blink too* You don't want to use a weakref you want a weak_MARK. The
callbacks are getting registered during each mark, and get used or
destroyed. But this registring and destructing has a cost too. This
cost is only payed by the weakmark-using objects, but they need to be
paid on every DoD run.

> > this is only useful if a hashlookup is fast compared with
> > string_make.
> 
> Well, it might be.  Hashing can be quite fast, ya know.

Only the profiler can tell you which one is faster.

> Here's a better idea, one you'll have more difficulty arguing with --
> imagine a debugger, written in parrot.
> 
> We are going to have one, right?  Hmm, p6tkdb :)
> 
> It needs to keep references to objects it's interested in, but if
> they're strong references, then we would have trouble debugging objects
> with custom destroys (or worse, objects needing timely destruction),
> since the debugger's references to them would prevent them from being
> cleaned up.
> 
> Changing to weakrefs removes this kind of horrible heisenbug.

Something totaly diffrent. DoD runs happen normaly in out of memory
situations. Doing things like running a debugger callback befor a
sweep finishes might ask for trouble. If the debugger is writen in
parrot, then the callback-function which deregisters the object is
surely also written in parrot. Recursive runloops with unfinished
sweeps, combined with early destruction in the inner runloop. This
will be really fun.

bye
boe
-- 
Juergen Boemmels                        [EMAIL PROTECTED]
Fachbereich Physik                      Tel: ++49-(0)631-205-2817
Universitaet Kaiserslautern             Fax: ++49-(0)631-205-3906
PGP Key fingerprint = 9F 56 54 3D 45 C1 32 6F  23 F6 C7 2F 85 93 DD 47

Reply via email to