Currently, there is a plan to make the Java GC perform some cleanup on Tcl_Obj in
TclBlend. Looking at the root cause for the GC trouble, I think there is a problem
with how TclBlend uses Tcl_Obj reference counting. Here is my analysis. I think if
we fix the reference counting, we don't need to do anything in the GC.
TclBlend does not follow the normal Tcl_Obj reference counting usage. In TclBlend, a
Java TclObject is used as the handle to the underlining Tcl_Obj:
TclObject
CObject
Tcl_Obj
Both Tcl_Obj and TclObject have reference counting. However, when incrementing or
decrementing the reference count on the TclObject, this incrementing or decrementing
is proxied into the native Tcl_Obj. This doesn't seem correct.
In addition, when a new TclObject is created to wrap around a Tcl_Obj, the reference
count of the TclObject is 0, but implicitly, the reference count of Tcl_Obj is
incremented by 1. This doesn't seem right either.
For example, in C, a call to Tcl_GetVar2Ex(...) returns a Tcl_Obj, of which, "The ref
count for the returned object is _not_ incremented to reflect the returned reference;
if you want to keep a reference to the object you must increment its ref count
yourself."
In TclBlend, the corresponding call is "interp->getVar()", which uses
Tcl_GetVar2Ex(...). However, the resulting Tcl_Obj does have its reference count
incremented by 1 implicitly by TclBlend.
The problem with this implicit increment of native Tcl_Obj's reference count is that
someone, namely the GC thread, must decrement the reference count. This causes all
sort of undesirable behaviors such as the GC thread deadlocking because Tcl_Obj's
reference count can only be modified by the thread that first created the Tcl_Obj.
I think we should fix the TclBlend reference counting behavior:
1. do not implicitly increment native Tcl_Obj reference count when creating a new
TclObject that wraps around a Tcl_Obj
2. when incrementing or decrementing reference count on TclObject, also proxy the
action into the native Tcl_Obj
3. when TclBlend code wants to keep a Tcl_Obj for the long term, the code must
increment the reference count
4. the GC thread should do nothing regarding to the native Tcl_Obj
5. put an assert into the TclObject.finalize() to catch cases when the reference count
is not decremented to 0
6. do not pass Tcl_Obj to other threads, this is not supported by Tcl anyway
With this fix, I dont' think there is a need to make the GC free Tcl_Obj.
-- Jiang Wu
[EMAIL PROTECTED]
----------------------------------------------
[EMAIL PROTECTED] is brought to you by
the Stanford Alumni Association and Critical Path.
----------------------------------------------------------------
The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe: send mail to [EMAIL PROTECTED]
with the word SUBSCRIBE as the subject.
To unsubscribe: send mail to [EMAIL PROTECTED]
with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'.
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com