Hi,

I've implemented the idea. It looks like working fine though instanceof does
not like some particular cases with the new implementation: CLASS_IS_ARRAY,
CLASS_IS_INTERFACE are normal special cases as they do not have any implementors
and so we cannot find their interface ancestors. But it looks like there are some others
when looking at the testcases results. I have still not found them as I'm trying to
fix a deadlock in GCTest.


Also, I think I can remove safely the atomic exchange in soft_fixup_trampoline now and only put a "*where = ret".

Anyway here is the new patch.

Regards,

Guilhem Lavaux.

Helmer Kr�mer wrote:

Guilhem Lavaux <[EMAIL PROTECTED]> wrote:



Helmer Kr�mer wrote:



Guilhem Lavaux <[EMAIL PROTECTED]> wrote:

Hi,





Here is a patch which changes the way the classes are destroyed and implements
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 ! :)



Cool :)

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.

Regards,
Helmer

_______________________________________________
kaffe mailing list
[email protected]
http://kaffe.org/cgi-bin/mailman/listinfo/kaffe




? systems/unix-pthreads/.thread-impl.c.swp
Index: baseClasses.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/baseClasses.c,v
retrieving revision 1.56
diff -u -r1.56 baseClasses.c
--- baseClasses.c       19 Dec 2004 06:25:07 -0000      1.56
+++ baseClasses.c       23 Dec 2004 18:02:50 -0000
@@ -261,6 +261,8 @@
 {
         errorInfo einfo;
 
+       memset(&dummyClassClass, 0, sizeof(dummyClassClass));
+
         /* Primitive types */
         initTypes();
        initVerifierPrimTypes();
Index: classMethod.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/classMethod.c,v
retrieving revision 1.130
diff -u -r1.130 classMethod.c
--- classMethod.c       21 Dec 2004 08:06:36 -0000      1.130
+++ classMethod.c       23 Dec 2004 18:02:51 -0000
@@ -196,7 +196,7 @@
 #endif
                        {
                                class->superclass =
-                                       getClass((uintp)class->superclass,
+                                       
getClass((constIndex)(uintp)class->superclass,
                                                 class,
                                                 einfo);
                        }
@@ -207,6 +207,7 @@
                                success = false;
                                goto done;
                        }
+                       KGC_addWeakRef(main_collector, class->superclass, 
&(class->superclass));
                        if( !(class->accflags & ACC_INTERFACE) &&
                            (class->superclass->accflags & ACC_INTERFACE)) {
                                postExceptionMessage(
@@ -622,7 +623,6 @@
 #endif
                    1) {
                        _SET_METHOD_NATIVECODE(meth, NULL);
-                       KFREE(meth->c.ncode.ncode_start);
                        meth->c.ncode.ncode_start = NULL;
                        meth->c.ncode.ncode_end = NULL;
                }
@@ -803,6 +803,7 @@
 #endif /* HAVE_GCJ_SUPPORT */
 
                class->interfaces[i] = nclass;
+
                lockClass(class);
                if (class->interfaces[i] == 0) {
                        success = false;
@@ -854,10 +855,6 @@
                                newifaces[i] = nclass->interfaces[j];
                        }
                }
-               /* free old list of interfaces */
-               if (class->interfaces != 0) {
-                       KFREE(class->interfaces);
-               }
                class->interfaces = newifaces;
        }
 
@@ -2091,26 +2088,31 @@
                return (true);
        }
 
-       class->if2itable = gc_malloc(class->total_interface_len * 
sizeof(short), KGC_ALLOC_CLASSMISC);
+       class->if2itable = gc_malloc((class->total_interface_len + 1) * 
sizeof(short), KGC_ALLOC_CLASSMISC);
 
        if (class->if2itable == 0) {
                postOutOfMemory(einfo);
                return (false);
        }
 
-       /* first count how many indices we need */
-       j = 0;
+       /* first count how many indices we need. We need at least one entry to 
put
+        * the pointer to the class.
+        */
+       j = 1;
        for (i = 0; i < class->total_interface_len; i++) {
                class->if2itable[i] = j;
                j += 1;         /* add one word to store interface class */
                j += class->interfaces[i]->msize;
        }
-       class->itable2dtable = gc_malloc(j * sizeof(void *), 
KGC_ALLOC_CLASSMISC);
+       /* This last entry is to specify the total length of the table. */
+       class->if2itable[class->total_interface_len] = j;
+       class->itable2dtable = gc_malloc(j * sizeof(void *), 
KGC_ALLOC_INTERFACE_TABLE);
        if (class->itable2dtable == 0) {
                postOutOfMemory(einfo);
                return (false);
        }
