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