[kaffe] CVS kaffe (guilhem): A few fixes. Implemented weak references. Changed class destruction handling.
Kaffe CVS
cvs-commits at kaffe.org
Sat Dec 25 11:14:13 PST 2004
PatchSet 5723
Date: 2004/12/25 19:09:03
Author: guilhem
Branch: HEAD
Tag: (none)
Log:
A few fixes. Implemented weak references. Changed class destruction handling.
* 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. Store the parent class of the table in the first entry.
(computeInterfaceImplementationIndex): Store a pointer to the
itable2dtable instead of an index.
* kaffe/kaffevm/soft.c
(soft_lookupinterfacemethod): Use directly the pointer in
implementors.
(instanceof_interface): Use implementors to directly check the
inheritancy.
* 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.
* kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
(jthread_unsuspend_all): Removed mutex protection.
(jthread_walkLiveThreads_r, jthread_walkLiveThreads): Splitted in
a reentrant function and a non-reentrant one. (See
jthread_unsuspend_all)
* include/Makefile.in, configure: Regenerated.
Members:
ChangeLog:1.3268->1.3269
configure:1.406->1.407
configure.ac:1.97->1.98
config/mips/irix5/md.h:1.6->1.7
include/Makefile.am:1.80->1.81
include/Makefile.in:1.200->1.201
kaffe/kaffevm/baseClasses.c:1.56->1.57
kaffe/kaffevm/classMethod.c:1.130->1.131
kaffe/kaffevm/classMethod.h:1.73->1.74
kaffe/kaffevm/gc.h:1.30->1.31
kaffe/kaffevm/gcFuncs.c:1.62->1.63
kaffe/kaffevm/soft.c:1.73->1.74
kaffe/kaffevm/thread.c:1.88->1.89
kaffe/kaffevm/boehm-gc/gc-refs.c:1.3->1.4
kaffe/kaffevm/boehm-gc/gc-refs.h:1.1->1.2
kaffe/kaffevm/boehm-gc/gc2.c:1.7->1.8
kaffe/kaffevm/intrp/methodcalls.c:1.3->1.4
kaffe/kaffevm/jit/methodcalls.c:1.5->1.6
kaffe/kaffevm/jit/methodcalls.h:1.2->1.3
kaffe/kaffevm/jit3/machine.c:1.67->1.68
kaffe/kaffevm/jni/jni-callmethod.c:1.4->1.5
kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.16->1.17
kaffe/kaffevm/kaffe-gc/gc-refs.c:1.8->1.9
kaffe/kaffevm/kaffe-gc/gc-refs.h:1.4->1.5
kaffe/kaffevm/systems/unix-jthreads/jthread.c:1.127->1.128
kaffe/kaffevm/systems/unix-jthreads/jthread.h:1.65->1.66
kaffe/kaffevm/systems/unix-pthreads/thread-impl.c:1.62->1.63
kaffe/kaffevm/systems/unix-pthreads/thread-internal.h:1.27->1.28
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3268 kaffe/ChangeLog:1.3269
--- kaffe/ChangeLog:1.3268 Fri Dec 24 21:04:28 2004
+++ kaffe/ChangeLog Sat Dec 25 19:09:03 2004
@@ -1,3 +1,67 @@
+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. Store the parent class of the table in the first entry.
+ (computeInterfaceImplementationIndex): Store a pointer to the
+ itable2dtable instead of an index.
+
+ * kaffe/kaffevm/soft.c
+ (soft_lookupinterfacemethod): Use directly the pointer in
+ implementors.
+ (instanceof_interface): Use implementors to directly check the
+ inheritancy.
+
+ * 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.
+
+ * kaffe/kaffevm/systems/unix-pthreads/thread-impl.c
+ (jthread_unsuspend_all): Removed mutex protection.
+ (jthread_walkLiveThreads_r, jthread_walkLiveThreads): Splitted in
+ a reentrant function and a non-reentrant one. (See
+ jthread_unsuspend_all)
+
+ * include/Makefile.in, configure: Regenerated.
+
2004-12-24 Adam Heath <doogie at brainfood.com>
* libraries/javalib/java/util/zip/ZipFile.java:
Index: kaffe/configure
diff -u kaffe/configure:1.406 kaffe/configure:1.407
--- kaffe/configure:1.406 Wed Dec 22 20:01:58 2004
+++ kaffe/configure Sat Dec 25 19:09:03 2004
@@ -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: kaffe/configure.ac
diff -u kaffe/configure.ac:1.97 kaffe/configure.ac:1.98
--- kaffe/configure.ac:1.97 Wed Dec 22 20:02:03 2004
+++ kaffe/configure.ac Sat Dec 25 19:09:10 2004
@@ -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: kaffe/config/mips/irix5/md.h
diff -u kaffe/config/mips/irix5/md.h:1.6 kaffe/config/mips/irix5/md.h:1.7
--- kaffe/config/mips/irix5/md.h:1.6 Tue Jul 13 13:52:00 2004
+++ kaffe/config/mips/irix5/md.h Sat Dec 25 19:09:12 2004
@@ -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: kaffe/include/Makefile.am
diff -u kaffe/include/Makefile.am:1.80 kaffe/include/Makefile.am:1.81
--- kaffe/include/Makefile.am:1.80 Tue Dec 21 16:51:11 2004
+++ kaffe/include/Makefile.am Sat Dec 25 19:09:12 2004
@@ -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: kaffe/include/Makefile.in
diff -u kaffe/include/Makefile.in:1.200 kaffe/include/Makefile.in:1.201
--- kaffe/include/Makefile.in:1.200 Wed Dec 22 19:04:48 2004
+++ kaffe/include/Makefile.in Sat Dec 25 19:09:12 2004
@@ -410,11 +410,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 \
@@ -467,6 +465,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/kaffe/kaffevm/baseClasses.c
diff -u kaffe/kaffe/kaffevm/baseClasses.c:1.56 kaffe/kaffe/kaffevm/baseClasses.c:1.57
--- kaffe/kaffe/kaffevm/baseClasses.c:1.56 Sun Dec 19 06:25:07 2004
+++ kaffe/kaffe/kaffevm/baseClasses.c Sat Dec 25 19:09:13 2004
@@ -261,6 +261,8 @@
{
errorInfo einfo;
+ memset(&dummyClassClass, 0, sizeof(dummyClassClass));
+
/* Primitive types */
initTypes();
initVerifierPrimTypes();
Index: kaffe/kaffe/kaffevm/classMethod.c
diff -u kaffe/kaffe/kaffevm/classMethod.c:1.130 kaffe/kaffe/kaffevm/classMethod.c:1.131
--- kaffe/kaffe/kaffevm/classMethod.c:1.130 Tue Dec 21 08:06:36 2004
+++ kaffe/kaffe/kaffevm/classMethod.c Sat Dec 25 19:09:13 2004
@@ -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] + 1) * 2;
if (len <= i) {
- len = i + 4;
+ len = (i + 1) + 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: kaffe/kaffe/kaffevm/classMethod.h
diff -u kaffe/kaffe/kaffevm/classMethod.h:1.73 kaffe/kaffe/kaffevm/classMethod.h:1.74
--- kaffe/kaffe/kaffevm/classMethod.h:1.73 Tue Dec 21 16:51:05 2004
+++ kaffe/kaffe/kaffevm/classMethod.h Sat Dec 25 19:09:13 2004
@@ -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: kaffe/kaffe/kaffevm/gc.h
diff -u kaffe/kaffe/kaffevm/gc.h:1.30 kaffe/kaffe/kaffevm/gc.h:1.31
--- kaffe/kaffe/kaffevm/gc.h:1.30 Tue Dec 21 08:06:36 2004
+++ kaffe/kaffe/kaffevm/gc.h Sat Dec 25 19:09:13 2004
@@ -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/kaffe/kaffevm/gcFuncs.c
diff -u kaffe/kaffe/kaffevm/gcFuncs.c:1.62 kaffe/kaffe/kaffevm/gcFuncs.c:1.63
--- kaffe/kaffe/kaffevm/gcFuncs.c:1.62 Tue Dec 21 16:51:05 2004
+++ kaffe/kaffe/kaffevm/gcFuncs.c Sat Dec 25 19:09:13 2004
@@ -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: kaffe/kaffe/kaffevm/soft.c
diff -u kaffe/kaffe/kaffevm/soft.c:1.73 kaffe/kaffe/kaffevm/soft.c:1.74
--- kaffe/kaffe/kaffevm/soft.c:1.73 Tue Dec 21 05:49:59 2004
+++ kaffe/kaffe/kaffevm/soft.c Sat Dec 25 19:09:13 2004
@@ -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,39 @@
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 (oc->state < CSTATE_USABLE || c->state < CSTATE_USABLE || 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 || c->implementors == NULL ||
+ 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: kaffe/kaffe/kaffevm/thread.c
diff -u kaffe/kaffe/kaffevm/thread.c:1.88 kaffe/kaffe/kaffevm/thread.c:1.89
--- kaffe/kaffe/kaffevm/thread.c:1.88 Tue Dec 21 16:51:05 2004
+++ kaffe/kaffe/kaffevm/thread.c Sat Dec 25 19:09:13 2004
@@ -610,7 +610,7 @@
dumpThreads(void)
{
dprintf("Dumping live threads:\n");
- KTHREAD(walkLiveThreads)(dumpJavaThread, NULL);
+ KTHREAD(walkLiveThreads_r)(dumpJavaThread, NULL);
}
/*
Index: kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c
diff -u kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c:1.3 kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c:1.4
--- kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c:1.3 Mon Aug 9 08:18:21 2004
+++ kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c Sat Dec 25 19:09:14 2004
@@ -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;
*** Patch too long, truncated ***
More information about the kaffe
mailing list