-       j = 0;
+       class->itable2dtable[0] = class;
+       j = 1;
        for (i = 0; i < class->total_interface_len; i++) {
                int inm = CLASS_NMETHODS(class->interfaces[i]);
                Method *imeth = CLASS_METHODS(class->interfaces[i]);
@@ -2249,15 +2251,17 @@
                found_i = 1;
                for (j = 0; j < clazz->total_interface_len; j++) {
                        Hjava_lang_Class* iface = clazz->interfaces[j];
-                       int len = 0;
+                       uintp len = 0;
 
-                       if (iface->implementors != 0) {
+                       if (iface->implementors != NULL) {
                                /* This is how many entries follow, so the
-                                * array has a[0] + 1 elements
+                                * array has a[0] + 1 elements. We have to 
convert
+                                * the value from pointer type (which is at 
least 16 bits
+                                * as previously).
                                 */
-                               len = iface->implementors[0];
+                               len = (uintp)iface->implementors[0];
                        }
-                       if (i >= len || iface->implementors[i+1] == -1) {
+                       if (i >= len || iface->implementors[i+1] == NULL) {
                                continue;       /* this one would work */
                        } else {
                                found_i = 0;
@@ -2277,41 +2281,38 @@
         */
        for (j = 0; j < clazz->total_interface_len; j++) {
                Hjava_lang_Class* iface = clazz->interfaces[j];
-               short len;
+               uintp len;
 
                /* make sure the implementor table is big enough */
-               if (iface->implementors == NULL || i > iface->implementors[0]) {
-                       short firstnewentry;
+               if (iface->implementors == NULL || i > 
(uintp)iface->implementors[0]) {
                        if (iface->implementors == NULL) {
                                len = (i + 1) + 4; /* 4 is slack only */
-                               iface->implementors = gc_malloc(len * 
sizeof(short), KGC_ALLOC_CLASSMISC);
+                               iface->implementors = (void ***)gc_malloc(len * 
sizeof(void **), KGC_ALLOC_CLASSMISC);
                        } else {
                                /* double in size */
-                               len = iface->implementors[0] * 2;
+                               len = (uintp)iface->implementors[0] * 2;
                                if (len <= i) {
                                        len = i + 4;
                                }
-                               iface->implementors = gc_realloc(
+                               iface->implementors = (void ***)gc_realloc(
                                        iface->implementors,
-                                       len * sizeof(short), 
KGC_ALLOC_CLASSMISC);
+                                       len * sizeof(void **), 
KGC_ALLOC_CLASSMISC);
                        }
 
-                       if (iface->implementors == 0) {
+                       if (iface->implementors == NULL) {
                                postOutOfMemory(einfo);
                                goto done;
                        }
                        /* NB: we assume KMALLOC/KREALLOC zero memory out */
-                       firstnewentry = iface->implementors[0] + 1;
-                       iface->implementors[0] = len - 1;
+                       iface->implementors[0] = (void *)(len - 1);
 
-                       /* mark new entries as unused */
-                       for (k = firstnewentry; k < len; k++) {
-                               iface->implementors[k] = -1;
-                       }
+                       /* New entries are magically marked as unused by the GC
+                        * as it fills the memory with 0.
+                        */
                }
 
-               assert(i < iface->implementors[0] + 1);
-               iface->implementors[i] = clazz->if2itable[j];
+               assert(i < (uintp)iface->implementors[0] + 1);
+               iface->implementors[i] = 
&(clazz->itable2dtable[clazz->if2itable[j]]);
        }
        rc = true;
 
Index: classMethod.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/classMethod.h,v
retrieving revision 1.73
diff -u -r1.73 classMethod.h
--- classMethod.h       21 Dec 2004 16:51:05 -0000      1.73
+++ classMethod.h       23 Dec 2004 18:02:54 -0000
@@ -131,9 +131,9 @@
        void**                  itable2dtable;
        short                   interface_len;
        short                   total_interface_len;
-       /* indices for all classes implementing this interface */
-       short*                  implementors;   /* interfaces only */
-       int                     impl_index;
+       /* pointers to all itable2dtable entries of classes implementing this 
interface */
+       void***                 implementors;   /* interfaces only */
+        int                    impl_index;    /* index of the class in the 
implementors array. */
 
        Hjava_lang_ClassLoader* loader;
 
Index: gc.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/gc.h,v
retrieving revision 1.30
diff -u -r1.30 gc.h
--- gc.h        21 Dec 2004 08:06:36 -0000      1.30
+++ gc.h        23 Dec 2004 18:02:54 -0000
@@ -72,6 +72,7 @@
        KGC_ALLOC_LINENRTABLE,
        KGC_ALLOC_LOCALVARTABLE,
        KGC_ALLOC_DECLAREDEXC,
+       KGC_ALLOC_INTERFACE_TABLE,
        KGC_ALLOC_CLASSMISC,
 
        /* miscelanious allocation types */
@@ -138,6 +139,8 @@
 
         bool    (*addRef)(Collector *, const void *mem);
         bool    (*rmRef)(Collector *, void *ref);
+        bool    (*addWeakRef)(Collector *, void *mem, void **ref);
+        bool    (*rmWeakRef)(Collector *, void *mem, void **ref);
 };
 
 Collector* createGC(void);
@@ -167,6 +170,10 @@
     ((G)->ops->addRef)((Collector*)(G), (addr))
 #define KGC_rmRef(G, addr) \
     ((G)->ops->rmRef)((Collector*)(G), (addr))
+#define KGC_addWeakRef(G, addr, ref) \
+    ((G)->ops->addWeakRef((Collector *)(G), (addr), (ref)))
+#define KGC_rmWeakRef(G, addr, ref) \
+    ((G)->ops->rmWeakRef((Collector *)(G), (addr), (ref)))
 
 #if !defined(KAFFEH)
 static inline void KGC_markObject(void *g, void *gc_info, const void *addr)
Index: gcFuncs.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/gcFuncs.c,v
retrieving revision 1.62
diff -u -r1.62 gcFuncs.c
--- gcFuncs.c   21 Dec 2004 16:51:05 -0000      1.62
+++ gcFuncs.c   23 Dec 2004 18:02:54 -0000
@@ -44,6 +44,7 @@
 #include "thread.h"
 #include "methodCache.h"
 #include "jvmpi_kaffe.h"
+#include "methodcalls.h"
 
 /*****************************************************************************
  * Class-related functions
@@ -135,22 +136,16 @@
                                }
 #endif
                        }
-                        utf8ConstRelease(m->name);
+                       utf8ConstRelease(m->name);
                         utf8ConstRelease(METHOD_SIG(m));
                         KFREE(METHOD_PSIG(m));
                         KFREE(m->lines);
                        KFREE(m->lvars);
                        if( m->ndeclared_exceptions != -1 )
-                               KFREE(m->declared_exceptions);
+                         KFREE(m->declared_exceptions);
                         KFREE(m->exception_table);
-                        KFREE(m->c.bcode.code);         /* aka 
c.ncode.ncode_start */
 
-                       /* Free ncode if necessary: this concerns
-                        * any uninvoked trampolines
-                        */
-                       if (KGC_getObjectIndex(collector, ncode) != -1) {
-                               KFREE(ncode);
-                       }
+                       /* ncode is swept by the GC. */
                        m++;
                 }
                 KFREE(CLASS_METHODS(clazz));
@@ -167,71 +162,78 @@
                }
        }
        /* free constant pool */
-       if (pool->data != 0) {
-               KFREE(pool->data);
-       }
+       if (pool->data != NULL)
+         {
+           KFREE(pool->data);
+         }
 
         /* free various other fixed things */
         KFREE(CLASS_STATICDATA(clazz));
-       if( clazz->vtable )
-       {
-               for( i = 0; i < clazz->msize; i++ )
-               {
-                       if( clazz->vtable->method[i] == 0 )
-                               continue;
-                       /* Free ncode if necessary: this concerns
-                        * any uninvoked trampolines
-                        */
-                       if (KGC_getObjectIndex(collector,
-                                             clazz->vtable->method[i])
-                           == KGC_ALLOC_DISPATCHTABLE) {
-                               KFREE(clazz->vtable->method[i]);
-                       }
-               }
-               KFREE(clazz->vtable);
-       }
-        KFREE(clazz->if2itable);
-       if( clazz->itable2dtable )
-       {
-               for (i = 0; i < clazz->total_interface_len; i++) {
-                       Hjava_lang_Class* iface = clazz->interfaces[i];
 
-                       /* only if interface has not been freed already */
-                       if (KGC_getObjectIndex(collector, iface)
-                           == KGC_ALLOC_CLASSOBJECT)
-                       {
-                               iface->implementors[clazz->impl_index] = -1;
-                       }
-               }
+               if(clazz->vtable != NULL)
+         {
+           /* The native methods in the vtable are swept by the GC. */
+           KFREE(clazz->vtable);
+         }
 
-               /* NB: we can't just sum up the msizes of the interfaces
-                * here because they might be destroyed simultaneously
+        KFREE(clazz->if2itable);
+
+       if (clazz->implementors != NULL)
+         {
+           uintp len, uidx;
+
+           len = (uintp)clazz->implementors[0] + 1;
+           for (uidx = 1; uidx < len; uidx++)
+             {
+               void *impl = clazz->implementors[uidx];
+               Hjava_lang_Class **impl_clazz;
+
+               if (impl == NULL)
+                 continue;
+               
+               impl_clazz = (Hjava_lang_Class **)KGC_getObjectBase(collector, 
impl);
+               assert(impl_clazz != NULL);
+
+               /* We must walk the list of interfaces for this class and
+                * unregister this interface. As the class should also be
+                * freed (in the other case this interface would not have 
+                * been destroyed), there is no problem with this.
                 */
-               j = KGC_getObjectSize(collector, clazz->itable2dtable)
-                       / sizeof (void*);
-               for( i = 0; i < j; i++ )
-               {
-                       if (KGC_getObjectIndex(collector,
-                                             clazz->itable2dtable[i])
-                           == KGC_ALLOC_DISPATCHTABLE) {
-                               KGC_free(collector, clazz->itable2dtable[i]);
-                       }
-               }
-               KGC_free(collector, clazz->itable2dtable);
-       }
-       if( clazz->gc_layout &&
-           (clazz->superclass->gc_layout != clazz->gc_layout) )
+               for (i = 0; i < (*impl_clazz)->total_interface_len; i++)
+                 if ((*impl_clazz)->interfaces[i] == clazz)
+                   {
+                     (*impl_clazz)->interfaces[i] = NULL;
+                     break;
+                   }
+             }
+           
+           KFREE(clazz->implementors);
+         }
+
+       if( clazz->itable2dtable )
        {
-               KFREE(clazz->gc_layout);
+         for (i = 0; i < clazz->total_interface_len; i++) {
+           Hjava_lang_Class* iface = clazz->interfaces[i];
+           
+           /* only if interface has not been freed already. We
+            * update the implementors section of the interface
+            * accordingly.
+            */
+           if (iface != NULL)
+             iface->implementors[clazz->impl_index] = NULL;
+         }
+         /* The itable2dtable table will be automatically swept by the
+          * GC when the class becomes unused as it is only marked while
+          * the class is being walked (see walkClass).
+          */
        }
+       if (clazz->gc_layout != NULL && clazz->superclass != NULL &&
+           clazz->superclass->gc_layout != clazz->gc_layout)
+         KFREE(clazz->gc_layout);
+
        KFREE(clazz->sourcefile);
-       KFREE(clazz->implementors);
        KFREE(clazz->inner_classes);
 
-        /* The interface table for array classes points to static memory */
-        if (!CLASS_IS_ARRAY(clazz)) {
-                KFREE(clazz->interfaces);
-        }
         utf8ConstRelease(clazz->name);
 }
 
