------- Additional Comments From Hans dot Boehm at hp dot com 2004-11-25 01:50
-------
After finally finding time to look at the code, it appears that my earlier
guesses were correct.
::java::lang::ref::Reference::create in natReference.cc calls
_Jv_RegisterFinalizer(referent ...), where referent is an arbitrary object,
which may already have a finalizer. This is bad news, since the original
finalizer will be dropped.
The original finalizer may be a Java finalizer, or it may be one that was
registered by the hash synchronization code to clean up a heavy lock entry for
the object. In either case we lose. (The hash synchronization code is careful
to not lose the original finalizer.) In both cases I think, we are likely to
mostly introduce leaks, and crash only occasionally. So this may explain some
other misbehavior.
The fix may require some thought. At a minimum, we need to export more GC
functionality, so that the Reference implementation can retrieve the old
finalizer. (The hash synchronization code currently cheats and goes directly
to the GC interface, which should also be fixed.)
I think that so long as Reference gets the ordering right, and doesn't assume
that all finalizers are Java finalizers, the hash synchronization code should
work. It needs to drop the heavy lock before the object is deallocated, and
while the lock is not held. I don't think the timing otherwise matters. If
the object is resurrected 17 times, we can drop the heavy lock at any of those
points, recreating it if necessary.
This really needs to be fixed to make any use of References reliable.
--
What |Removed |Added
----------------------------------------------------------------------------
CC| |tromey at redhat dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18266