[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [sc-dev] Finalizers
No, you have some other problem. GCWrite does not create a reference
and calling toGrey is not a fix.
When you call NewFinalizer is the collect argument true? If so make it
false. You don't want to collect when you have an unreferenced object.
James,
The issue had to do with the way tail call optimizations interact
with the GC.
FinalizerTest {
var finalizerObj;
*prCall { arg selector, unused;
_FinalizerTest_Call
^this.primitiveFailed
}
*prLocum { arg selector, unused;
//nop
{}.value;
^FinalizerTest.prCall(selector, unused);
}
*alloc {
^FinalizerTest.prLocum("alloc", Array.new(5));
}
init {
^FinalizerTest.prLocum("init", Array.new(5));
}
}
init gets TCO'd and as a result, it's frame (which contains the only
reference to alloc's return value) is dereferenced. If the GC
collects inside of prLocum (which the NOP encourages), then alloc's
return value is finalized if the GC is finishing a cycle. Normally
this would not be an issue because the reference to alloc's return
value has legitimately been lost.
However, in order for my SC GC <-> Obj-C retain count scheme to work
I have to make sure that only one SC object exists for any given Obj-
C object. To do this I keep a hash table containing Obj-C object
addresses as keys and their SC object representations as values.
Whenever an Obj-C method returns an object this hash table is
consulted. Problem is that the GC can't be aware of this hash table,
so init was returning an object that had been finalized.
The solution is simple, I just pass "this" to prLocum to make a
reference so it isn't lost in the TCO.
Best,
Ryan