@@ -243,7 +245,19 @@
 walkMethods(Collector* collector, void *gc_info, Method* m, int nm)
 {
         while (nm-- > 0) {
+               int index;
+
                 KGC_markObject(collector, gc_info, m->class);
+               
+               index = KGC_getObjectIndex(collector, m->ncode);
+               if (index == KGC_ALLOC_JITCODE || index == KGC_ALLOC_TRAMPOLINE)
+                 KGC_markObject(collector, gc_info, m->ncode);
+               
+               index = KGC_getObjectIndex(collector, m->c.bcode.code);
+               if (index == KGC_ALLOC_JITCODE || index == KGC_ALLOC_TRAMPOLINE 
||
+                   index == KGC_ALLOC_BYTECODE)
+                 KGC_markObject(collector, gc_info, m->c.bcode.code);
+               
 
                 /* walk exception table in order to keep resolved catch types
                    alive */
@@ -282,7 +296,35 @@
 
         if (class->state >= CSTATE_PREPARED) {
                 KGC_markObject(collector, gc_info, class->superclass);
-        }
+        } 
+
+        /* We only need the interface array to be allocated.
+        * We do not want to mark array's interfaces as the pointer is
+        * static (see lookupArray). */
+       if (class->interfaces != NULL && CLASS_CNAME(class)[0] != '[')
+          {
+            KGC_markObject(collector, gc_info, class->interfaces);
+          }
+
+       if (class->itable2dtable != NULL)
+         {
+           unsigned int len = class->if2itable[class->total_interface_len];
+           KGC_markObject(collector, gc_info, class->itable2dtable);
+
+           for (idx = 1; idx < len; idx++)
+             {
+               void *method = class->itable2dtable[idx];
+               int index;
+               
+               if (method == (void*)-1)
+                 continue;
+               
+               index = KGC_getObjectIndex(collector, method);
+               
+               if (index == KGC_ALLOC_JITCODE || index == KGC_ALLOC_TRAMPOLINE)
+                 KGC_markObject(collector, gc_info, method);
+             }
+         }
 
         /* walk constant pool - only resolved classes and strings count */
         pool = CLASS_CONSTANTS(class);
@@ -298,6 +340,18 @@
                 }
         }
 
