? 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 + + * 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 * 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 */