diff options
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/lang/Class.h | 7 | ||||
-rw-r--r-- | libjava/java/lang/ClassLoader.java | 13 | ||||
-rw-r--r-- | libjava/java/lang/natClass.cc | 41 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 75 | ||||
-rw-r--r-- | libjava/java/lang/reflect/Modifier.java | 13 |
5 files changed, 89 insertions, 60 deletions
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index 4ccf388..d59899a 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -182,9 +182,9 @@ public: JArray<java::lang::reflect::Method *> *getMethods (void); inline jint getModifiers (void) - { - return accflags; - } + { + return accflags & java::lang::reflect::Modifier::ALL_FLAGS; + } jstring getName (void); @@ -348,6 +348,7 @@ private: _Jv_Utf8Const *method_signature); friend void _Jv_PrepareClass (jclass); + friend void _Jv_PrepareMissingMethods (jclass base, jclass iface_class); friend class _Jv_ClassReader; friend class _Jv_InterpClass; diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java index 033b2cc..8c99897 100644 --- a/libjava/java/lang/ClassLoader.java +++ b/libjava/java/lang/ClassLoader.java @@ -468,17 +468,18 @@ public abstract class ClassLoader { throw x; // rethrow } - catch (java.lang.VirtualMachineError x) + catch (VirtualMachineError x) { throw x; // rethrow } - catch (java.lang.Throwable x) + catch (Throwable x) { // This should never happen, or we are beyond spec. - throw new InternalError ("Unexpected exception " - + "while defining class " - + name + ": " - + x.toString ()); + InternalError r = new InternalError ("Unexpected exception " + + "while defining class " + + name); + r.initCause(x); + throw r; } } diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index bafac78..768ced6 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -343,7 +343,9 @@ java::lang::Class::_getDeclaredMethod (jstring name, while (--i >= 0) { if (_Jv_equalUtf8Consts (methods[i].name, utf_name) - && _Jv_equaln (methods[i].signature, partial_sig, p_len)) + && _Jv_equaln (methods[i].signature, partial_sig, p_len) + && (methods[i].accflags + & java::lang::reflect::Modifier::INVISIBLE) == 0) { // Found it. using namespace java::lang::reflect; @@ -368,7 +370,9 @@ 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)) + || _Jv_equalUtf8Consts (method->name, finit_name) + || (methods[i].accflags + & java::lang::reflect::Modifier::INVISIBLE) != 0) continue; numMethods++; } @@ -382,7 +386,9 @@ 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)) + || _Jv_equalUtf8Consts (method->name, finit_name) + || (methods[i].accflags + & java::lang::reflect::Modifier::INVISIBLE) != 0) continue; java::lang::reflect::Method* rmethod = new java::lang::reflect::Method (); @@ -514,7 +520,9 @@ java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types) { // FIXME: access checks. if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name) - && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)) + && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len) + && (klass->methods[i].accflags + & java::lang::reflect::Modifier::INVISIBLE) == 0) { // Found it. using namespace java::lang::reflect; @@ -565,7 +573,9 @@ 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)) + || _Jv_equalUtf8Consts (method->name, finit_name) + || (method->accflags + & java::lang::reflect::Modifier::INVISIBLE) != 0) continue; // Only want public methods. if (! java::lang::reflect::Modifier::isPublic (method->accflags)) @@ -1564,6 +1574,13 @@ isVirtualMethod (_Jv_Method *meth) && meth->name->data[0] != '<'); } +// This is put in empty vtable slots. +static void +_Jv_abstractMethodError (void) +{ + throw new java::lang::AbstractMethodError(); +} + // Prepare virtual method declarations in KLASS, and any superclasses as // required, by determining their vtable index, setting method->index, and // finally setting the class's vtable_method_count. Must be called with the @@ -1594,13 +1611,16 @@ _Jv_LayoutVTableMethods (jclass klass) continue; if (superclass != NULL) - super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name, - meth->signature); + { + super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name, + meth->signature); + } if (super_meth) meth->index = super_meth->index; - else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL)) - meth->index = index++; + else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL) + && ! (klass->accflags & java::lang::reflect::Modifier::FINAL)) + meth->index = index++; } klass->vtable_method_count = index; @@ -1626,8 +1646,7 @@ _Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable, jboolean *flags) continue; if ((meth->accflags & Modifier::ABSTRACT)) { - // FIXME: we should set abstract slots to a function that - // throws AbstractMethodError. How can we do that on IA-64? + vtable->set_method(meth->index, (void *) &_Jv_abstractMethodError); flags[meth->index] = false; } else diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index aeee08a..96a8181 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -56,17 +56,18 @@ java::lang::ClassLoader::defineClass0 (jstring name, sizeof (_Jv_InterpClass)); _Jv_InitNewClassFields (klass); - // synchronize on the class, so that it is not - // attempted initialized until we're done loading. - _Jv_MonitorEnter (klass); + // Synchronize on the class, so that it is not attempted initialized + // until we're done loading. + JvSynchronize sync (klass); - // record which is the defining loader - klass->loader = this; + // Record the defining loader. For the system class loader, we + // record NULL. + if (this != java::lang::ClassLoader::getSystemClassLoader()) + klass->loader = this; - // register that we are the initiating loader... if (name != 0) { - _Jv_Utf8Const * name2 = _Jv_makeUtf8Const (name); + _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name); if (! _Jv_VerifyClassName (name2)) throw new java::lang::ClassFormatError @@ -86,16 +87,8 @@ java::lang::ClassLoader::defineClass0 (jstring name, _Jv_UnregisterClass (klass); - _Jv_MonitorExit (klass); - - // FIXME: Here we may want to test that EX does - // indeed represent a valid exception. That is, - // anything but ClassNotFoundException, - // or some kind of Error. - - // FIXME: Rewrite this as a cleanup instead of - // as a catch handler. - + // If EX is not a ClassNotFoundException, that's ok, because we + // account for the possibility in defineClass(). throw ex; } @@ -104,10 +97,6 @@ java::lang::ClassLoader::defineClass0 (jstring name, // if everything proceeded sucessfully, we're loaded. JvAssert (klass->state == JV_STATE_LOADED); - // if an exception is generated, this is initially missed. - // however, we come back here in handleException0 below... - _Jv_MonitorExit (klass); - return klass; #else // INTERPRETER @@ -293,10 +282,11 @@ _Jv_PrepareCompiledClass (jclass klass) // Hash function for Utf8Consts. #define HASH_UTF(Utf) (((Utf)->hash) % HASH_LEN) -struct _Jv_LoaderInfo { - _Jv_LoaderInfo *next; - java::lang::Class *klass; - java::lang::ClassLoader *loader; +struct _Jv_LoaderInfo +{ + _Jv_LoaderInfo *next; + java::lang::Class *klass; + java::lang::ClassLoader *loader; }; static _Jv_LoaderInfo *initiated_classes[HASH_LEN]; @@ -309,9 +299,12 @@ static jclass loaded_classes[HASH_LEN]; jclass _Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) { - _Jv_MonitorEnter (&java::lang::Class::class$); + JvSynchronize sync (&java::lang::Class::class$); jint hash = HASH_UTF (name); + if (loader && loader == java::lang::ClassLoader::getSystemClassLoader()) + loader = NULL; + // first, if LOADER is a defining loader, then it is also initiating jclass klass; for (klass = loaded_classes[hash]; klass; klass = klass->next) @@ -337,15 +330,13 @@ _Jv_FindClassInCache (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) } } - _Jv_MonitorExit (&java::lang::Class::class$); - return klass; } void _Jv_UnregisterClass (jclass the_class) { - _Jv_MonitorEnter (&java::lang::Class::class$); + JvSynchronize sync (&java::lang::Class::class$); jint hash = HASH_UTF(the_class->name); jclass *klass = &(loaded_classes[hash]); @@ -363,29 +354,32 @@ _Jv_UnregisterClass (jclass the_class) { while (*info && (*info)->klass == the_class) { + _Jv_LoaderInfo *old = *info; *info = (*info)->next; + _Jv_Free (old); } if (*info == NULL) break; } - - _Jv_MonitorExit (&java::lang::Class::class$); } void _Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) { - // non-gc alloc! - _Jv_LoaderInfo *info = (_Jv_LoaderInfo *) _Jv_Malloc (sizeof(_Jv_LoaderInfo)); + if (loader && loader == java::lang::ClassLoader::getSystemClassLoader()) + loader = NULL; + + // This information can't be visible to the GC. + _Jv_LoaderInfo *info + = (_Jv_LoaderInfo *) _Jv_Malloc (sizeof(_Jv_LoaderInfo)); jint hash = HASH_UTF(klass->name); - _Jv_MonitorEnter (&java::lang::Class::class$); + JvSynchronize sync (&java::lang::Class::class$); info->loader = loader; info->klass = klass; info->next = initiated_classes[hash]; initiated_classes[hash] = info; - _Jv_MonitorExit (&java::lang::Class::class$); } // This function is called many times during startup, before main() is @@ -471,6 +465,9 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) { jstring sname = _Jv_NewStringUTF (name->data); + java::lang::ClassLoader *sys + = java::lang::ClassLoader::getSystemClassLoader (); + if (loader) { // Load using a user-defined loader, jvmspec 5.3.2 @@ -479,14 +476,14 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader) // If "loader" delegated the loadClass operation to another // loader, explicitly register that it is also an initiating // loader of the given class. - if (klass && (klass->getClassLoader () != loader)) + java::lang::ClassLoader *delegate = (loader == sys + ? NULL + : loader); + if (klass && klass->getClassLoaderInternal () != delegate) _Jv_RegisterInitiatingLoader (klass, loader); } else { - java::lang::ClassLoader *sys - = java::lang::ClassLoader::getSystemClassLoader (); - // Load using the bootstrap loader jvmspec 5.3.1. klass = sys->loadClass (sname, false); diff --git a/libjava/java/lang/reflect/Modifier.java b/libjava/java/lang/reflect/Modifier.java index 75d0c9b..8171a88 100644 --- a/libjava/java/lang/reflect/Modifier.java +++ b/libjava/java/lang/reflect/Modifier.java @@ -1,5 +1,5 @@ /* java.lang.reflect.Modifier - Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -158,6 +158,17 @@ public class Modifier static final int ALL_FLAGS = 0xfff; /** + * GCJ-LOCAL: This access flag is set on methods we declare + * internally but which must not be visible to reflection. + */ + static final int INVISIBLE = 0x1000; + + /** + * GCJ-LOCAL: This access flag is set on interpreted classes. + */ + static final int INTERPRETED = 0x1000; + + /** * Check whether the given modifier is abstract. * @param mod the modifier. * @return <code>true</code> if abstract, <code>false</code> otherwise. |