+       /* walk the local vtable */
+       if (class->vtable != NULL && !CLASS_IS_PRIMITIVE(class))
+         for (idx = 0; idx < class->msize; idx++)
+           {
+             void *method = class->vtable->method[idx];
+             int index = KGC_getObjectIndex(collector, method);
+
+             if (index == KGC_ALLOC_JITCODE || index == KGC_ALLOC_TRAMPOLINE ||
+                 index == KGC_ALLOC_BYTECODE)
+               KGC_markObject(collector, gc_info, method);
+           }
+
         /*
          * NB: We suspect that walking the class pool should suffice if
          * we ensured that all classes referenced from this would show up
@@ -370,6 +424,25 @@
                }
         }
 
+       /* Now we walk the interface table pointer. */
+       if (class->itable2dtable != NULL)
+         {
+           unsigned int num_interfaces;
+
+           KGC_markObject(collector, gc_info, class->itable2dtable);
+           /* We want the number of interfaces registered in the table. As
+            * this number is not recorded in the table we recompute it
+            * quickly using if2itable. (See 
classMethod.c/buildInterfaceDispatchTable).
+            */
+           for (idx = 1, n = 0; n < class->total_interface_len; n++)
+             {
+               void *iface = class->itable2dtable[idx];
+               
+               KGC_markObject(collector, gc_info, iface);
+               idx += class->interfaces[n]->msize+1;
+             }
+         }
+
         /* CLASS_METHODS only points to the method array for non-array and
          * non-primitive classes */
         if (!CLASS_IS_PRIMITIVE(class) && !CLASS_IS_ARRAY(class) && 
CLASS_METHODS(class) != 0) {
@@ -613,11 +686,19 @@
            "j.l.ClassLoader");
        KGC_registerGcTypeByIndex(gc, KGC_ALLOC_THREADCTX, 
            NULL, KGC_OBJECT_NORMAL, NULL, "thread-ctxts");
+       KGC_registerGcTypeByIndex(gc, KGC_ALLOC_INTERFACE,
+           NULL, KGC_OBJECT_NORMAL, NULL, "interfaces");
+       KGC_registerGcTypeByIndex(gc, KGC_ALLOC_INTERFACE_TABLE,
+            NULL, KGC_OBJECT_NORMAL, NULL, "interface table");
+       KGC_registerGcTypeByIndex(gc, KGC_ALLOC_TRAMPOLINE,
+           NULL, KGC_OBJECT_NORMAL, NULL, "trampoline");
+       KGC_registerGcTypeByIndex(gc, KGC_ALLOC_JITCODE,
+           NULL, KGC_OBJECT_NORMAL, NULL, "jit-code");
+       KGC_registerGcTypeByIndex(gc, KGC_ALLOC_BYTECODE,
+           NULL, KGC_OBJECT_NORMAL, NULL, "java-bytecode");
 
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_STATIC_THREADDATA, 
"thread-data");
-       KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_BYTECODE, "java-bytecode");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_EXCEPTIONTABLE, "exc-table");
-       KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JITCODE, "jitcode");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_STATICDATA, "static-data");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CONSTANT, "constants");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_FIXED, "other-fixed");
@@ -625,7 +706,6 @@
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_METHOD, "methods");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_FIELD, "fields");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_UTF8CONST, "utf8consts");
-       KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_INTERFACE, "interfaces");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_LOCK, "locks");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_REF, "gc-refs");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JITTEMP, "jit-temp-data");
@@ -637,7 +717,6 @@
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_DECLAREDEXC, "declared-exc");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_CLASSMISC, "class-misc");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_VERIFIER, "verifier");
-       KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_TRAMPOLINE, "trampoline");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_NATIVELIB, "native-lib");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_SEQ, "jit-seq");
        KGC_registerFixedTypeByIndex(gc, KGC_ALLOC_JIT_CONST, "jit-const");
Index: soft.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/soft.c,v
retrieving revision 1.73
diff -u -r1.73 soft.c
--- soft.c      21 Dec 2004 05:49:59 -0000      1.73
+++ soft.c      23 Dec 2004 18:02:54 -0000
@@ -238,7 +238,7 @@
        Hjava_lang_Class* cls;
        void*   ncode;
        register int i;
-       register short* implementors;
+       register void*** implementors;
 
        if (obj == NULL) {
                soft_nullpointer();
@@ -262,7 +262,7 @@
        }
 #endif
        /* skip word at the beginning of itable2dtable */
-       ncode = cls->itable2dtable[implementors[i] + idx + 1];
+       ncode = implementors[i][idx + 1];
 
        /* This means this class does not implement this interface method
         * at all.  This is something we detect at the time the interface
@@ -272,11 +272,11 @@
         * is that's missing (or create multiple nosuch_method routines,
         * given that they should be rare---minus possible DoS.)
         */
-       if (ncode == (void *)-1) {
-               return NULL;
-       }
+       if (ncode == (void *)-1)
+         return NULL;
        assert(ncode != NULL);
-       return (ncode);
+
+       return ncode;
 }
 
 inline
@@ -299,14 +299,38 @@
 instanceof_interface(Hjava_lang_Class* c, Hjava_lang_Class* oc)
 {
        int i;
+       Hjava_lang_Class **impl_clazz;
 
-       /* Check 'total' interface list */
-       for (i = oc->total_interface_len - 1; i >= 0; i--) {
-               if (c == oc->interfaces[i]) {
-                       return (1);
-               }
-       }
-       return (0);
+       if (1 || c->state < CSTATE_PREPARED || CLASS_IS_ARRAY(oc) || 
CLASS_IS_INTERFACE(oc))
+         {
+           /* Check 'total' interface list. If the class is not
+            * prepared the dumb way is the only way. Arrays and interface do 
not have
+            * any implementors too so we have to go through the all list.
+            */
+           for (i = oc->total_interface_len - 1; i >= 0; i--) {
+             if (c == oc->interfaces[i]) {
+               return 1;
+             }
+           }
+           return 0;
+         }
+       else
+         {
+           /* Fetch the implementation reference from the class. */
+           i = oc->impl_index;
+           /* No interface implemented or this class is not implementing this
+            * interface. Bailing out. */
+           if (i == 0 || i >= (uintp)c->implementors[0] ||
+               c->implementors[i] == NULL)
+             return 0;
+           
+           /* We retrieve the first pointer in the itable2dtable array. */
+           impl_clazz = (Hjava_lang_Class 
**)(KGC_getObjectBase(main_collector, c->implementors[i]));
+           assert(impl_clazz != NULL);
+           
+           /* Now we may compare the raw pointers. */
+           return (*impl_clazz == oc);
+         }
 }
 
 inline
