Eliminate use of C++ static constructors.

* interpret.cc: Remove static Utf8Consts. Use namespace gcj.
	* jni.cc: Likewise.
	* resolve.cc: Likewise.
	* defineclass.cc: Likewise.
	(_Jv_ClassReader::handleClassBegin): Synchronize call to
	_Jv_RegisterClass.
	* include/jvm.h (void_signature, clinit_name, init_name, finit_name):
	Declare in namespace gcj.
	* java/lang/Class.h (Class): Remove initialization for 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): Define in
	namespace gcj.
	(_Jv_CreateJavaVM): Call _Jv_InitThreads, _Jv_InitGC, and
	_Jv_InitializeSyncMutex from here. Initialize Utf8 constants.
	Initialize primitive types.
	* java/lang/natClassLoader.cc (_Jv_RegisterClasses): Don't call
	initialization routines. Don't synchronize.
	* java/lang/natRuntime.cc (_load): Synchronize on java.lang.Class
	across dlopen call.

From-SVN: r46282
This commit is contained in:
Bryce McKinlay 2001-10-16 08:35:17 +00:00 committed by Bryce McKinlay
parent 6fd617e3e1
commit 107abb2f61
10 changed files with 131 additions and 61 deletions

View file

@ -2,6 +2,30 @@
* name-finder.cc (_Jv_name_finder::lookup): Check for NULL dli_sname.
Eliminate use of C++ static constructors.
* interpret.cc: Remove static Utf8Consts. Use namespace gcj.
* jni.cc: Likewise.
* resolve.cc: Likewise.
* defineclass.cc: Likewise.
(_Jv_ClassReader::handleClassBegin): Synchronize call to
_Jv_RegisterClass.
* include/jvm.h (void_signature, clinit_name, init_name, finit_name):
Declare in namespace gcj.
* java/lang/Class.h (Class): Remove initialization for 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): Define in
namespace gcj.
(_Jv_CreateJavaVM): Call _Jv_InitThreads, _Jv_InitGC, and
_Jv_InitializeSyncMutex from here. Initialize Utf8 constants.
Initialize primitive types.
* java/lang/natClassLoader.cc (_Jv_RegisterClasses): Don't call
initialization routines. Don't synchronize.
* java/lang/natRuntime.cc (_load): Synchronize on java.lang.Class
across dlopen call.
2001-10-15 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
* java/util/HashMap.java (HashEntry.clone): Removed.

View file

@ -41,10 +41,7 @@ details. */
#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 separate functions, to avoid having _Jv_InitClass
// inserted all over the place.
@ -934,7 +931,11 @@ _Jv_ClassReader::handleClassBegin
// to include references to this class.
def->state = JV_STATE_PRELOADING;
_Jv_RegisterClass (def);
{
JvSynchronize sync (&java::lang::Class::class$);
_Jv_RegisterClass (def);
}
if (super_class != 0)
{

View file

@ -124,6 +124,15 @@ extern jboolean _Jv_equaln (_Jv_Utf8Const *, jstring, jint);
// 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);

View file

@ -37,7 +37,7 @@ details. */
#include <stdlib.h>
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
using namespace gcj;
static void throw_internal_error (char *msg)
__attribute__ ((__noreturn__));

View file

@ -60,17 +60,10 @@ details. */
#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;
jclass
java::lang::Class::forName (jstring className, jboolean initialize,
java::lang::ClassLoader *loader)
@ -341,9 +334,7 @@ java::lang::Class::getDeclaredMethods (void)
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))
|| _Jv_equalUtf8Consts (method->name, finit_name))
continue;
numMethods++;
}
@ -357,9 +348,7 @@ java::lang::Class::getDeclaredMethods (void)
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))
|| _Jv_equalUtf8Consts (method->name, finit_name))
continue;
java::lang::reflect::Method* rmethod
= new java::lang::reflect::Method ();
@ -522,9 +511,7 @@ java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result,
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))
|| _Jv_equalUtf8Consts (method->name, finit_name))
continue;
// Only want public methods.
if (! java::lang::reflect::Modifier::isPublic (method->accflags))

