This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: [3.0 branch] libjava testsuite, i686-pc-linux-gnu --disable-shared
> 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,