[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