Index: boehm-gc/gc-refs.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c,v
retrieving revision 1.3
diff -u -r1.3 gc-refs.c
--- boehm-gc/gc-refs.c  9 Aug 2004 08:18:21 -0000       1.3
+++ boehm-gc/gc-refs.c  23 Dec 2004 18:02:54 -0000
@@ -29,17 +29,29 @@
 #include "gc2.h"
 
 #define        REFOBJHASHSZ    128
-typedef struct _refObject {
+typedef struct _strongRefObject {
   const void*          mem;
   unsigned int         ref;
-  struct _refObject*   next;
-} refObject;
+  struct _strongRefObject* next;
+} strongRefObject;
 
-typedef struct _refTable {
-  refObject*           hash[REFOBJHASHSZ];
-} refTable;
+typedef struct _strongRefTable {
+  strongRefObject*             hash[REFOBJHASHSZ];
+} strongRefTable;
+
+typedef struct _weakRefObject {
+  const void *          mem;
+  unsigned int          ref;
+  void ***              allRefs;
+  struct _weakRefObject *next;
+} weakRefObject;
+
+typedef struct _weakRefTable {
+  weakRefObject*               hash[REFOBJHASHSZ];
+} weakRefTable;
 
-static refTable                        refObjects;
+static strongRefTable                  strongRefObjects;
+static weakRefTable                     weakRefObjects;
 
 /* This is a bit homemade.  We need a 7-bit hash from the address here */
 #define        REFOBJHASH(V)   ((((uintp)(V) >> 2) ^ ((uintp)(V) >> 
