This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
PATCH: minimalize root set for GC
- From: Jeff Sturm <jsturm at one-point dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Wed, 26 Jun 2002 19:34:48 -0400 (EDT)
- Subject: PATCH: minimalize root set for GC
As described on the main list, I'm posting my experimental patch for
comment. Tested on i686-linux with mainline.
Jeff
2002-06-26 Jeff Sturm <jsturm@one-point.com>
* boehm.cc (_Jv_MarkObj): Mark unresolved static fields.
(_Jv_InitGC): Clear static roots, register libgcj roots.
(_Jv_GCAddRoots, _Jv_GCAddClass, _Jv_PushOtherRoots): New.
* jni.cc (natrehash): Allocate/free storage with
_Jv_Malloc/_Jv_Free.
(_Jv_AddJNIRoots): New.
* prims.cc (_Jv_makeUtf8Const): Allocate storage with
_Jv_Malloc.
(arg_vec, main_thread): Move to _Jv_RunMain.
(_Jv_AddPrimRoots): New.
* gnu/gcj/runtime/SharedLibLoader.java (curLoader): Move from...
* gnu/gcj/runtime/natSharedLibLoader.cc (curLoader): ...here.
(SharedLibDummy, register_hook, init): Access curLoader as
a class variable.
* include/jvm.h (_Jv_GCAddRoots, _Jv_GCAddClass): Declare.
(_Jv_AddPrimRoots, _Jv_AddJNIRoots, _Jv_AddObjectRoots): Declare.
* java/lang/natClass.cc (initializeClass): Register class for GC.
* java/lang/natObject.cc (_Jv_AddObjectRoots): New.
* java/lang/natString.cc (rehash): Allocate/free storage with
_Jv_Malloc/_Jv_Free.
Index: boehm.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/boehm.cc,v
retrieving revision 1.33
diff -u -p -r1.33 boehm.cc
--- boehm.cc 12 Feb 2002 04:14:52 -0000 1.33
+++ boehm.cc 26 Jun 2002 21:10:56 -0000
@@ -52,6 +52,8 @@ static ptr_t *array_free_list;
// Lock used to protect access to Boehm's GC_enable/GC_disable functions.
static _Jv_Mutex_t disable_gc_mutex;
+static void _Jv_PushOtherRoots (void);
+static void (*old_push_other_roots)();
// This is called by the GC during the mark phase. It marks a Java
@@ -188,7 +190,9 @@ _Jv_MarkObj (void *addr, void *msp, void
// mark also the value pointed to. We check for isResolved
// since marking can happen before memory is allocated for
// static members.
- if (JvFieldIsRef (field) && field->isResolved())
+ // For compiled classes, it seems a field can be allocated
+ // before it is resolved, so ignore isResolved() for now.
+ if (JvFieldIsRef (field) && p)
{
jobject val = *(jobject*) field->u.addr;
p = (ptr_t) val;
@@ -488,6 +492,18 @@ _Jv_InitGC (void)
GC_obj_kinds[array_kind_x].ok_relocate_descr = FALSE;
GC_obj_kinds[array_kind_x].ok_init = TRUE;
+ GC_no_dls = 1;
+ GC_clear_roots();
+ _Jv_AddPrimRoots ();
+ _Jv_AddJNIRoots ();
+ _Jv_AddObjectRoots ();
+ // XXX Do we need to scan this, or does the gc take care of it?
+ _Jv_GCAddRoots (&array_free_list, sizeof (ptr_t **), 1);
+
+ // Chain _Jv_PushOtherRoots to previous handler.
+ old_push_other_roots = GC_push_other_roots;
+ GC_push_other_roots = _Jv_PushOtherRoots;
+
_Jv_MutexInit (&disable_gc_mutex);
}
@@ -549,4 +565,40 @@ _Jv_GCCanReclaimSoftReference (jobject)
{
// For now, always reclaim soft references. FIXME.
return true;
+}
+
+// Add a root segment for the GC to scan.
+void
+_Jv_GCAddRoots (void *ptr, size_t size, int count)
+{
+ GC_add_roots((char *) ptr, ((char *) ptr) + size * count);
+}
+
+// FIXME This needs to dynamically grow.
+jclass initialized_classes[1024];
+int count_initialized_classes;
+
+// Add a class to the root list. These are pushed with a procedure
+// with a procedure descriptor rather than the ordinary length desciptor.
+void
+_Jv_GCAddClass (jclass cl)
+{
+ if (count_initialized_classes < 1024)
+ initialized_classes[count_initialized_classes++] = cl;
+ else
+ abort ();
+}
+
+static void
+_Jv_PushOtherRoots (void)
+{
+ if (old_push_other_roots)
+ (*old_push_other_roots) ();
+ for (int n = 0; n < count_initialized_classes; n++)
+ {
+ if (++GC_mark_stack_top >= GC_mark_stack_limit)
+ abort ();
+ GC_mark_stack_top->mse_start = (word *) initialized_classes[n];
+ GC_mark_stack_top->mse_descr = GC_MAKE_PROC (0, 1);
+ }
}
Index: jni.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni.cc,v
retrieving revision 1.60.2.1
diff -u -p -r1.60.2.1 jni.cc
--- jni.cc 5 Mar 2002 22:40:01 -0000 1.60.2.1
+++ jni.cc 26 Jun 2002 21:10:56 -0000
@@ -1746,7 +1746,7 @@ natrehash ()
{
nathash_size = 1024;
nathash =
- (JNINativeMethod *) _Jv_AllocBytes (nathash_size
+ (JNINativeMethod *) _Jv_Malloc (nathash_size
* sizeof (JNINativeMethod));
memset (nathash, 0, nathash_size * sizeof (JNINativeMethod));
}
@@ -1756,7 +1756,7 @@ natrehash ()
JNINativeMethod *savehash = nathash;
nathash_size *= 2;
nathash =
- (JNINativeMethod *) _Jv_AllocBytes (nathash_size
+ (JNINativeMethod *) _Jv_Malloc (nathash_size
* sizeof (JNINativeMethod));
memset (nathash, 0, nathash_size * sizeof (JNINativeMethod));
@@ -1768,6 +1768,7 @@ natrehash ()
*slot = savehash[i];
}
}
+ _Jv_Free (savehash);
}
}
@@ -2364,6 +2365,13 @@ _Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm
{
*vm = _Jv_GetJavaVM ();
return *vm == NULL ? JNI_ERR : JNI_OK;
+}
+
+void
+_Jv_AddJNIRoots (void)
+{
+ _Jv_GCAddRoots (&local_ref_table, sizeof (jobject *), 1);
+ _Jv_GCAddRoots (&global_ref_table, sizeof (jobject *), 1);
}
Index: prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.71.2.1
diff -u -p -r1.71.2.1 prims.cc
--- prims.cc 10 Mar 2002 03:30:48 -0000 1.71.2.1
+++ prims.cc 26 Jun 2002 21:10:59 -0000
@@ -248,7 +248,7 @@ _Jv_makeUtf8Const (char* s, int len)
{
if (len < 0)
len = strlen (s);
- Utf8Const* m = (Utf8Const*) _Jv_AllocBytes (sizeof(Utf8Const) + len + 1);
+ Utf8Const* m = (Utf8Const*) _Jv_Malloc (sizeof(Utf8Const) + len + 1);
memcpy (m->data, s, len);
m->data[len] = 0;
m->length = len;
@@ -263,7 +263,7 @@ _Jv_makeUtf8Const (jstring string)
jint len = _Jv_GetStringUTFLength (string);
Utf8Const* m = (Utf8Const*)
- _Jv_AllocBytes (sizeof(Utf8Const) + len + 1);
+ _Jv_Malloc (sizeof(Utf8Const) + len + 1);
m->hash = hash;
m->length = len;
@@ -607,6 +607,7 @@ _Jv_InitPrimClass (jclass cl, char *cnam
{
using namespace java::lang::reflect;
+ _Jv_GCAddClass (cl);
_Jv_InitNewClassFields (cl);
// We must set the vtable for the class; the Java constructor
@@ -696,16 +697,6 @@ JvConvertArgv (int argc, const char **ar
return (JArray<jstring>*) ar;
}
-// FIXME: These variables are static so that they will be
-// automatically scanned by the Boehm collector. This is needed
-// because with qthreads the collector won't scan the initial stack --
-// it will only scan the qthreads stacks.
-
-// Command line arguments.
-static JArray<jstring> *arg_vec;
-
-// The primary thread.
-static java::lang::Thread *main_thread;
char *
_Jv_ThisExecutable (void)
@@ -959,7 +950,8 @@ _Jv_RunMain (jclass klass, const char *n
_Jv_argc = argc;
java::lang::Runtime *runtime = NULL;
-
+ JArray<jstring> *arg_vec;
+ java::lang::Thread *main_thread = NULL;
#ifdef DISABLE_MAIN_ARGS
_Jv_ThisExecutable ("[Embedded App]");
@@ -1144,4 +1136,14 @@ _Jv_remJ (jlong dividend, jlong divisor)
return 0;
return dividend % divisor;
+}
+
+void
+_Jv_AddPrimRoots (void)
+{
+ _Jv_GCAddRoots (&no_memory, sizeof (jobject *), 1);
+#ifdef HANDLE_SEGV
+ _Jv_GCAddRoots (&nullp, sizeof (jobject *), 1);
+#endif
+ _Jv_GCAddRoots (&arithexception, sizeof (jobject *), 1);
}
Index: gnu/gcj/runtime/SharedLibLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/SharedLibLoader.java,v
retrieving revision 1.1
diff -u -p -r1.1 SharedLibLoader.java
--- gnu/gcj/runtime/SharedLibLoader.java 29 Sep 2001 19:16:26 -0000 1.1
+++ gnu/gcj/runtime/SharedLibLoader.java 26 Jun 2002 21:11:00 -0000
@@ -72,4 +72,7 @@ public class SharedLibLoader extends Cla
/** Map classnames to Classes. */
Hashtable classMap = new Hashtable(20);
+
+ // Only used during dlopen, while having a lock on Class.class.
+ protected static SharedLibLoader curLoader;
}
Index: gnu/gcj/runtime/natSharedLibLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/natSharedLibLoader.cc,v
retrieving revision 1.2
diff -u -p -r1.2 natSharedLibLoader.cc
--- gnu/gcj/runtime/natSharedLibLoader.cc 24 Oct 2001 07:00:19 -0000 1.2
+++ gnu/gcj/runtime/natSharedLibLoader.cc 26 Jun 2002 21:11:00 -0000
@@ -18,15 +18,13 @@ details. */
#ifdef HAVE_DLOPEN
#include <dlfcn.h>
-/* Only used during dlopen, while having a lock on Class.class. */
-static gnu::gcj::runtime::SharedLibLoader* curLoader;
-
typedef void (*ClassHookFunc) (jclass);
static void
::register_hook(jclass cls)
{
- curLoader->registerClass(cls->getName(), cls);
+ gnu::gcj::runtime::SharedLibLoader::curLoader->registerClass
+ (cls->getName(), cls);
}
struct SharedLibDummy
@@ -39,7 +37,7 @@ struct SharedLibDummy
~SharedLibDummy()
{
_Jv_RegisterClassHook = saved;
- curLoader = NULL;
+ gnu::gcj::runtime::SharedLibLoader::curLoader = NULL;
}
};
#endif
@@ -53,7 +51,7 @@ gnu::gcj::runtime::SharedLibLoader::init
flags = RTLD_LAZY;
JvSynchronize dummy1(&java::lang::Class::class$);
SharedLibDummy dummy2;
- curLoader = this;
+ gnu::gcj::runtime::SharedLibLoader::curLoader = this;
_Jv_RegisterClassHook = ::register_hook;
void *h = dlopen(lname, flags);
if (h == NULL)
Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.50.8.1
diff -u -p -r1.50.8.1 jvm.h
--- include/jvm.h 11 Apr 2002 15:56:34 -0000 1.50.8.1
+++ include/jvm.h 26 Jun 2002 21:11:00 -0000
@@ -178,6 +178,9 @@ void _Jv_InitGC (void);
void _Jv_RegisterFinalizer (void *object, _Jv_FinalizerFunc *method);
/* Compute the GC descriptor for a class */
void * _Jv_BuildGCDescr(jclass);
+/* Explicitly register static roots. */
+void _Jv_GCAddRoots (void *ptr, size_t size, int count);
+void _Jv_GCAddClass (jclass cl);
/* Allocate some unscanned, unmoveable memory. Return NULL if out of
memory. */
@@ -371,5 +374,9 @@ extern void (*_Jv_JVMPI_Notify_OBJECT_AL
extern void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
extern void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event);
#endif
+
+extern void _Jv_AddPrimRoots (void);
+extern void _Jv_AddJNIRoots (void);
+extern void _Jv_AddObjectRoots (void);
#endif /* __JAVA_JVM_H__ */
Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.50
diff -u -p -r1.50 natClass.cc
--- java/lang/natClass.cc 21 Dec 2001 19:47:50 -0000 1.50
+++ java/lang/natClass.cc 26 Jun 2002 21:11:00 -0000
@@ -717,6 +717,7 @@ java::lang::Class::initializeClass (void
else
#endif
{
+ _Jv_GCAddClass (this);
_Jv_PrepareCompiledClass (this);
}
}
Index: java/lang/natObject.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natObject.cc,v
retrieving revision 1.21.2.1
diff -u -p -r1.21.2.1 natObject.cc
--- java/lang/natObject.cc 10 Mar 2002 03:30:52 -0000 1.21.2.1
+++ java/lang/natObject.cc 26 Jun 2002 21:11:01 -0000
@@ -1251,5 +1251,12 @@ _Jv_InitializeSyncMutex (void)
{
}
+// Register light_locks as a GC root.
+void
+_Jv_AddObjectRoots (void)
+{
+ _Jv_GCAddRoots(light_locks, sizeof (hash_entry), JV_SYNC_TABLE_SZ);
+}
+
#endif /* JV_HASH_SYNCHRONIZATION */
Index: java/lang/natString.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natString.cc,v
retrieving revision 1.25
diff -u -p -r1.25 natString.cc
--- java/lang/natString.cc 15 Nov 2001 02:22:52 -0000 1.25
+++ java/lang/natString.cc 26 Jun 2002 21:11:01 -0000
@@ -121,15 +121,16 @@ java::lang::String::rehash()
if (strhash == NULL)
{
strhash_size = 1024;
- strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
+ strhash = (jstring *) _Jv_Malloc (strhash_size * sizeof (jstring));
memset (strhash, 0, strhash_size * sizeof (jstring));
}
else
{
+ jstring *old = strhash;
int i = strhash_size;
jstring* ptr = strhash + i;
int nsize = strhash_size * 2;
- jstring *next = (jstring *) _Jv_AllocBytes (nsize * sizeof (jstring));
+ jstring *next = (jstring *) _Jv_Malloc (nsize * sizeof (jstring));
memset (next, 0, nsize * sizeof (jstring));
while (--i >= 0)
@@ -157,6 +158,7 @@ java::lang::String::rehash()
strhash_size = nsize;
strhash = next;
+ _Jv_Free (old);
}
}