This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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);
     }
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]