9))%REFOBJHASHSZ)
@@ -51,10 +63,10 @@
 KaffeGC_addRef(Collector *collector, const void* mem)
 {
   uint32 idx;
-  refObject* obj;
+  strongRefObject* obj;
 
   idx = REFOBJHASH(mem);
-  for (obj = refObjects.hash[idx]; obj != 0; obj = obj->next) {
+  for (obj = strongRefObjects.hash[idx]; obj != 0; obj = obj->next) {
     /* Found it - just increase reference */
     if (obj->mem == mem) {
       obj->ref++;
@@ -63,14 +75,14 @@
   }
 
   /* Not found - create a new one */
-  obj = (refObject*)GC_malloc_uncollectable(sizeof(refObject));
+  obj = (strongRefObject*)GC_malloc_uncollectable(sizeof(strongRefObject));
   if (!obj)
     return false;
        
   obj->mem = ALIGN_BACKWARD(mem);
   obj->ref = 1;
-  obj->next = refObjects.hash[idx];
-  refObjects.hash[idx] = obj;
+  obj->next = strongRefObjects.hash[idx];
+  strongRefObjects.hash[idx] = obj;
   return true;
 }
 
@@ -82,13 +94,13 @@
 KaffeGC_rmRef(Collector *collector, const void* mem)
 {
   uint32 idx;
-  refObject** objp;
-  refObject* obj;
+  strongRefObject** objp;
+  strongRefObject* obj;
 
   idx = REFOBJHASH(mem);
   mem = ALIGN_BACKWARD(mem);
 
-  for (objp = &refObjects.hash[idx]; *objp != 0; objp = &obj->next) {
+  for (objp = &strongRefObjects.hash[idx]; *objp != 0; objp = &obj->next) {
     obj = *objp;
     /* Found it - just decrease reference */
     if (obj->mem == mem) {
@@ -103,4 +115,117 @@
 
   /* Not found!! */
   return false;
+}
+
+bool
+KaffeGC_addWeakRef(Collector *collector, void* mem, void** refobj)
+{
+  int idx;
+  weakRefObject* obj;
+
+  idx = REFOBJHASH(mem);
+  for (obj = weakRefObjects.hash[idx]; obj != 0; obj = obj->next) {
+    /* Found it - just register a new weak reference */
+    if (obj->mem == mem) {
+      void ***newRefs;
+      obj->ref++;
+
+      newRefs = (void ***)GC_malloc_uncollectable(sizeof(void ***)*obj->ref);
+      memcpy(newRefs, obj->allRefs, sizeof(void ***)*(obj->ref-1));
+      GC_free(obj->allRefs);
+
+      obj->allRefs = newRefs;
+      obj->allRefs[obj->ref-1] = refobj;
+      return true;
+    }
+  }
+
+  /* Not found - create a new one */
+  obj = (weakRefObject*)GC_malloc_uncollectable(sizeof(weakRefObject));
+  if (!obj)
+    return false;
+
+  obj->mem = mem;
+  obj->ref = 1;
+  obj->allRefs = (void ***)GC_malloc_uncollectable(sizeof(void ***));
+  obj->allRefs[0] = refobj;
+  obj->next = weakRefObjects.hash[idx];
+  weakRefObjects.hash[idx] = obj;
+  return true;
+}
+
+bool
+KaffeGC_rmWeakRef(Collector *collector, void* mem, void** refobj)
+{
+  uint32 idx;
+  weakRefObject** objp;
+  weakRefObject* obj;
+  unsigned int i;
+
+  idx = REFOBJHASH(mem);
+  for (objp = &weakRefObjects.hash[idx]; *objp != 0; objp = &obj->next) {
+    obj = *objp;
+    /* Found it - just decrease reference */
+    if (obj->mem == mem)
+      {
+       for (i = 0; i < obj->ref; i++)
+         {
+           if (obj->allRefs[i] == refobj)
+             {
+               void ***newRefs;
+               
+               obj->ref--;
+               newRefs = (void ***)GC_malloc_uncollectable(sizeof(void 
***)*obj->ref);
+               memcpy(newRefs, obj->allRefs, i*sizeof(void ***));
+               memcpy(&newRefs[i], &obj->allRefs[i+1], obj->ref*sizeof(void 
***));
+               GC_free(obj->allRefs);
+               obj->allRefs = newRefs;
+               break;
+             }
+         }
+       if (i == obj->ref)
+         return false;
+       if (obj->ref == 0) {
+         *objp = obj->next;
+         GC_free(obj);
+       }
+       return true;
+      }
+  }
+
+  /* Not found!! */
+  return false;
+}
+
+/**
+ * This function clear all weak references to the specified object. 
+ * The references are then removed from the database.
+ *
+ * @param collector a garbage collector instance.
+ * @param mem a valid memory object.
+ */
+void
+KaffeGC_clearWeakRef(Collector *collector, void* mem)
+{ 
+  uint32 idx;
+  weakRefObject** objp;
+  weakRefObject* obj;
+  unsigned int i;
+
+  idx = REFOBJHASH(mem);
+  for (objp = &weakRefObjects.hash[idx]; *objp != 0; objp = &obj->next)
+    {
+      obj = *objp;
+      /* Found it - clear all references attached to it. */
+      if (obj->mem == mem)
+       {
+         for (i = 0; i < obj->ref; i++)
+           *(obj->allRefs[i]) = NULL;
+         GC_free(obj->allRefs);
+
+         *objp = obj->next;
+         GC_free(obj);
+         return;
+       }
+    }
 }
Index: boehm-gc/gc-refs.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/boehm-gc/gc-refs.h,v
retrieving revision 1.1
diff -u -r1.1 gc-refs.h
--- boehm-gc/gc-refs.h  2 Aug 2004 10:44:56 -0000       1.1
+++ boehm-gc/gc-refs.h  23 Dec 2004 18:02:54 -0000
@@ -18,5 +18,8 @@
 struct _Collector;
 bool KaffeGC_addRef(struct _Collector *collector, const void* mem);
 bool KaffeGC_rmRef(struct _Collector *collector, const void* mem);
+bool KaffeGC_addWeakRef(struct _Collector *collector, void *mem, void **obj);
+bool KaffeGC_rmWeakRef(struct _Collector *collector, void *mem, void **obj);
+void KaffeGC_clearWeakRef(struct _Collector *collector, void *mem);
 
 #endif /* __gcrefs_h */
Index: boehm-gc/gc2.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/boehm-gc/gc2.c,v
retrieving revision 1.7
diff -u -r1.7 gc2.c
--- boehm-gc/gc2.c      16 Dec 2004 06:13:52 -0000      1.7
+++ boehm-gc/gc2.c      23 Dec 2004 18:02:54 -0000
@@ -145,6 +145,8 @@
   if (f->final != KGC_OBJECT_NORMAL && f->final != NULL)
     f->final(&boehm_gc.collector, ALIGN_FORWARD(ob));
 
+  KaffeGC_clearWeakRef(&boehm_gc.collector, ALIGN_FORWARD(ob));
+
   if (f->destroy != NULL)
     f->destroy(&boehm_gc.collector, ALIGN_FORWARD(ob));
 }
@@ -498,7 +500,9 @@
 static void
 KaffeGC_warnproc(char *msg, GC_word arg)
 {
-DBG(GCDIAG, dprintf(msg, arg); )
+DBG(GCDIAG, 
+     dprintf(msg, arg);
+    );
 }
 
 static void
@@ -544,7 +548,6 @@
     }
 }
 
-
 /*
  * vtable for object implementing the collector interface.
  */
@@ -574,7 +577,9 @@
   KaffeGC_HeapLimit,
   KaffeGC_HeapTotal,
   KaffeGC_addRef,
-  KaffeGC_rmRef
+  KaffeGC_rmRef,
+  KaffeGC_addWeakRef,
+  KaffeGC_rmWeakRef
 };
 
 /*
Index: intrp/methodcalls.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/intrp/methodcalls.c,v
retrieving revision 1.3
diff -u -r1.3 methodcalls.c
--- intrp/methodcalls.c 21 Oct 2004 14:20:34 -0000      1.3
+++ intrp/methodcalls.c 23 Dec 2004 18:02:54 -0000
@@ -139,3 +139,4 @@
        }
 
 }
+
Index: jit/methodcalls.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jit/methodcalls.c,v
retrieving revision 1.5
diff -u -r1.5 methodcalls.c
--- jit/methodcalls.c   21 Dec 2004 05:50:00 -0000      1.5
+++ jit/methodcalls.c   23 Dec 2004 18:02:54 -0000
@@ -63,17 +63,13 @@
         */
 #if defined(COMPARE_AND_EXCHANGE)
        if (COMPARE_AND_EXCHANGE(where, tramp, METHOD_NATIVECODE(meth))) {
-               gc_free(tramp);
+               ;
        }
 #elif defined(ATOMIC_EXCHANGE)
        {
                void *tmp = METHOD_NATIVECODE(meth);
 
                ATOMIC_EXCHANGE(where, tmp);
-
-               if (tmp == tramp) {
-                       gc_free(tramp);
-               }
        }
 #else
 #error "You have to define either COMPARE_AND_EXCHANGE or ATOMIC_EXCHANGE"
@@ -182,6 +178,7 @@
                                !!!"Cannot override trampoline anchor");
                }
                ret = tramp;
