diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2004-11-25 03:47:08 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2004-11-25 03:47:08 +0000 |
commit | 367390404d26b7bfc400d77893579e83e2a19fb9 (patch) | |
tree | 477abdf83653e20b0e74447d6ca47eb67b0511b8 /libjava/java/lang/natClassLoader.cc | |
parent | ec0641f612862498e829fdaf040a201c0ba68762 (diff) | |
download | gcc-367390404d26b7bfc400d77893579e83e2a19fb9.zip gcc-367390404d26b7bfc400d77893579e83e2a19fb9.tar.gz gcc-367390404d26b7bfc400d77893579e83e2a19fb9.tar.bz2 |
* Merged gcj-abi-2-dev-branch to trunk.
(Actual changes too large to list in the commit message;
see ChangeLog.)
From-SVN: r91270
Diffstat (limited to 'libjava/java/lang/natClassLoader.cc')
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 194 |
1 files changed, 21 insertions, 173 deletions
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index 5a0898a..dd5cd46 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -18,6 +18,7 @@ details. */ #include <gcj/cni.h> #include <jvm.h> +#include <execution.h> #include <java-threads.h> #include <java-interp.h> @@ -33,6 +34,7 @@ details. */ #include <java/lang/ClassNotFoundException.h> #include <java/lang/ClassCircularityError.h> #include <java/lang/IncompatibleClassChangeError.h> +#include <java/lang/ClassFormatError.h> #include <java/lang/VirtualMachineError.h> #include <java/lang/VMClassLoader.h> #include <java/lang/reflect/Modifier.h> @@ -41,156 +43,6 @@ details. */ #include <java/io/Serializable.h> #include <java/lang/Cloneable.h> -void -_Jv_WaitForState (jclass klass, int state) -{ - if (klass->state >= state) - return; - - _Jv_MonitorEnter (klass) ; - - if (klass->state == JV_STATE_COMPILED) - { - klass->state = JV_STATE_LOADED; - if (gcj::verbose_class_flag) - fprintf (stderr, "[Loaded (pre-compiled) %s]\n", klass->name->chars()); - } - if (state == JV_STATE_LINKED) - { - // Must call _Jv_PrepareCompiledClass while holding the class - // mutex. -#ifdef INTERPRETER - if (_Jv_IsInterpretedClass (klass)) - _Jv_PrepareClass (klass); -#endif - _Jv_PrepareCompiledClass (klass); - _Jv_MonitorExit (klass); - return; - } - - java::lang::Thread *self = java::lang::Thread::currentThread(); - - // this is similar to the strategy for class initialization. - // if we already hold the lock, just leave. - while (klass->state <= state - && klass->thread - && klass->thread != self) - klass->wait (); - - _Jv_MonitorExit (klass); - - if (klass->state == JV_STATE_ERROR) - throw new java::lang::LinkageError; -} - -typedef unsigned int uaddr __attribute__ ((mode (pointer))); - -/** This function does class-preparation for compiled classes. - NOTE: It contains replicated functionality from - _Jv_ResolvePoolEntry, and this is intentional, since that function - lives in resolve.cc which is entirely conditionally compiled. - */ -void -_Jv_PrepareCompiledClass (jclass klass) -{ - jint state = klass->state; - if (state >= JV_STATE_LINKED) - return; - - // Short-circuit, so that mutually dependent classes are ok. - klass->state = JV_STATE_LINKED; - - _Jv_Constants *pool = &klass->constants; - - // Resolve class constants first, since other constant pool - // entries may rely on these. - for (int index = 1; index < pool->size; ++index) - { - if (pool->tags[index] == JV_CONSTANT_Class) - { - _Jv_Utf8Const *name = pool->data[index].utf8; - - jclass found; - if (name->first() == '[') - found = _Jv_FindClassFromSignature (name->chars(), - klass->loader); - else - found = _Jv_FindClass (name, klass->loader); - - if (! found) - { - jstring str = name->toString(); - throw new java::lang::NoClassDefFoundError (str); - } - - pool->data[index].clazz = found; - pool->tags[index] |= JV_CONSTANT_ResolvedFlag; - } - } - - // If superclass looks like a constant pool entry, - // resolve it now. - if ((uaddr) klass->superclass < pool->size) - klass->superclass = pool->data[(uaddr) klass->superclass].clazz; - - // Likewise for interfaces. - for (int i = 0; i < klass->interface_count; i++) - if ((uaddr) klass->interfaces[i] < pool->size) - klass->interfaces[i] = pool->data[(uaddr) klass->interfaces[i]].clazz; - - // Resolve the remaining constant pool entries. - for (int index = 1; index < pool->size; ++index) - { - if (pool->tags[index] == JV_CONSTANT_String) - { - jstring str; - - str = _Jv_NewStringUtf8Const (pool->data[index].utf8); - pool->data[index].o = str; - pool->tags[index] |= JV_CONSTANT_ResolvedFlag; - } - } - -#ifdef INTERPRETER - // FIXME: although the comment up top says that this function is - // only called for compiled classes, it is actually called for every - // class. - if (! _Jv_IsInterpretedClass (klass)) - { -#endif /* INTERPRETER */ - jfieldID f = JvGetFirstStaticField (klass); - for (int n = JvNumStaticFields (klass); n > 0; --n) - { - int mod = f->getModifiers (); - // If we have a static String field with a non-null initial - // value, we know it points to a Utf8Const. - _Jv_ResolveField(f, klass->loader); - if (f->getClass () == &java::lang::String::class$ - && java::lang::reflect::Modifier::isStatic (mod)) - { - jstring *strp = (jstring *) f->u.addr; - if (*strp) - *strp = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) *strp); - } - f = f->getNextField (); - } -#ifdef INTERPRETER - } -#endif /* INTERPRETER */ - - if (klass->isInterface ()) - _Jv_LayoutInterfaceMethods (klass); - - if (state == JV_STATE_COMPILED && gcj::verbose_class_flag) - fprintf (stderr, "[Loaded (pre-compiled) %s]\n", - klass->name->chars()); - - klass->notifyAll (); - - _Jv_PushClass (klass); -} - - // // A single class can have many "initiating" class loaders, // and a single "defining" class loader. The Defining @@ -221,6 +73,8 @@ static _Jv_LoaderInfo *initiated_classes[HASH_LEN]; static jclass loaded_classes[HASH_LEN]; // This is the root of a linked list of classes +static jclass stack_head; + @@ -323,11 +177,6 @@ _Jv_RegisterClasses (const jclass *classes) jclass klass = *classes; (*_Jv_RegisterClassHook) (klass); - - // registering a compiled class causes - // it to be immediately "prepared". - if (klass->state == JV_STATE_NOTHING) - klass->state = JV_STATE_COMPILED; } } @@ -341,11 +190,6 @@ _Jv_RegisterClasses_Counted (const jclass * classes, size_t count) jclass klass = classes[i]; (*_Jv_RegisterClassHook) (klass); - - // registering a compiled class causes - // it to be immediately "prepared". - if (klass->state == JV_STATE_NOTHING) - klass->state = JV_STATE_COMPILED; } } @@ -354,8 +198,10 @@ _Jv_RegisterClassHookDefault (jclass klass) { jint hash = HASH_UTF (klass->name); - jclass check_class = loaded_classes[hash]; - + // The BC ABI makes this check unnecessary: we always resolve all + // data references via the appropriate class loader, so the kludge + // that required this check has gone. +#if 0 // If the class is already registered, don't re-register it. while (check_class != NULL) { @@ -381,7 +227,11 @@ _Jv_RegisterClassHookDefault (jclass klass) check_class = check_class->next; } +#endif + // FIXME: this is really bogus! + if (! klass->engine) + klass->engine = &_Jv_soleCompiledEngine; klass->next = loaded_classes[hash]; loaded_classes[hash] = klass; } @@ -442,7 +292,7 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) { // we need classes to be in the hash while // we're loading, so that they can refer to themselves. - _Jv_WaitForState (klass, JV_STATE_LOADED); + _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED); } return klass; @@ -555,7 +405,7 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader, // cache one and reuse it. It is not necessary to synchronize this. if (!array_idt) { - _Jv_PrepareConstantTimeTables (array_class); + _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED); array_idt = array_class->idt; array_depth = array_class->depth; array_ancestors = array_class->ancestors; @@ -569,19 +419,19 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader, using namespace java::lang::reflect; { - // Array classes are "abstract final"... - _Jv_ushort accflags = Modifier::FINAL | Modifier::ABSTRACT; - // ... and inherit accessibility from element type, per vmspec 5.3.3.2 - accflags |= (element->accflags & Modifier::PUBLIC); - accflags |= (element->accflags & Modifier::PROTECTED); - accflags |= (element->accflags & Modifier::PRIVATE); + // Array classes are "abstract final" and inherit accessibility + // from element type, per vmspec 5.3.3.2 + _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT + | (element->accflags + & (Modifier::PUBLIC | Modifier::PROTECTED + | Modifier::PRIVATE))); array_class->accflags = accflags; } // An array class has no visible instance fields. "length" is invisible to // reflection. - // say this class is initialized and ready to go! + // Say this class is initialized and ready to go! array_class->state = JV_STATE_DONE; // vmspec, section 5.3.3 describes this @@ -591,8 +441,6 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader, element->arrayclass = array_class; } -static jclass stack_head; - // These two functions form a stack of classes. When a class is loaded // it is pushed onto the stack by the class loader; this is so that // StackTrace can quickly determine which classes have been loaded. |