This is the mail archive of the java@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]

Re: static constructors and GC initialization


"Boehm, Hans" wrote:

> I suspect the issue here is that list of dynamic libraries was somehow
> invalid when it tried to walk it, and it thus ends up trying to mark from a
> region of memory that isn't mapped yet.

That makes sense to me.

> Alternatively, it's somehow
> It would be nice to know more about what's happening, e.g. the fault address
> (i.e. the value of "limit" in mark.c), and the output of GC_dump() when it
> fails, if that's possible.

I already wrote a patch to remove all the static c++ initializers from libgcj
(see below), so I'm not seeing the crash any more in my local tree. I'll send
you this info if I can reproduce it again later.

Unfortunatly sprof still refuses to have anything to do with libgcj.so.  I
don't know why. It works fine with libgcjgc.so and libstdc++-v3.so. Thats
unfortunate because it looks like a rather useful profiling tool considering it
works with threads, and we don't need to compile with any special options.

$ sprof libgcj.so.1 profile/libgcj.so.1.profile
sprof: failed to load shared object `libgcj.so.1'

regards

  [ bryce ]


Index: defineclass.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/defineclass.cc,v
retrieving revision 1.13
diff -u -r1.13 defineclass.cc
--- defineclass.cc	2000/10/20 23:25:57	1.13
+++ defineclass.cc	2001/01/30 06:52:22
@@ -30,6 +30,7 @@
 #endif
 #include <java-cpool.h>
 #include <gcj/cni.h>
+#include <jvm.h>
 
 #include <java/lang/Class.h>
 #include <java/lang/Float.h>
@@ -44,10 +45,7 @@
 #include <java/lang/IncompatibleClassChangeError.h>
 #include <java/lang/reflect/Modifier.h>
 
-// we don't verify method names that match these.
-static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
-
+using namespace gcj;
 
 // these go in some seperate functions, to avoid having _Jv_InitClass
 // inserted all over the place.
Index: interpret.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/interpret.cc,v
retrieving revision 1.22
diff -u -r1.22 interpret.cc
--- interpret.cc	2000/10/20 23:25:57	1.22
+++ interpret.cc	2001/01/30 06:52:22
@@ -40,7 +40,7 @@
 #include <alloca.h>
 #endif
 
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
+using namespace gcj;
 
 static void throw_internal_error (char *msg)
   __attribute__ ((__noreturn__));
Index: jni.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/jni.cc,v
retrieving revision 1.36
diff -u -r1.36 jni.cc
--- jni.cc	2001/01/27 19:30:31	1.36
+++ jni.cc	2001/01/30 06:52:23
@@ -47,6 +47,8 @@
 
 #include <java-interp.h>
 
+using namespace gcj;
+
 // FIXME: remove these defines.
 #define ClassClass java::lang::Class::class$
 #define ObjectClass java::lang::Object::class$
@@ -1479,9 +1481,6 @@
 			   jboolean)
 {
   using namespace java::lang::reflect;
-
-  // FIXME.
-  static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
 
   jobject result = NULL;
 
Index: prims.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/prims.cc,v
retrieving revision 1.46
diff -u -r1.46 prims.cc
--- prims.cc	2001/01/17 08:13:06	1.46
+++ prims.cc	2001/01/30 06:52:23
@@ -510,22 +510,50 @@
 
 
 
+/*
 #define DECLARE_PRIM_TYPE(NAME, SIG, LEN)				\
   _Jv_ArrayVTable _Jv_##NAME##VTable;					\
   java::lang::Class _Jv_##NAME##Class ((jobject) #NAME,			\
-				       (jbyte) SIG, (jint) LEN,		\
-				       (jobject) &_Jv_##NAME##VTable);
+				       (jbyte) SIG, (jint) LEN);
+*/
 
-DECLARE_PRIM_TYPE(byte, 'B', 1);
-DECLARE_PRIM_TYPE(short, 'S', 2);
-DECLARE_PRIM_TYPE(int, 'I', 4);
-DECLARE_PRIM_TYPE(long, 'J', 8);
-DECLARE_PRIM_TYPE(boolean, 'Z', 1);
-DECLARE_PRIM_TYPE(char, 'C', 2);
-DECLARE_PRIM_TYPE(float, 'F', 4);
-DECLARE_PRIM_TYPE(double, 'D', 8);
-DECLARE_PRIM_TYPE(void, 'V', 0);
+#define DECLARE_PRIM_TYPE(NAME)						\
+  _Jv_ArrayVTable _Jv_##NAME##VTable;					\
+  java::lang::Class _Jv_##NAME##Class;
+
+/*				       (jobject) &_Jv_##NAME##VTable); */
+
+DECLARE_PRIM_TYPE(byte);
+DECLARE_PRIM_TYPE(short);
+DECLARE_PRIM_TYPE(int);
+DECLARE_PRIM_TYPE(long);
+DECLARE_PRIM_TYPE(boolean);
+DECLARE_PRIM_TYPE(char);
+DECLARE_PRIM_TYPE(float);
+DECLARE_PRIM_TYPE(double);
+DECLARE_PRIM_TYPE(void);
 
+void
+_Jv_InitPrimClass (jclass cl, char *cname, char sig, int len, 
+                   _Jv_ArrayVTable *array_vtable)
+{    
+  using namespace java::lang::reflect;
+
+  // We must initialize every field of the class.  We do this in the
+  // same order they are declared in Class.h, except for fields that
+  // are initialized to NULL.
+  cl->name = _Jv_makeUtf8Const (cname, -1);
+  cl->accflags = Modifier::PUBLIC | Modifier::FINAL | Modifier::ABSTRACT;
+  cl->method_count = sig;
+  cl->size_in_bytes = len;
+  cl->vtable = JV_PRIMITIVE_VTABLE;
+  cl->state = JV_STATE_DONE;
+  cl->depth = -1;
+  if (sig != 'V')
+    _Jv_NewArrayClass (cl, NULL, (_Jv_VTable *) array_vtable);
+}
+
+
 jclass
 _Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader)
 {
@@ -637,9 +665,52 @@
 
 #endif
 
+namespace gcj
+{
+  _Jv_Utf8Const *void_signature;
+  _Jv_Utf8Const *clinit_name;
+  _Jv_Utf8Const *init_name;
+  _Jv_Utf8Const *finit_name;
+}
+
+/* Initialize some Utf8 constants declared in jvm.h. */
+void
+initVMConstants ()
+{
+  using namespace gcj;
+
+  void_signature = _Jv_makeUtf8Const ("()V", 3);
+  clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
+  init_name = _Jv_makeUtf8Const ("<init>", 6);
+  finit_name = _Jv_makeUtf8Const ("finit$", 6);
+}
+
+#include <stdio.h>
 static void
 main_init ()
 {
+  static bool init = false;
+
+  if (init)
+    return;
+
+  init = true;
+  initVMConstants ();
+  _Jv_InitThreads ();
+  _Jv_InitGC ();
+  _Jv_InitializeSyncMutex ();
+
+  /* Initialize built-in classes to represent primitive TYPEs. */
+  _Jv_InitPrimClass (&_Jv_byteClass,    "byte",    'B', 1, &_Jv_byteVTable);
+  _Jv_InitPrimClass (&_Jv_shortClass,   "short",   'S', 2, &_Jv_shortVTable);
+  _Jv_InitPrimClass (&_Jv_intClass,     "int",     'I', 4, &_Jv_intVTable);
+  _Jv_InitPrimClass (&_Jv_longClass,    "long",    'J', 8, &_Jv_longVTable);
+  _Jv_InitPrimClass (&_Jv_booleanClass, "boolean", 'Z', 1, &_Jv_booleanVTable);
+  _Jv_InitPrimClass (&_Jv_charClass,    "char",    'C', 2, &_Jv_charVTable);
+  _Jv_InitPrimClass (&_Jv_floatClass,   "float",   'F', 4, &_Jv_floatVTable);
+  _Jv_InitPrimClass (&_Jv_doubleClass,  "double",  'D', 8, &_Jv_doubleVTable);
+  _Jv_InitPrimClass (&_Jv_voidClass,    "void",    'V', 0, &_Jv_voidVTable);
+
   // Turn stack trace generation off while creating exception objects.
   _Jv_InitClass (&java::lang::Throwable::class$);
   java::lang::Throwable::trace_enabled = 0;
Index: resolve.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/resolve.cc,v
retrieving revision 1.19
diff -u -r1.19 resolve.cc
--- resolve.cc	2000/10/06 01:49:31	1.19
+++ resolve.cc	2001/01/30 06:52:23
@@ -34,6 +34,8 @@
 
 #ifdef INTERPRETER
 
+using namespace gcj;
+
 static void throw_internal_error (char *msg)
 	__attribute__ ((__noreturn__));
 static void throw_class_format_error (jstring msg)
@@ -53,9 +55,6 @@
 			 jboolean,
 			 jint);
 
-
-// We need to know the name of a constructor.
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
 
 static void throw_incompatible_class_change_error (jstring msg)
 {
Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/egcs/libjava/include/jvm.h,v
retrieving revision 1.31
diff -u -r1.31 jvm.h
--- jvm.h	2000/10/09 01:54:50	1.31
+++ jvm.h	2001/01/30 06:52:23
@@ -102,6 +102,15 @@
 // FIXME: remove this define.
 #define StringClass java::lang::String::class$
 
+namespace gcj
+{
+  /* Some constants used during lookup of special class methods.  */
+  extern _Jv_Utf8Const *void_signature; /* "()V" */
+  extern _Jv_Utf8Const *clinit_name;    /* "<clinit>" */
+  extern _Jv_Utf8Const *init_name;      /* "<init>" */
+  extern _Jv_Utf8Const *finit_name;     /* "finit$", */
+};
+
 /* Type of pointer used as finalizer.  */
 typedef void _Jv_FinalizerFunc (jobject);
 
Index: java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/egcs/libjava/java/lang/Class.h,v
retrieving revision 1.31
diff -u -r1.31 Class.h
--- Class.h	2001/01/17 10:22:32	1.31
+++ Class.h	2001/01/30 06:52:23
@@ -14,7 +14,6 @@
 
 #pragma interface
 
-#include <stddef.h>
 #include <java/lang/Object.h>
 #include <java/lang/String.h>
 #include <java/net/URL.h>
@@ -52,6 +51,7 @@
 
 struct _Jv_Field;
 struct _Jv_VTable;
+struct _Jv_ArrayVTable;
 union _Jv_word;
 
 struct _Jv_Constants
@@ -197,19 +197,20 @@
   // finalization
   void finalize ();
 
-  Class () {};
-
   // This constructor is used to create Class object for the primitive
   // types. See prims.cc.
-  Class (jobject cname, jbyte sig, jint len, jobject array_vtable)
-  {    
-    using namespace java::lang::reflect;
-    _Jv_Utf8Const *_Jv_makeUtf8Const (char *s, int len);
-
+  Class ()
+  {
     // C++ ctors set the vtbl pointer to point at an offset inside the vtable
     // object. That doesn't work for Java, so this hack adjusts it back.
     void *p =  ((void **)this)[0];
     ((void **)this)[0] = (void *)((char *)p-2*sizeof (void *));
+  };
+/*
+  Class (jobject cname, jbyte sig, jint len)
+  {    
+    using namespace java::lang::reflect;
+    _Jv_Utf8Const *_Jv_makeUtf8Const (char *s, int len);
 
     // We must initialize every field of the class.  We do this in the
     // same order they are declared in Class.h, except for fields that
@@ -224,7 +225,7 @@
     if (method_count != 'V')
       _Jv_NewArrayClass (this, NULL, (_Jv_VTable *) array_vtable);
   }
-
+*/
   static java::lang::Class class$;
 
 private:   
@@ -291,6 +292,9 @@
 				 _Jv_VTable *array_vtable = 0);
   friend jclass _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
 			      java::lang::ClassLoader *loader);
+
+  // in prims.cc
+  friend void _Jv_InitPrimClass (jclass, char *, char, int, _Jv_ArrayVTable *);
 
   friend void _Jv_PrepareCompiledClass (jclass);
   friend void _Jv_PrepareConstantTimeTables (jclass);
Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/java/lang/natClass.cc,v
retrieving revision 1.35
diff -u -r1.35 natClass.cc
--- natClass.cc	2001/01/17 10:22:32	1.35
+++ natClass.cc	2001/01/30 06:52:23
@@ -60,17 +60,21 @@
 #define FieldClass java::lang::reflect::Field::class$
 #define ConstructorClass java::lang::reflect::Constructor::class$
 
-// Some constants we use to look up the class initializer.
-static _Jv_Utf8Const *void_signature = _Jv_makeUtf8Const ("()V", 3);
-static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
-static _Jv_Utf8Const *finit_name = _Jv_makeUtf8Const ("finit$", 6);
-// The legacy `$finit$' method name, which still needs to be
-// recognized as equivalent to the now prefered `finit$' name.
-static _Jv_Utf8Const *finit_leg_name = _Jv_makeUtf8Const ("$finit$", 7);
-
 
 
+using namespace gcj;
+
+static inline bool
+isHiddenMethod (_Jv_Method *method)
+{
+  if (method->name == NULL
+      || _Jv_equalUtf8Consts (method->name, clinit_name)
+      || _Jv_equalUtf8Consts (method->name, init_name)
+      || _Jv_equalUtf8Consts (method->name, finit_name))
+    return true;
+  return false;
+}
+
 jclass
 java::lang::Class::forName (jstring className, java::lang::ClassLoader *loader)
 {
@@ -332,12 +336,7 @@
   for (i = max; --i >= 0; )
     {
       _Jv_Method *method = &methods[i];
-      if (method->name == NULL
-	  || _Jv_equalUtf8Consts (method->name, clinit_name)
-	  || _Jv_equalUtf8Consts (method->name, init_name)
-	  || _Jv_equalUtf8Consts (method->name, finit_name)
-	  // Backward compatibility hack: match the legacy `$finit$' name
-	  || _Jv_equalUtf8Consts (method->name, finit_leg_name))
+      if (isHiddenMethod (method))
 	continue;
       numMethods++;
     }
@@ -348,13 +347,8 @@
   for (i = 0;  i < max;  i++)
     {
       _Jv_Method *method = &methods[i];
-      if (method->name == NULL
-	  || _Jv_equalUtf8Consts (method->name, clinit_name)
-	  || _Jv_equalUtf8Consts (method->name, init_name)
-	  || _Jv_equalUtf8Consts (method->name, finit_name)
-	  // Backward compatibility hack: match the legacy `$finit$' name
-	  || _Jv_equalUtf8Consts (method->name, finit_leg_name))
-	continue;
+      if (isHiddenMethod (method))
+        continue;
       java::lang::reflect::Method* rmethod
 	= new java::lang::reflect::Method ();
       rmethod->offset = (char*) method - (char*) methods;
@@ -513,12 +507,7 @@
   for (int i = isPrimitive () ? 0 : method_count; --i >= 0; )
     {
       _Jv_Method *method = &methods[i];
-      if (method->name == NULL
-	  || _Jv_equalUtf8Consts (method->name, clinit_name)
-	  || _Jv_equalUtf8Consts (method->name, init_name)
-	  || _Jv_equalUtf8Consts (method->name, finit_name)
-	  // Backward compatibility hack: match the legacy `$finit$' name
-	  || _Jv_equalUtf8Consts (method->name, finit_leg_name))
+      if (isHiddenMethod (method))
 	continue;
       // Only want public methods.
       if (! java::lang::reflect::Modifier::isPublic (method->accflags))
Index: java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/egcs/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.28
diff -u -r1.28 natClassLoader.cc
--- natClassLoader.cc	2001/01/08 23:28:55	1.28
+++ natClassLoader.cc	2001/01/30 06:52:23
@@ -420,17 +420,8 @@
 void
 _Jv_RegisterClasses (jclass *classes)
 {
-  static bool init = false;
-
-  if (! init)
-    {
-      init = true;
-      _Jv_InitThreads ();
-      _Jv_InitGC ();
-      _Jv_InitializeSyncMutex ();
-    }
-
-  JvSynchronize sync (&ClassClass);
+  // FIXME
+  //JvSynchronize sync (&ClassClass);
   for (; *classes; ++classes)
     {
       jclass klass = *classes;
@@ -594,16 +585,18 @@
   JvAssert (ObjectClass.vtable_method_count == NUM_OBJECT_METHODS);
   int dm_count = ObjectClass.vtable_method_count;
 
-  // Create a new vtable by copying Object's vtable (except the
-  // class pointer, of course).  Note that we allocate this as
-  // unscanned memory -- the vtables are handled specially by the
-  // GC.
-  int size = (sizeof (_Jv_VTable) + ((dm_count - 1) * sizeof (void *)));
   _Jv_VTable *vtable;
   if (array_vtable)
     vtable = array_vtable;
   else
-    vtable = (_Jv_VTable *) _Jv_AllocBytes (size);
+    {
+      // Create a new vtable by copying Object's vtable (except the
+      // class pointer, of course).  Note that we allocate this as
+      // unscanned memory -- the vtables are handled specially by the
+      // GC.
+      int size = (sizeof (_Jv_VTable) + ((dm_count - 1) * sizeof (void *)));
+      vtable = (_Jv_VTable *) _Jv_AllocBytes (size);
+    }
   vtable->clas = array_class;
   memcpy (vtable->method, ObjectClass.vtable->method,
 	  dm_count * sizeof (void *));

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