+               //              gc_add_ref(tramp);
        } else {
                if (CLASS_GCJ((meth)->class)) {
                        _SET_METHOD_NATIVECODE(meth, meth->ncode);
Index: jit/methodcalls.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jit/methodcalls.h,v
retrieving revision 1.2
diff -u -r1.2 methodcalls.h
--- jit/methodcalls.h   21 Aug 2004 14:53:32 -0000      1.2
+++ jit/methodcalls.h   23 Dec 2004 18:02:54 -0000
@@ -42,5 +42,4 @@
  */
 #define engine_reservedArgs(M) 0
 
-
 #endif /* __method_dispatch_h__ */
Index: jit3/machine.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jit3/machine.c,v
retrieving revision 1.67
diff -u -r1.67 machine.c
--- jit3/machine.c      22 Dec 2004 00:22:05 -0000      1.67
+++ jit3/machine.c      23 Dec 2004 18:02:55 -0000
@@ -585,8 +585,6 @@
 
        SET_METHOD_JITCODE(meth, code->code);
 
-       if( meth->c.bcode.code )
-               gc_free(meth->c.bcode.code);
        meth->c.ncode.ncode_start = code->mem;
        meth->c.ncode.ncode_end = (void*)((uintp)code->code + code->codelen);
        
@@ -634,8 +632,6 @@
 #if defined(FLUSH_DCACHE)
        FLUSH_DCACHE(code->code, (void*)((uintp)code->code + code->codelen));
 #endif
-
-       gc_free(tramp);
 
        /* Translate exception table and make it available */
        if (meth->exception_table != 0) {
Index: jni/jni-callmethod.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jni/jni-callmethod.c,v
retrieving revision 1.4
diff -u -r1.4 jni-callmethod.c
--- jni/jni-callmethod.c        20 Dec 2004 00:13:16 -0000      1.4
+++ jni/jni-callmethod.c        23 Dec 2004 18:02:55 -0000
@@ -28,7 +28,7 @@
 getMethodFunc (Method* meth, Hjava_lang_Object *obj)
 {
   if (obj && CLASS_IS_INTERFACE (meth->class)) {
-    register short *implementors;
+    register void ***implementors;
     register Hjava_lang_Class *clazz;
                
     assert (meth->idx >= 0);
@@ -36,9 +36,9 @@
     implementors = meth->class->implementors;
     clazz = OBJECT_CLASS(obj);
 
-    assert (implementors != NULL && clazz->impl_index <= implementors[0]);
+    assert (implementors != NULL && clazz->impl_index <= 
(uintp)implementors[0]);
                
-    return clazz->itable2dtable[implementors[clazz->impl_index] + meth->idx + 
1];      
+    return implementors[clazz->impl_index][meth->idx + 1];     
   } else {
     return meth->idx >= 0 ? obj->vtable->method[meth->idx] : METHOD_NATIVECODE 
(meth);
   }
Index: kaffe-gc/gc-incremental.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/kaffe-gc/gc-incremental.c,v
retrieving revision 1.16
diff -u -r1.16 gc-incremental.c
--- kaffe-gc/gc-incremental.c   20 Dec 2004 01:39:21 -0000      1.16
+++ kaffe-gc/gc-incremental.c   23 Dec 2004 18:02:55 -0000
@@ -799,6 +799,9 @@
                }
 #endif
 
+               /* clear all weak references to the object */
+               KaffeGC_clearWeakRef(gcif, UTOMEM(unit));
+
                /* invoke destroy function before freeing the object */
                info = gc_mem2block(unit);
                idx = GCMEM2IDX(info, unit);
@@ -1475,7 +1478,9 @@
        gcGetHeapLimit,
        gcGetHeapTotal,
        KaffeGC_addRef,
-       KaffeGC_rmRef
+       KaffeGC_rmRef,
+       KaffeGC_addWeakRef,
+       KaffeGC_rmWeakRef
 };
 
 /*
Index: kaffe-gc/gc-refs.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/kaffe-gc/gc-refs.c,v
retrieving revision 1.8
diff -u -r1.8 gc-refs.c
--- kaffe-gc/gc-refs.c  21 Dec 2004 11:46:54 -0000      1.8
+++ kaffe-gc/gc-refs.c  23 Dec 2004 18:02:55 -0000
@@ -28,17 +28,29 @@
 #include "java_lang_Thread.h"
 
 #define        REFOBJHASHSZ    128
-typedef struct _refObject {
+typedef struct _strongRefObject {
   const void*          mem;
   unsigned int         ref;
-  struct _refObject*   next;
-} refObject;
+  struct _strongRefObject* next;
+} strongRefObject;
 
-typedef struct _refTable {
-  refObject*           hash[REFOBJHASHSZ];
-} refTable;
+typedef struct _strongRefTable {
+  strongRefObject*             hash[REFOBJHASHSZ];
+} strongRefTable;
+
+typedef struct _weakRefObject {
+  const void *          mem;
+  unsigned int          ref;
+  void ***              allRefs;
+  struct _weakRefObject *next;
+} weakRefObject;
+
+typedef struct _weakRefTable {
+  weakRefObject*               hash[REFOBJHASHSZ];
+} weakRefTable;
 
-static refTable                        refObjects;
+static strongRefTable                  strongRefObjects;
+static weakRefTable                     weakRefObjects;
 
 /* This is a bit homemade.  We need a 7-bit hash from the address here */
 #define        REFOBJHASH(V)   ((((uintp)(V) >> 2) ^ ((uintp)(V) >> 
9))%REFOBJHASHSZ)
@@ -50,10 +62,10 @@
 KaffeGC_addRef(Collector *collector, const void* mem)
 {
   uint32 idx;
-  refObject* obj;
+  strongRefObject* obj;
 
   idx = REFOBJHASH(mem);
-  for (obj = refObjects.hash[idx]; obj != 0; obj = obj->next) {
+  for (obj = strongRefObjects.hash[idx]; obj != 0; obj = obj->next) {
     /* Found it - just increase reference */
     if (obj->mem == mem) {
       obj->ref++;
@@ -62,14 +74,14 @@
   }
 
   /* Not found - create a new one */
-  obj = (refObject*)KGC_malloc(collector, sizeof(refObject), KGC_ALLOC_REF);
+  obj = (strongRefObject*)KGC_malloc(collector, sizeof(strongRefObject), 
KGC_ALLOC_REF);
   if (!obj)
     return false;
        
   obj->mem = mem;
   obj->ref = 1;
-  obj->next = refObjects.hash[idx];
-  refObjects.hash[idx] = obj;
+  obj->next = strongRefObjects.hash[idx];
+  strongRefObjects.hash[idx] = obj;
   return true;
 }
 
@@ -81,11 +93,11 @@
 KaffeGC_rmRef(Collector *collector, void* mem)
 {
   uint32 idx;
-  refObject** objp;
-  refObject* obj;
+  strongRefObject** objp;
+  strongRefObject* obj;
 
   idx = REFOBJHASH(mem);
-  for (objp = &refObjects.hash[idx]; *objp != 0; objp = &obj->next) {
+  for (objp = &strongRefObjects.hash[idx]; *objp != 0; objp = &obj->next) {
     obj = *objp;
     /* Found it - just decrease reference */
     if (obj->mem == mem) {
@@ -102,7 +114,87 @@
   return false;
 }
 
-/*      
+bool
+KaffeGC_addWeakRef(Collector *collector, void* mem, void** refobj)
+{
+  int idx;
+  weakRefObject* obj;
+
+  idx = REFOBJHASH(mem);
+  for (obj = weakRefObjects.hash[idx]; obj != 0; obj = obj->next) {
+    /* Found it - just register a new weak reference */
+    if (obj->mem == mem) {
+      void ***newRefs;
+      obj->ref++;
+
+      newRefs = (void ***)KGC_malloc(collector, sizeof(void ***)*obj->ref, 
KGC_ALLOC_REF);
+      memcpy(newRefs, obj->allRefs, sizeof(void ***)*(obj->ref-1));
+      KGC_free(collector, obj->allRefs);
+
+      obj->allRefs = newRefs;
+      obj->allRefs[obj->ref-1] = refobj;
+      return true;
+    }
+  }
+
+  /* Not found - create a new one */
+  obj = (weakRefObject*)KGC_malloc(collector, sizeof(weakRefObject), 
KGC_ALLOC_REF);
+  if (!obj)
+    return false;
+
+  obj->mem = mem;
+  obj->ref = 1;
+  obj->allRefs = (void ***)KGC_malloc(collector, sizeof(void ***), 
KGC_ALLOC_REF);
+  obj->allRefs[0] = refobj;
+  obj->next = weakRefObjects.hash[idx];
+  weakRefObjects.hash[idx] = obj;
+  return true;
+}
+
+bool
+KaffeGC_rmWeakRef(Collector *collector, void* mem, void** refobj)
+{
+  uint32 idx;
+  weakRefObject** objp;
+  weakRefObject* obj;
+  unsigned int i;
+
+  idx = REFOBJHASH(mem);
+  for (objp = &weakRefObjects.hash[idx]; *objp != 0; objp = &obj->next) {
+    obj = *objp;
+    /* Found it - just decrease reference */
+    if (obj->mem == mem)
+      {
+       for (i = 0; i < obj->ref; i++)
+         {
+           if (obj->allRefs[i] == refobj)
+             {
+               void ***newRefs;
+               
+               obj->ref--;
+               newRefs = (void ***)KGC_malloc(collector, sizeof(void 
***)*obj->ref, KGC_ALLOC_REF);
+               memcpy(newRefs, obj->allRefs, i*sizeof(void ***));
+               memcpy(&newRefs[i], &obj->allRefs[i+1], obj->ref*sizeof(void 
***));
+               KGC_free(collector, obj->allRefs);
+               obj->allRefs = newRefs;
+               break;
+             }
+         }
+       if (i == obj->ref)
+         return false;
+       if (obj->ref == 0) {
+         *objp = obj->next;
+         KGC_free(collector, obj);
+       }
+       return true;
+      }
+  }
+
+  /* Not found!! */
+  return false;
+}
+
+/*
  * Walk the thread's internal context.
  * This is invoked by the garbage collector thread, which is not
  * stopped.
@@ -183,7 +275,7 @@
 KaffeGC_walkRefs(Collector* collector)
 {
   int i;
-  refObject* robj;
+  strongRefObject* robj;
   
 DBG(GCWALK,
     dprintf("Walking gc roots...\n");
@@ -191,7 +283,7 @@
 
   /* Walk the referenced objects */
   for (i = 0; i < REFOBJHASHSZ; i++) {
-    for (robj = refObjects.hash[i]; robj != 0; robj = robj->next) {
+    for (robj = strongRefObjects.hash[i]; robj != 0; robj = robj->next) {
       KGC_markObject(collector, NULL, robj->mem);
     }
   }
@@ -209,4 +301,38 @@
  DBG(GCWALK,
      dprintf("Following references now...\n");
      );
+}
+
+
+/**
+ * This function clear all weak references to the specified object. 
+ * The references are then removed from the database.
+ *
+ * @param collector a garbage collector instance.
+ * @param mem a valid memory object.
+ */
+void
+KaffeGC_clearWeakRef(Collector *collector, void* mem)
+{ 
+  uint32 idx;
+  weakRefObject** objp;
+  weakRefObject* obj;
+  unsigned int i;
+
+  idx = REFOBJHASH(mem);
+  for (objp = &weakRefObjects.hash[idx]; *objp != 0; objp = &obj->next)
+    {
+      obj = *objp;
+      /* Found it - clear all references attached to it. */
+      if (obj->mem == mem)
+       {
+         for (i = 0; i < obj->ref; i++)
+           *(obj->allRefs[i]) = NULL;
+         KGC_free(collector, obj->allRefs);
+
+         *objp = obj->next;
+         KGC_free(collector, obj);
+         return;
+       }
+    }
 }
Index: kaffe-gc/gc-refs.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/kaffe-gc/gc-refs.h,v
retrieving revision 1.4
diff -u -r1.4 gc-refs.h
--- kaffe-gc/gc-refs.h  20 Nov 2004 18:15:13 -0000      1.4
+++ kaffe-gc/gc-refs.h  23 Dec 2004 18:02:55 -0000
@@ -22,5 +22,8 @@
 bool KaffeGC_addRef(struct _Collector *collector, const void* mem);
 bool KaffeGC_rmRef(struct _Collector *collector, void* mem);
 void KaffeGC_walkRefs(struct _Collector* collector);
+bool KaffeGC_addWeakRef(struct _Collector *collector, void *mem, void **obj);
+bool KaffeGC_rmWeakRef(struct _Collector *collector, void *mem, void **obj);
+void KaffeGC_clearWeakRef(struct _Collector *collector, void *mem);
 
 #endif /* __gcrefs_h */
_______________________________________________
kaffe mailing list
[email protected]
http://kaffe.org/cgi-bin/mailman/listinfo/kaffe

Reply via email to