[kaffe] Weak references/Class destruction
Guilhem Lavaux
guilhem at kaffe.org
Wed Dec 22 09:05:31 PST 2004
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.
There are some drawbacks:
* creating a weak reference is slow and consumes memory.
* walking a class takes more time as you have to decide whether to mark
or not some memory.
Advantages:
* boehm-gc should work now (even if some bugs might still lurk around
the structure is in place).
* Relieve the VM from caring about some pointers shared between several
classes (like interface implementors).
* The patch does not touch the class structure.
It seems that I've still a failure from time to time in ClassGC when
using the boehm-gc. We will have check this.
Here is the patch. If nobody rejects it I'll check it in tomorrow.
Regards,
Guilhem Lavaux.
-------------- next part --------------
? build_boehm
? build_intrp
? build_pth
? mem_patch
? pat
? weak-ref-patch
? config/powerpc/darwin/md.h.new
? kaffe/kaffe/main.ch
? libraries/javalib/Klasses.jar.bootstrap.save
? libraries/javalib/l
? po/fr.gmo
? po/zh_TW.gmo
Index: ChangeLog
===================================================================
RCS file: /cvs/kaffe/kaffe/ChangeLog,v
retrieving revision 1.3252
diff -u -r1.3252 ChangeLog
--- ChangeLog 22 Dec 2004 01:09:35 -0000 1.3252
+++ ChangeLog 22 Dec 2004 17:03:38 -0000
@@ -1,3 +1,53 @@
+2004-12-22 Guilhem Lavaux <guilhem at kaffe.org>
+
+ * configure.ac: Fixed CPPFLAGS generation to be compatible with
+ boehm's configure.
+
+ * config/mips/irix5/md.h: Removed extra macros.
+
+ * include/Makefile.am: Moved ObjectInputStream and
+ VMObjectStreamClass to JNI headers.
+
+ * kaffe/kaffevm/baseClasses.c: Reset dummyClassClass before using
+ it.
+
+ * kaffe/kaffevm/classMethod.c
+ (processClass, resolveInterfaces): Use weak references to track
+ vanishing classes.
+ (processClass): Do not free explicitly the generated code anymore.
+ (buildInterfaceDispatchTable): Remember the total length of the
+ table.
+
+ * kaffe/kaffevm/gc.h: New type for interface table. Two new
+ functions to handle weak references.
+
+ * kaffe/kaffevm/gcFuncs.c
+ (destroyClass): Do not explicitly free memory for the
+ native/bytecode code. Use weak references to track classes which
+ has already been freed.
+ (walkMethods): Mark the bytecode _and_ the native code.
+ (walkClass): Mark the dtable, the interfaces, the vtable.
+ (initCollector): KGC_ALLOC_TRAMPOLINE, KGC_ALLOC_JITCODE,
+ KGC_ALLOC_BYTECODE, KGC_ALLOC_INTERFACE, KGC_ALLOC_INTERFACE_TABLE
+ are now dynamic.
+
+ * kaffe/kaffevm/kaffe-gc/gc-incremental.c
+ (finishGC): Invoke KaffeGC_clearWeakRef.
+
+ * kaffe/kaffevm/kaffe-gc/gc-refs.c
+ (refObject): Renamed to strongRefObject.
+ (refTable): Likewise.
+ (weakRefObject, weakRefTable): New table.
+ (KaffeGC_addWeakRef, KaffeGC_rmWeakRef): New functions.
+ (KaffeGC_clearWeakRef): New function.
+
+ * kaffe/kaffevm/boehm-gc/gc-refs.c: Like kaffe-gc/gc-refs.c
+
+ * kaffe/kaffevm/boehm-gc/gc2.c
+ (finalizeObject): Invoke KaffeGC_clearWeakRef.
+
+ * include/Makefile.in, configure: Regenerated.
+
2004-12-22 Dalibor Topic <robilad at kaffe.org>
* m4/ac_prog_antlr.m4,
Index: configure
===================================================================
RCS file: /cvs/kaffe/kaffe/configure,v
retrieving revision 1.403
diff -u -r1.403 configure
--- configure 22 Dec 2004 01:09:37 -0000 1.403
+++ configure 22 Dec 2004 17:03:56 -0000
@@ -28530,6 +28530,7 @@
esac
VMLIBS="$VM_LIBS $PTHREAD_LIBS"
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT"
else
CPPFLAGS="$CPPFLAGS -DBR_PTHREADS=0"
fi
@@ -42735,13 +42736,8 @@
BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_HPUX_THREADS"
;;
linux*)
- if test x"$ac_cv_c_compile_value_glibc" -le x"2"; then
- if test "$ac_c_compile_value_glibc_minor" -le "2"; then
- BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_LINUX_THREADS"
- fi
- if test "$ac_cv_c_compile_value_glibc_minor" -ge "3"; then
- BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_PTHREADS"
- fi
+ if test "$ac_cv_c_compile_value_glibc" -le "2"; then
+ BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_LINUX_THREADS -DTHREAD_LOCAL_ALLOC"
fi
;;
*)
Index: configure.ac
===================================================================
RCS file: /cvs/kaffe/kaffe/configure.ac,v
retrieving revision 1.96
diff -u -r1.96 configure.ac
--- configure.ac 22 Dec 2004 01:09:45 -0000 1.96
+++ configure.ac 22 Dec 2004 17:03:56 -0000
@@ -679,6 +679,7 @@
KAFFE_LIB_SOLARIS_PTHREAD
VMLIBS="$VM_LIBS $PTHREAD_LIBS"
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT"
else
CPPFLAGS="$CPPFLAGS -DBR_PTHREADS=0"
fi
@@ -1096,12 +1097,10 @@
BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_HPUX_THREADS"
;;
linux*)
- if test x"$ac_cv_c_compile_value_glibc" -le x"2"; then
- if test "$ac_c_compile_value_glibc_minor" -le "2"; then
- BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_LINUX_THREADS"
- fi
- if test "$ac_cv_c_compile_value_glibc_minor" -ge "3"; then
- BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_PTHREADS"
+ if test "$ac_cv_c_compile_value_glibc" -le "2"; then
+ BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DGC_LINUX_THREADS"
+ if test "$Khost_cpu" = "i386"; then
+ BOEHMGC_SPECIFIC_FLAGS="$BOEHMGC_SPECIFIC_FLAGS -DTHREAD_LOCAL_ALLOC"
fi
fi
;;
Index: config/mips/irix5/md.h
===================================================================
RCS file: /cvs/kaffe/kaffe/config/mips/irix5/md.h,v
retrieving revision 1.6
diff -u -r1.6 md.h
--- config/mips/irix5/md.h 13 Jul 2004 13:52:00 -0000 1.6
+++ config/mips/irix5/md.h 22 Dec 2004 17:03:56 -0000
@@ -29,12 +29,6 @@
#define SIGNAL_PC(scp) ((scp)->sc_pc) /* pc at time of signal */
#define STACK_POINTER(scp) ((scp)->sc_badvaddr) /* cp0 bad virtual address */
-#define SIGNAL_ARGS(sig, sc) int sig, int code UNUSED, struct sigcontext *sc
-#define SIGNAL_CONTEXT_POINTER(scp) struct sigcontext *scp
-#define GET_SIGNAL_CONTEXT_POINTER(sc) (sc)
-#define SIGNAL_PC(scp)
-#define STACK_POINTER(scp) ((scp)->sc_badvaddr)
-
#include "kaffe-unix-stack.h"
#endif
Index: include/Makefile.am
===================================================================
RCS file: /cvs/kaffe/kaffe/include/Makefile.am,v
retrieving revision 1.80
diff -u -r1.80 Makefile.am
--- include/Makefile.am 21 Dec 2004 16:51:11 -0000 1.80
+++ include/Makefile.am 22 Dec 2004 17:03:56 -0000
@@ -51,11 +51,9 @@
java_io_FileOutputStream.h \
java_io_InputStream.h \
java_io_InterruptedIOException.h \
- java_io_ObjectInputStream.h \
java_io_PrintStream.h \
java_io_RandomAccessFile.h \
java_io_VMFile.h \
- java_io_VMObjectStreamClass.h \
java_lang_Boolean.h \
java_lang_Byte.h \
java_lang_Character.h \
@@ -110,6 +108,8 @@
gnu_classpath_VMSystemProperties.h \
gnu_java_nio_channels_FileChannelImpl.h \
gnu_java_nio_SelectorImpl.h \
+ java_io_ObjectInputStream.h \
+ java_io_VMObjectStreamClass.h \
java_nio_channels_Channels.h \
java_nio_VMDirectByteBuffer.h \
java_nio_MappedByteBufferImpl.h \
Index: include/Makefile.in
===================================================================
RCS file: /cvs/kaffe/kaffe/include/Makefile.in,v
retrieving revision 1.199
diff -u -r1.199 Makefile.in
--- include/Makefile.in 22 Dec 2004 01:09:46 -0000 1.199
+++ include/Makefile.in 22 Dec 2004 17:03:56 -0000
@@ -407,11 +407,9 @@
java_io_FileOutputStream.h \
java_io_InputStream.h \
java_io_InterruptedIOException.h \
- java_io_ObjectInputStream.h \
java_io_PrintStream.h \
java_io_RandomAccessFile.h \
java_io_VMFile.h \
- java_io_VMObjectStreamClass.h \
java_lang_Boolean.h \
java_lang_Byte.h \
java_lang_Character.h \
@@ -464,6 +462,8 @@
gnu_classpath_VMSystemProperties.h \
gnu_java_nio_channels_FileChannelImpl.h \
gnu_java_nio_SelectorImpl.h \
+ java_io_ObjectInputStream.h \
+ java_io_VMObjectStreamClass.h \
java_nio_channels_Channels.h \
java_nio_VMDirectByteBuffer.h \
java_nio_MappedByteBufferImpl.h \
Index: kaffe/kaffevm/baseClasses.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/baseClasses.c,v
retrieving revision 1.56
diff -u -r1.56 baseClasses.c
--- kaffe/kaffevm/baseClasses.c 19 Dec 2004 06:25:07 -0000 1.56
+++ kaffe/kaffevm/baseClasses.c 22 Dec 2004 17:03:56 -0000
@@ -261,6 +261,8 @@
{
errorInfo einfo;
+ memset(&dummyClassClass, 0, sizeof(dummyClassClass));
+
/* Primitive types */
initTypes();
initVerifierPrimTypes();
Index: kaffe/kaffevm/classMethod.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/classMethod.c,v
retrieving revision 1.130
diff -u -r1.130 classMethod.c
--- kaffe/kaffevm/classMethod.c 21 Dec 2004 08:06:36 -0000 1.130
+++ kaffe/kaffevm/classMethod.c 22 Dec 2004 17:03:57 -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;
@@ -841,24 +842,27 @@
}
for (i = 0; i < class->interface_len; i++) {
newifaces[i] = class->interfaces[i];
+ KGC_addWeakRef(main_collector, newifaces[i], &newifaces[i]);
}
nclass = class->superclass;
if (nclass != 0 && nclass != ObjectClass) {
for (j = 0; j < nclass->total_interface_len; j++, i++) {
newifaces[i] = nclass->interfaces[j];
+ KGC_addWeakRef(main_collector, newifaces[i], &newifaces[i]);
}
}
for (k = 0; k < class->interface_len; k++) {
nclass = class->interfaces[k];
for (j = 0; j < nclass->total_interface_len; j++, i++) {
newifaces[i] = nclass->interfaces[j];
+ KGC_addWeakRef(main_collector, newifaces[i], &newifaces[i]);
}
}
- /* free old list of interfaces */
- if (class->interfaces != 0) {
- KFREE(class->interfaces);
- }
class->interfaces = newifaces;
+ } else {
+ /* Add weak references now. */
+ for (i = 0; i < class->interface_len; i++)
+ KGC_addWeakRef(main_collector, class->interfaces[i], &class->interfaces[i]);
}
/* don't set total_interface_len before interfaces to avoid
@@ -2091,7 +2095,7 @@
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);
@@ -2105,7 +2109,9 @@
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);
Index: kaffe/kaffevm/gc.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/gc.h,v
retrieving revision 1.30
diff -u -r1.30 gc.h
--- kaffe/kaffevm/gc.h 21 Dec 2004 08:06:36 -0000 1.30
+++ kaffe/kaffevm/gc.h 22 Dec 2004 17:03:57 -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: kaffe/kaffevm/gcFuncs.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/gcFuncs.c,v
retrieving revision 1.62
diff -u -r1.62 gcFuncs.c
--- kaffe/kaffevm/gcFuncs.c 21 Dec 2004 16:51:05 -0000 1.62
+++ kaffe/kaffevm/gcFuncs.c 22 Dec 2004 17:04:00 -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,45 @@
}
}
/* free constant pool */
- if (pool->data != 0) {
- KFREE(pool->data);
- }
+ if (pool->data != 0)
+ {
+ 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 )
+ {
+ /* 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
- */
- 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) )
+ KFREE(clazz->if2itable);
+ 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] = -1;
+ }
+ }
+ /* 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).
+ */
}
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 +212,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 +263,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);
+ }
+
+ KGC_markObject(collector, gc_info, class->gc_layout);
+ if (class->itable2dtable != NULL)
+ {
+ KGC_markObject(collector, gc_info, class->itable2dtable);
+
+ for (idx = 0; idx < class->if2itable[class->total_interface_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 +307,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 +391,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 = 0, 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 +653,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 +673,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 +684,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: kaffe/kaffevm/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
--- kaffe/kaffevm/boehm-gc/gc-refs.c 9 Aug 2004 08:18:21 -0000 1.3
+++ kaffe/kaffevm/boehm-gc/gc-refs.c 22 Dec 2004 17:04:00 -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: kaffe/kaffevm/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
--- kaffe/kaffevm/boehm-gc/gc-refs.h 2 Aug 2004 10:44:56 -0000 1.1
+++ kaffe/kaffevm/boehm-gc/gc-refs.h 22 Dec 2004 17:04:00 -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: kaffe/kaffevm/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
--- kaffe/kaffevm/boehm-gc/gc2.c 16 Dec 2004 06:13:52 -0000 1.7
+++ kaffe/kaffevm/boehm-gc/gc2.c 22 Dec 2004 17:04:00 -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,6 +548,17 @@
}
}
+static
+bool
+KaffeGC_addWeakRef(Collector *collector UNUSED, void* mem UNUSED, void **ref UNUSED)
+{
+}
+
+static
+bool
+KaffeGC_rmWeakRef(Collector *collector UNUSED, void* mem UNUSED, void **ref UNUSED)
+{
+}
/*
* vtable for object implementing the collector interface.
@@ -574,7 +589,9 @@
KaffeGC_HeapLimit,
KaffeGC_HeapTotal,
KaffeGC_addRef,
- KaffeGC_rmRef
+ KaffeGC_rmRef,
+ KaffeGC_addWeakRef,
+ KaffeGC_rmWeakRef
};
/*
Index: kaffe/kaffevm/intrp/methodcalls.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/intrp/methodcalls.c,v
retrieving revision 1.3
diff -u -r1.3 methodcalls.c
--- kaffe/kaffevm/intrp/methodcalls.c 21 Oct 2004 14:20:34 -0000 1.3
+++ kaffe/kaffevm/intrp/methodcalls.c 22 Dec 2004 17:04:00 -0000
@@ -139,3 +139,4 @@
}
}
+
Index: kaffe/kaffevm/jit/methodcalls.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jit/methodcalls.c,v
retrieving revision 1.5
diff -u -r1.5 methodcalls.c
--- kaffe/kaffevm/jit/methodcalls.c 21 Dec 2004 05:50:00 -0000 1.5
+++ kaffe/kaffevm/jit/methodcalls.c 22 Dec 2004 17:04:00 -0000
@@ -63,7 +63,8 @@
*/
#if defined(COMPARE_AND_EXCHANGE)
if (COMPARE_AND_EXCHANGE(where, tramp, METHOD_NATIVECODE(meth))) {
- gc_free(tramp);
+ // gc_rm_ref(tramp);
+ // gc_free(tramp);
}
#elif defined(ATOMIC_EXCHANGE)
{
@@ -72,7 +73,8 @@
ATOMIC_EXCHANGE(where, tmp);
if (tmp == tramp) {
- gc_free(tramp);
+ // gc_rm_ref(tramp);
+ // gc_free(tramp);
}
}
#else
@@ -182,6 +184,7 @@
!!!"Cannot override trampoline anchor");
}
ret = tramp;
+ // gc_add_ref(tramp);
} else {
if (CLASS_GCJ((meth)->class)) {
_SET_METHOD_NATIVECODE(meth, meth->ncode);
Index: kaffe/kaffevm/jit/methodcalls.h
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jit/methodcalls.h,v
retrieving revision 1.2
diff -u -r1.2 methodcalls.h
--- kaffe/kaffevm/jit/methodcalls.h 21 Aug 2004 14:53:32 -0000 1.2
+++ kaffe/kaffevm/jit/methodcalls.h 22 Dec 2004 17:04:00 -0000
@@ -42,5 +42,4 @@
*/
#define engine_reservedArgs(M) 0
-
#endif /* __method_dispatch_h__ */
Index: kaffe/kaffevm/jit3/machine.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jit3/machine.c,v
retrieving revision 1.67
diff -u -r1.67 machine.c
--- kaffe/kaffevm/jit3/machine.c 22 Dec 2004 00:22:05 -0000 1.67
+++ kaffe/kaffevm/jit3/machine.c 22 Dec 2004 17:04:00 -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: kaffe/kaffevm/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/kaffevm/kaffe-gc/gc-incremental.c 20 Dec 2004 01:39:21 -0000 1.16
+++ kaffe/kaffevm/kaffe-gc/gc-incremental.c 22 Dec 2004 17:04:01 -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/kaffevm/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/kaffevm/kaffe-gc/gc-refs.c 21 Dec 2004 11:46:54 -0000 1.8
+++ kaffe/kaffevm/kaffe-gc/gc-refs.c 22 Dec 2004 17:04:01 -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/kaffevm/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/kaffevm/kaffe-gc/gc-refs.h 20 Nov 2004 18:15:13 -0000 1.4
+++ kaffe/kaffevm/kaffe-gc/gc-refs.h 22 Dec 2004 17:04:01 -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 */
More information about the kaffe
mailing list