natClassLoader.cc (defineClass0): Removed erroneous comment.

* java/lang/natClassLoader.cc (defineClass0): Removed erroneous
	comment.
	* java/lang/ClassLoader.java (defineClass): Use chained
	exception when rethrowing.
	* defineclass.cc (handleClassBegin): Mark class as interpreted.
	* java/lang/reflect/Modifier.java (INVISIBLE, INTERPRETED): New
	constants.
	* resolve.cc (_Jv_PrepareMissingMethods): New function.
	(_Jv_PrepareClass): Use it.
	* include/java-interp.h (_Jv_IsInterpretedClass): Rewrote.
	(_Jv_InterpClass): _Jv_PrepareMissingMethods now friend.
	* java/lang/Class.h (Class::getModifiers): Mask with ALL_FLAGS.
	(Class): _Jv_PrepareMissingMethods now friend.
	* java/lang/natClassLoader.cc (defineClass0): Use JvSynchronize.
	Record `NULL' for system class loader.
	(_Jv_RegisterInitiatingLoader): Use JvSynchronize.  Special case
	system class loader.
	(_Jv_FindClassInCache): Likewise.
	(_Jv_UnregisterClass): Use JvSynchronize.  Free old loader info.
	(_Jv_FindClass): Special case system class loader.
	* java/lang/natClass.cc (_Jv_abstractMethodError): New function.
	(_Jv_SetVTableEntries): Put _Jv_abstractMethodError into empty
	vtable slots.
	(_Jv_LayoutVTableMethods): Don't generate vtable slot for a method
	in a final class.
	(_getDeclaredMethod): Don't return synthetic methods.
	(getDeclaredMethods): Likewise.
	(_getMethod): Likewise.
	(_getMethods): Likewise.

From-SVN: r60319
This commit is contained in:
Tom Tromey 2002-12-19 19:31:55 +00:00 committed by Tom Tromey
parent 385405940e
commit a1aba4f9a5
11 changed files with 221 additions and 96 deletions

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);

View file

@ -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.
@ -157,6 +157,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.