[3.0 branch] libjava testsuite, i686-pc-linux-gnu --disable-shared

Andrew Haley aph@cambridge.redhat.com
Thu May 3 09:50:00 GMT 2001


 > Joseph S. Myers writes:
 >  > On Fri, 27 Apr 2001, Joseph S. Myers wrote:
 >  > 
 >  > > On i686-pc-linux-gnu, configured with --prefix=/opt/gcc/snapshot
 >  > > --disable-shared --enable-threads=posix --with-system-zlib, I find the
 >  > > libjava testsuite (3.0 branch) runs for an excessive length of time
 >  > > because of many execution tests timing out.  When using --enable-shared
 >  > > instead this doesn't happen and the results are the more reasonable
 >  > 
 >  > I'm still observing this problem, which makes building and running the
 >  > testsuite take about seven times as long as it should.  The diff between
 >  > --enable-shared and --disable-shared libjava.sum is:

This problem is caused by initialization in libgcj: class
initialization routines are being called before the C++ static
initializers that they depend on have been run.

This patch removes the dependence on static initializers.  It is
mostly the same as one posted by Bryce a couple of months ago.

In practice it is almost impossible to control C++ static
initializers, so I propose that we ban them from now on.

Andrew.


2001-05-03  Andrew Haley  <aph@cambridge.redhat.com>

	* include/jvm.h
	(void_signature, clinit_name, init_name, finit_name, finit_leg_name):
	Declare in namespace gcj.
	* java/lang/Class.h (Class): Remove initialization of primitive
	types.
	(friend void _Jv_InitPrimClass): This is in prims.cc.
	* prims.cc (_Jv_InitPrimClass): Do primitive type initialization
	here instead.
	(void_signature, clinit_name, init_name, finit_name, finit_leg_name):
	Define in namespace gcj.
	(initVMConstants): New.
	(main_init): Initialize primitive types.
	* jni.cc (DECLARE_PRIM_TYPE): Don't initialize by static
	constructor.
	* defineclass.cc: Remove clinit_name and init_name.  Use namespace
	gcj.
	* interpret.cc: Likewise.
	* resolve.cc: Likewise.
	* java/lang/natClass.cc: Rmove static _Jv_Utf8Const method names.
	* java/lang/natClassLoader.cc (_Jv_RegisterClasses): Don't call
	initialization routines.
	(_Jv_NewArrayClass): Don't calculate size if array_vtable is
	passed.

Index: defineclass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/defineclass.cc,v
retrieving revision 1.16
diff -p -2 -c -r1.16 defineclass.cc
*** defineclass.cc	2001/03/26 07:05:31	1.16
--- defineclass.cc	2001/05/03 15:23:25
*************** details.  */
*** 28,31 ****
--- 28,32 ----
  #include <java-cpool.h>
  #include <gcj/cni.h>
+ #include <jvm.h>
  
  #include <java/lang/Class.h>
*************** details.  */
*** 42,49 ****
  #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);
! 
  
  // these go in some seperate functions, to avoid having _Jv_InitClass
--- 43,47 ----
  #include <java/lang/reflect/Modifier.h>
  
! using namespace gcj;
  
  // these go in some seperate functions, to avoid having _Jv_InitClass
Index: interpret.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/interpret.cc,v
retrieving revision 1.25
diff -p -2 -c -r1.25 interpret.cc
*** interpret.cc	2001/03/26 07:05:31	1.25
--- interpret.cc	2001/05/03 15:23:26
*************** details.  */
*** 38,42 ****
  #include <stdlib.h>
  
! static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
  
  static void throw_internal_error (char *msg)
--- 38,42 ----
  #include <stdlib.h>
  
! using namespace gcj;
  
  static void throw_internal_error (char *msg)
Index: jni.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni.cc,v
retrieving revision 1.43
diff -p -2 -c -r1.43 jni.cc
*** jni.cc	2001/04/27 16:09:54	1.43
--- jni.cc	2001/05/03 15:23:28
*************** details.  */
*** 48,51 ****
--- 48,53 ----
  #include <java-interp.h>
  
+ using namespace gcj;
+ 
  // FIXME: remove these defines.
  #define ClassClass java::lang::Class::class$