View file

@ -175,7 +175,6 @@ java::lang::ClassLoader::markClassErrorState0 (java::lang::Class *klass)
klass->notifyAll ();
}
// This is the findClass() implementation for the System classloader. It is
// the only native method in VMClassLoader, so we define it here.
jclass
@ -419,24 +418,13 @@ _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
}
// This function is called many times during startup, before main() is
// run. We do our runtime initialization here the very first time we
// are called. At that point in time we know for certain we are
// running single-threaded, so we don't need to lock when modifying
// `init'. CLASSES is NULL-terminated.
// run. At that point in time we know for certain we are running
// single-threaded, so we don't need to lock when adding classes to the
// class chain. At all other times, the caller should synchronize on
// Class::class$.
void
_Jv_RegisterClasses (jclass *classes)
{
static bool init = false;
if (! init)
{
init = true;
_Jv_InitThreads ();
_Jv_InitGC ();
_Jv_InitializeSyncMutex ();
}
JvSynchronize sync (&ClassClass);
for (; *classes; ++classes)
{
jclass klass = *classes;

View file

@ -138,8 +138,15 @@ java::lang::Runtime::_load (jstring path, jboolean do_search)
#endif
jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
buf[offset + total] = '\0';
lt_dlhandle h;
// FIXME: make sure path is absolute.
lt_dlhandle h = do_search ? lt_dlopenext (buf) : lt_dlopen (buf);
{
// Synchronize on java.lang.Class. This is to protect the class chain from
// concurrent modification by class registration calls which may be run
// during the dlopen().
JvSynchronize sync (&java::lang::Class::class$);
h = do_search ? lt_dlopenext (buf) : lt_dlopen (buf);
}
if (h == NULL)
{
const char *msg = lt_dlerror ();

View file

@ -48,6 +48,8 @@ details. */
#include <java-interp.h>
#include <java-threads.h>
using namespace gcj;
// This enum is used to select different template instantiations in
// the invocation code.
enum invocation_type
@ -1502,9 +1504,6 @@ _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
{
using namespace java::lang::reflect;
// FIXME.
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
jobject result = NULL;
try

View file

@ -574,21 +574,39 @@ _Jv_NewMultiArray (jclass array_type, jint dimensions, ...)
#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);
#define DECLARE_PRIM_TYPE(NAME) \
_Jv_ArrayVTable _Jv_##NAME##VTable; \
java::lang::Class _Jv_##NAME##Class;
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);
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 ((char *) 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)
@ -848,11 +866,49 @@ process_gcj_properties ()
}
#endif // DISABLE_GETENV_PROPERTIES
namespace gcj
{
_Jv_Utf8Const *void_signature;
_Jv_Utf8Const *clinit_name;
_Jv_Utf8Const *init_name;
_Jv_Utf8Const *finit_name;
}
jint
_Jv_CreateJavaVM (void* /*vm_args*/)
{
using namespace gcj;
static bool init = false;
if (init)
return -1;
init = true;
PROCESS_GCJ_PROPERTIES;
_Jv_InitThreads ();
_Jv_InitGC ();
_Jv_InitializeSyncMutex ();
/* Initialize Utf8 constants declared in jvm.h. */
void_signature = _Jv_makeUtf8Const ("()V", 3);
clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
init_name = _Jv_makeUtf8Const ("<init>", 6);
finit_name = _Jv_makeUtf8Const ("finit$", 6);
/* 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;

View file

@ -32,6 +32,8 @@ details. */
#include <java/lang/IncompatibleClassChangeError.h>
#include <java/lang/reflect/Modifier.h>
using namespace gcj;
void
_Jv_ResolveField (_Jv_Field *field, java::lang::ClassLoader *loader)
{
@ -65,9 +67,6 @@ _Jv_BuildResolvedMethod (_Jv_Method*,
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)
{
throw new java::lang::IncompatibleClassChangeError (msg);