[kaffe] Weak references/Class destruction
hkraemer at freenet.de
Thu Dec 23 01:13:41 PST 2004
Guilhem Lavaux <guilhem at kaffe.org> wrote:
> Helmer Krämer wrote:
> >Guilhem Lavaux <guilhem at kaffe.org> wrote:
> >>Here is a patch which changes the way the classes are destroyed and
> >>weak references for boehm-gc and kaffe-gc. This fixes class concurrent
> >>destruction issues which was bugging boehm-gc (and maybe also kaffe-gc) and
> >>should insure that we do not access already freed memory.
> >If I remember it correctly, the problems with boehm-gc and
> >garbage collecting classes are:
> >a) Suppose class A is the only class implementing interface I. If
> > A becomes unreachable, so does I. In this case however, there's
> > no guarantee that C is destroyed before I. This means that destroyClass
> > has to deal with the fact that I might already have been destroyed
> > when C is destroyed. This gets complicated for the implementors
> > table and the interface dispatch tables because destroyClass has
> > to remove C from some of the structures stored inside I.
> >b) Same thing when a class A and its super class A' become unreachable
> > at the same time. In this case, some of the pointers stored in the
> > vtable (and interface dispatch table) may no longer be valid because
> > A' was already destroyed.
> >The solution for a) is to use weak references.
> >The solution for b) is to use allocation types that are automatically
> >freed by the gc for everything that might be stored in a vtable (or
> >interface dispatch table).
> >Is this correct so far?
> Completely right ! :)
The solution for Problem b looks fine to me too, although I'm missing
freeing the gc_layout bitmap (I might have overlooked that, though).
For Problem a, I'm going to describe an alternative solution that
doesn't need weak references, mainly to get some arguments for the
different implementations into the mail archives (the implementation
of weak references itself seems ok to me and should go in so we can
have support for java.lang.ref later on).
The itable2dtable of a class is just one large chunk of memory
containing all dispatch tables of all interfaces. If we stored
the Hjava_lang_Class* of the class owning the itable2dtable at
the beginning of the table, we could use KGC_getObjectBase to get
the class implementing the interfaces (sort of like its done in
stackTrace.c to retrieve the java method of a given pc). All we
need is a pointer somewhere into the itable2dtable chunk.
If we further modified the implementors table to store a pointer into
the itable2dtable instead of an index (soft_lookupinterfacemethod
would look like ncode = ifclass->implementors[cls->impl_idx][idx+1]),
we should get all the information we need to implement destroyClass
without relaying on the gc to keep track of destroyed objects:
A class can still remove itself from the implemented interfaces.
An interface can remove itself from the implementing classes by
traversing the implementors table and using KGC_getObjectBase to
get the implementing class. Since a class is removed from the
implementors table when it is destroyed, we can assume that the
pointers stored in the implementors table are valid when an
interface is destroyed.
Having this sort of table would probably also allow us to easily
implement instanceof_interface in constant time.
More information about the kaffe