*************** _Jv_JNI_ToReflectedMethod (JNIEnv *env, 
*** 1497,1503 ****
  {
    using namespace java::lang::reflect;
- 
-   // FIXME.
-   static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
  
    jobject result = NULL;
--- 1499,1502 ----
Index: prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.50
diff -p -2 -c -r1.50 prims.cc
*** prims.cc	2001/04/28 00:04:55	1.50
--- prims.cc	2001/05/03 15:23:28
*************** _Jv_NewMultiArray (jclass array_type, ji
*** 510,529 ****
  
  
! #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);
! 
! 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);
  
  jclass
  _Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader)
--- 510,548 ----
  
  
! #define DECLARE_PRIM_TYPE(NAME)			\
!   _Jv_ArrayVTable _Jv_##NAME##VTable;		\
!   java::lang::Class _Jv_##NAME##Class;
! 
! 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)
*************** win32_exception_handler (LPEXCEPTION_POI
*** 641,647 ****
--- 660,711 ----
  #endif
  
+ namespace gcj
+ {
+   _Jv_Utf8Const *void_signature;
+   _Jv_Utf8Const *clinit_name;
+   _Jv_Utf8Const *init_name;
+   _Jv_Utf8Const *finit_name;
+   _Jv_Utf8Const *finit_leg_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);
+   finit_leg_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$);
Index: resolve.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/resolve.cc,v
retrieving revision 1.21
diff -p -2 -c -r1.21 resolve.cc
*** resolve.cc	2001/03/26 07:05:31	1.21
--- resolve.cc	2001/05/03 15:23:29
*************** _Jv_ResolveField (_Jv_Field *field, java
*** 46,49 ****
--- 46,51 ----
  #ifdef INTERPRETER
  
+ using namespace gcj;
+ 
  static void throw_internal_error (char *msg)
  	__attribute__ ((__noreturn__));
*************** _Jv_BuildResolvedMethod (_Jv_Method*,
*** 65,71 ****
  			 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)
--- 67,70 ----
Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.32
diff -p -2 -c -r1.32 jvm.h
*** jvm.h	2001/03/23 19:15:43	1.32
--- jvm.h	2001/05/03 15:23:30
*************** extern jboolean _Jv_equaln (_Jv_Utf8Cons
*** 103,106 ****
--- 103,116 ----
  #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$", */
+   extern _Jv_Utf8Const *finit_leg_name; /* "$finit$", */
+ };
+ 
  /* Type of pointer used as finalizer.  */
  typedef void _Jv_FinalizerFunc (jobject);
Index: java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
retrieving revision 1.32
diff -p -2 -c -r1.32 Class.h
*** Class.h	2001/04/25 15:45:12	1.32
--- Class.h	2001/05/03 15:23:30
*************** details.  */
*** 15,19 ****
  #pragma interface
  
- #include <stddef.h>
  #include <java/lang/Object.h>
  #include <java/lang/String.h>
--- 15,18 ----
*************** enum
*** 54,57 ****
--- 53,57 ----
  struct _Jv_Field;
  struct _Jv_VTable;
+ struct _Jv_ArrayVTable;
  union _Jv_word;
  
*************** public:
*** 201,232 ****
    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);
! 
      // 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 *));
  
-     // 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.
-     name = _Jv_makeUtf8Const ((char *) cname, -1);
-     accflags = Modifier::PUBLIC | Modifier::FINAL | Modifier::ABSTRACT;
-     method_count = sig;
-     size_in_bytes = len;
-     vtable = JV_PRIMITIVE_VTABLE;
-     state = JV_STATE_DONE;
-     depth = -1;
-     if (method_count != 'V')
-       _Jv_NewArrayClass (this, NULL, (_Jv_VTable *) array_vtable);
-   }
- 
    static java::lang::Class class$;
  
--- 201,214 ----
    void finalize ();
  
    // This constructor is used to create Class object for the primitive
    // types. See prims.cc.
!   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 *));
+   };
  
    static java::lang::Class class$;
  
*************** private:   
*** 295,298 ****
--- 277,283 ----
    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);
Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.42
diff -p -2 -c -r1.42 natClass.cc
*** natClass.cc	2001/04/25 15:45:12	1.42
--- natClass.cc	2001/05/03 15:23:31
*************** details.  */
*** 61,74 ****
  #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);
- 
  
  
  jclass
--- 61,67 ----
  #define ConstructorClass java::lang::reflect::Constructor::class$
  
  
+ 
+ using namespace gcj;
  
  jclass
Index: java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.32
diff -p -2 -c -r1.32 natClassLoader.cc
*** natClassLoader.cc	2001/04/28 01:39:15	1.32
--- natClassLoader.cc	2001/05/03 15:23:32
*************** void
*** 424,438 ****
  _Jv_RegisterClasses (jclass *classes)
  {
!   static bool init = false;
! 
!   if (! init)
!     {
!       init = true;
!       _Jv_InitThreads ();
!       _Jv_InitGC ();
!       _Jv_InitializeSyncMutex ();
!     }
! 
!   JvSynchronize sync (&ClassClass);
    for (; *classes; ++classes)
      {
--- 424,429 ----
  _Jv_RegisterClasses (jclass *classes)
  {
!   // FIXME
!   //JvSynchronize sync (&ClassClass);
    for (; *classes; ++classes)
      {
*************** _Jv_NewArrayClass (jclass element, java:
*** 598,611 ****
    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);
    vtable->clas = array_class;
    memcpy (vtable->method, ObjectClass.vtable->method,
--- 589,604 ----
    int dm_count = ObjectClass.vtable_method_count;
  
    _Jv_VTable *vtable;
    if (array_vtable)
      vtable = array_vtable;
    else
!     {
!       // 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,



More information about the Java mailing list