[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