+2002-12-03 Andrew Haley <aph@redhat.com>
+
+ * class.c (make_class_data): New field, "chain".
+ * decl.c (java_init_decl_processing): Likewise.
+
2002-12-02 Tom Tromey <tromey@redhat.com>
For PR java/8740:
PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
PUSH_FIELD_VALUE (cons, "arrayclass", null_pointer_node);
PUSH_FIELD_VALUE (cons, "protectionDomain", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "chain", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (cons);
PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);
PUSH_FIELD (class_type_node, field, "arrayclass", ptr_type_node);
PUSH_FIELD (class_type_node, field, "protectionDomain", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "chain", ptr_type_node);
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
push_super_field (class_type_node, object_type_node);
gnu/gcj/runtime/FinalizerThread.java \
gnu/gcj/runtime/FirstThread.java \
gnu/gcj/runtime/JNIWeakRef.java \
+gnu/gcj/runtime/MethodRef.java \
gnu/gcj/runtime/NameFinder.java \
gnu/gcj/runtime/SharedLibLoader.java \
+gnu/gcj/runtime/StackTrace.java \
gnu/gcj/runtime/StringBuffer.java \
gnu/gcj/runtime/VMClassLoader.java \
gnu/java/io/ClassLoaderObjectInputStream.java \
gnu/gcj/runtime/natFirstThread.cc \
gnu/gcj/runtime/natNameFinder.cc \
gnu/gcj/runtime/natSharedLibLoader.cc \
+gnu/gcj/runtime/natStackTrace.cc \
gnu/gcj/runtime/natStringBuffer.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
java/lang/natStringBuffer.cc \
java/lang/natSystem.cc \
java/lang/natThread.cc \
-java/lang/natVMThrowable.cc \
java/lang/ref/natReference.cc \
java/lang/reflect/natArray.cc \
java/lang/reflect/natConstructor.cc \
gnu/gcj/runtime/FinalizerThread.java \
gnu/gcj/runtime/FirstThread.java \
gnu/gcj/runtime/JNIWeakRef.java \
+gnu/gcj/runtime/MethodRef.java \
gnu/gcj/runtime/NameFinder.java \
gnu/gcj/runtime/SharedLibLoader.java \
+gnu/gcj/runtime/StackTrace.java \
gnu/gcj/runtime/StringBuffer.java \
gnu/gcj/runtime/VMClassLoader.java \
gnu/java/io/ClassLoaderObjectInputStream.java \
gnu/gcj/runtime/natFirstThread.cc \
gnu/gcj/runtime/natNameFinder.cc \
gnu/gcj/runtime/natSharedLibLoader.cc \
+gnu/gcj/runtime/natStackTrace.cc \
gnu/gcj/runtime/natStringBuffer.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
java/lang/natStringBuffer.cc \
java/lang/natSystem.cc \
java/lang/natThread.cc \
-java/lang/natVMThrowable.cc \
java/lang/ref/natReference.cc \
java/lang/reflect/natArray.cc \
java/lang/reflect/natConstructor.cc \
gnu/gcj/io/shs.lo gnu/gcj/protocol/core/natCoreInputStream.lo \
gnu/gcj/runtime/natFinalizerThread.lo gnu/gcj/runtime/natFirstThread.lo \
gnu/gcj/runtime/natNameFinder.lo gnu/gcj/runtime/natSharedLibLoader.lo \
-gnu/gcj/runtime/natStringBuffer.lo java/io/natFile.lo \
-java/io/natFileDescriptor.lo java/io/natObjectInputStream.lo \
-java/io/natObjectOutputStream.lo java/lang/natCharacter.lo \
-java/lang/natClass.lo java/lang/natClassLoader.lo \
-java/lang/natConcreteProcess.lo java/lang/natDouble.lo \
-java/lang/natFloat.lo java/lang/natMath.lo java/lang/natObject.lo \
-java/lang/natRuntime.lo java/lang/natString.lo \
+gnu/gcj/runtime/natStackTrace.lo gnu/gcj/runtime/natStringBuffer.lo \
+java/io/natFile.lo java/io/natFileDescriptor.lo \
+java/io/natObjectInputStream.lo java/io/natObjectOutputStream.lo \
+java/lang/natCharacter.lo java/lang/natClass.lo \
+java/lang/natClassLoader.lo java/lang/natConcreteProcess.lo \
+java/lang/natDouble.lo java/lang/natFloat.lo java/lang/natMath.lo \
+java/lang/natObject.lo java/lang/natRuntime.lo java/lang/natString.lo \
java/lang/natStringBuffer.lo java/lang/natSystem.lo \
-java/lang/natThread.lo java/lang/natVMThrowable.lo \
-java/lang/ref/natReference.lo java/lang/reflect/natArray.lo \
-java/lang/reflect/natConstructor.lo java/lang/reflect/natField.lo \
-java/lang/reflect/natMethod.lo java/lang/reflect/natProxy.lo \
-java/net/natNetworkInterface.lo java/net/natInetAddress.lo \
-java/net/natPlainDatagramSocketImpl.lo java/net/natPlainSocketImpl.lo \
-java/text/natCollator.lo java/util/natTimeZone.lo \
-java/util/zip/natDeflater.lo java/util/zip/natInflater.lo
+java/lang/natThread.lo java/lang/ref/natReference.lo \
+java/lang/reflect/natArray.lo java/lang/reflect/natConstructor.lo \
+java/lang/reflect/natField.lo java/lang/reflect/natMethod.lo \
+java/lang/reflect/natProxy.lo java/net/natNetworkInterface.lo \
+java/net/natInetAddress.lo java/net/natPlainDatagramSocketImpl.lo \
+java/net/natPlainSocketImpl.lo java/text/natCollator.lo \
+java/util/natTimeZone.lo java/util/zip/natDeflater.lo \
+java/util/zip/natInflater.lo
libgcjx_la_OBJECTS = gnu/gcj/xlib/natClip.lo \
gnu/gcj/xlib/natColormap.lo gnu/gcj/xlib/natDisplay.lo \
gnu/gcj/xlib/natDrawable.lo gnu/gcj/xlib/natFont.lo \
.deps/gnu/gcj/runtime/FileDeleter.P \
.deps/gnu/gcj/runtime/FinalizerThread.P \
.deps/gnu/gcj/runtime/FirstThread.P .deps/gnu/gcj/runtime/JNIWeakRef.P \
-.deps/gnu/gcj/runtime/NameFinder.P \
+.deps/gnu/gcj/runtime/MethodRef.P .deps/gnu/gcj/runtime/NameFinder.P \
.deps/gnu/gcj/runtime/SharedLibLoader.P \
-.deps/gnu/gcj/runtime/StringBuffer.P \
+.deps/gnu/gcj/runtime/StackTrace.P .deps/gnu/gcj/runtime/StringBuffer.P \
.deps/gnu/gcj/runtime/VMClassLoader.P \
.deps/gnu/gcj/runtime/natFinalizerThread.P \
.deps/gnu/gcj/runtime/natFirstThread.P \
.deps/gnu/gcj/runtime/natNameFinder.P \
.deps/gnu/gcj/runtime/natSharedLibLoader.P \
+.deps/gnu/gcj/runtime/natStackTrace.P \
.deps/gnu/gcj/runtime/natStringBuffer.P .deps/gnu/gcj/xlib/Clip.P \
.deps/gnu/gcj/xlib/Colormap.P .deps/gnu/gcj/xlib/Display.P \
.deps/gnu/gcj/xlib/Drawable.P .deps/gnu/gcj/xlib/Font.P \
.deps/java/lang/natMath.P .deps/java/lang/natObject.P \
.deps/java/lang/natRuntime.P .deps/java/lang/natString.P \
.deps/java/lang/natStringBuffer.P .deps/java/lang/natSystem.P \
-.deps/java/lang/natThread.P .deps/java/lang/natVMThrowable.P \
-.deps/java/lang/ref/PhantomReference.P .deps/java/lang/ref/Reference.P \
-.deps/java/lang/ref/ReferenceQueue.P \
+.deps/java/lang/natThread.P .deps/java/lang/ref/PhantomReference.P \
+.deps/java/lang/ref/Reference.P .deps/java/lang/ref/ReferenceQueue.P \
.deps/java/lang/ref/SoftReference.P .deps/java/lang/ref/WeakReference.P \
.deps/java/lang/ref/natReference.P \
.deps/java/lang/reflect/AccessibleObject.P \
#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
+#include <gnu/gcj/runtime/StackTrace.h>
extern "C" {
#include <ffi.h>
friend class _Jv_ClassReader;
friend class _Jv_BytecodeVerifier;
friend class gnu::gcj::runtime::NameFinder;
+ friend class gnu::gcj::runtime::StackTrace;
friend void _Jv_PrepareClass(jclass);
};
#include <java/lang/reflect/Modifier.h>
#include <java/security/ProtectionDomain.h>
#include <java/lang/Package.h>
+#include <gnu/gcj/runtime/StackTrace.h>
// We declare these here to avoid including gcj/cni.h.
extern "C" void _Jv_InitClass (jclass klass);
java::lang::ClassLoader *getClassLoader (void);
+ // This is an internal method that circumvents the usual security
+ // checks when getting the class loader.
+ java::lang::ClassLoader *getClassLoaderInternal (void)
+ {
+ return loader;
+ }
+
java::lang::reflect::Constructor *getConstructor (JArray<jclass> *);
JArray<java::lang::reflect::Constructor *> *getConstructors (void);
java::lang::reflect::Constructor *getDeclaredConstructor (JArray<jclass> *);
java::lang::ClassLoader *loader);
friend jclass _Jv_FindClassInCache (_Jv_Utf8Const *name,
java::lang::ClassLoader *loader);
+ friend jclass _Jv_PopClass (void);
+ friend void _Jv_PushClass (jclass k);
friend void _Jv_NewArrayClass (jclass element,
java::lang::ClassLoader *loader,
_Jv_VTable *array_vtable = 0);
#endif
friend class _Jv_BytecodeVerifier;
+ friend class gnu::gcj::runtime::StackTrace;
// Chain for class pool.
jclass next;
jclass arrayclass;
// Security Domain to which this class belongs (or null).
java::security::ProtectionDomain *protectionDomain;
+ // Used by Jv_PopClass and _Jv_PushClass to communicate with StackTrace.
+ jclass chain;
};
#endif /* __JAVA_LANG_CLASS_H__ */
package java.lang;
import gnu.gcj.runtime.NameFinder;
+import gnu.gcj.runtime.StackTrace;
/**
- * VM dependant state and support methods Throwabele.
+ * VM dependent state and support methods Throwable.
* It is deliberately package local and final and should only be accessed
* by the Throwable class.
* <p>
*/
final class VMThrowable
{
- private gnu.gcj.RawData stackTraceAddrs;
- private int length;
+ private gnu.gcj.runtime.StackTrace trace;
/**
* Private contructor, create VMThrowables with fillInStackTrace();
* @return a new VMThrowable containing the current execution stack trace.
* @see Throwable#fillInStackTrace()
*/
- static native VMThrowable fillInStackTrace(Throwable t);
+ static VMThrowable fillInStackTrace(Throwable t)
+ {
+ VMThrowable state = null;
+
+ /* FIXME: size of the stack trace is limited to 128 elements.
+ It's undoubtedly sensible to limit the stack trace, but 128 is
+ rather arbitrary. It may be better to configure this. */
+ if (trace_enabled)
+ {
+ state = new VMThrowable ();
+ state.trace = new gnu.gcj.runtime.StackTrace(128);
+ }
+ return state;
+ }
/**
* Returns an <code>StackTraceElement</code> array based on the execution
StackTraceElement[] getStackTrace(Throwable t)
{
StackTraceElement[] result;
- if (stackTraceAddrs != null)
+ if (trace != null)
{
NameFinder nameFinder = new NameFinder();
- result = nameFinder.lookup(t, stackTraceAddrs, length);
+ result = nameFinder.lookup(t, trace.stackTraceAddrs(),
+ trace.length());
nameFinder.close();
}
else
#include <java/lang/IllegalAccessError.h>
#include <java/lang/IllegalArgumentException.h>
#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/InstantiationException.h>
#include <java/lang/NoClassDefFoundError.h>
#include <java/lang/NoSuchFieldException.h>
#include <java/lang/System.h>
#include <java/lang/SecurityManager.h>
#include <java/lang/StringBuffer.h>
+#include <gnu/gcj/runtime/StackTrace.h>
#include <gcj/method.h>
+#include <gnu/gcj/runtime/MethodRef.h>
+#include <gnu/gcj/RawData.h>
#include <java-cpool.h>
if (! _Jv_VerifyClassName (name))
throw new java::lang::ClassNotFoundException (className);
- // FIXME: should use bootstrap class loader if loader is null.
jclass klass = (buffer[0] == '['
? _Jv_FindClassFromSignature (name->data, loader)
: _Jv_FindClass (name, loader));
jclass
java::lang::Class::forName (jstring className)
{
- // FIXME: should use class loader from calling method.
- return forName (className, true, NULL);
+ java::lang::ClassLoader *loader = NULL;
+ gnu::gcj::runtime::StackTrace *t
+ = new gnu::gcj::runtime::StackTrace(4);
+ java::lang::Class *klass = NULL;
+ try
+ {
+ for (int i=1; !klass; i++)
+ {
+ klass = t->classAt (i);
+ }
+ loader = klass->getClassLoader();
+ }
+ catch (::java::lang::ArrayIndexOutOfBoundsException *e)
+ {
+ }
+
+ return forName (className, true, loader);
}
java::lang::ClassLoader *
{
JvAssert (arr != NULL);
jclass elt_class = (JV_CLASS (arr))->getComponentType();
+ if (elt_class == &java::lang::Object::class$)
+ return;
jclass obj_class = JV_CLASS (obj);
if (__builtin_expect
(! _Jv_IsAssignableFrom (elt_class, obj_class), false))
_Jv_LinkOffsetTable(klass);
klass->notifyAll ();
+
+ _Jv_PushClass (klass);
}
ret->ancestors = NULL;
ret->idt = NULL;
ret->arrayclass = NULL;
+ ret->protectionDomain = NULL;
+ ret->chain = NULL;
}
jclass
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.
+
+jclass
+_Jv_PopClass (void)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ if (stack_head)
+ {
+ jclass tmp = stack_head;
+ stack_head = tmp->chain;
+ return tmp;
+ }
+ return NULL;
+}
+
+void
+_Jv_PushClass (jclass k)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ jclass tmp = stack_head;
+ stack_head = k;
+ k->chain = tmp;
+}
size_t size = (size_t) elements (obj);
size += count * sizeof (jobject);
- // FIXME: second argument should be "current loader"
- jclass klass = _Jv_GetArrayClass (elementClass, 0);
+ jclass klass = _Jv_GetArrayClass (elementClass,
+ elementClass->getClassLoaderInternal());
obj = (jobjectArray) _Jv_AllocArray (size, klass);
// Cast away const.
arithexception = new java::lang::ArithmeticException
(JvNewStringLatin1 ("/ by zero"));
#endif
-
+
no_memory = new java::lang::OutOfMemoryError;
-
+
java::lang::VMThrowable::trace_enabled = 1;
-
+
#ifdef USE_LTDL
LTDL_SET_PRELOADED_SYMBOLS ();
#endif
using namespace java::lang;
java::lang::ClassLoader *loader
- = verifier->current_class->getClassLoader();
+ = verifier->current_class->getClassLoaderInternal();
// We might see either kind of name. Sigh.
if (data.name->data[0] == 'L'
&& data.name->data[data.name->length - 1] == ';')
if (key == reference_type)
return type (_Jv_GetArrayClass (data.klass,
- data.klass->getClassLoader ()));
+ data.klass->getClassLoaderInternal()));
else
verifier->verify_fail ("internal error in type::to_array()");
}
while (arraycount > 0)
{
java::lang::ClassLoader *loader
- = verifier->current_class->getClassLoader();
+ = verifier->current_class->getClassLoaderInternal();
k = _Jv_GetArrayClass (k, loader);
--arraycount;
}