* Merged gcj-abi-2-dev-branch to trunk.

(Actual changes too large to list in the commit message;
see ChangeLog.)

From-SVN: r91270
This commit is contained in:
Tom Tromey 2004-11-25 03:47:08 +00:00
parent ec0641f612
commit 367390404d
70 changed files with 11301 additions and 3355 deletions

View file

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