diff options
author | Andrew Haley <aph@redhat.com> | 2002-12-03 13:50:05 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2002-12-03 13:50:05 +0000 |
commit | 421f9e6091ca35352c825e7ec69439b3651da021 (patch) | |
tree | 635e8205b478433021057fc6be1683b642acf907 /libjava | |
parent | ee7ecb2924a9995adc324905836cd7207ce43747 (diff) | |
download | gcc-421f9e6091ca35352c825e7ec69439b3651da021.zip gcc-421f9e6091ca35352c825e7ec69439b3651da021.tar.gz gcc-421f9e6091ca35352c825e7ec69439b3651da021.tar.bz2 |
natClassLoader.cc (_Jv_PrepareCompiledClass): Call _Jv_PushClass.
2002-12-03 Andrew Haley <aph@redhat.com>
* java/lang/natClassLoader.cc (_Jv_PrepareCompiledClass): Call
_Jv_PushClass.
(_Jv_InitNewClassFields): Set protectionDomain and chain = NULL.
(_Jv_PopClass): New.
(_Jv_PushClass): New.
* java/lang/natClass.cc (forName (jstring)): Use a StackTrace to
discover the ClassLoader of our caller.
(_Jv_CheckArrayStore): Don't check that a class is assignment
compatible with Object.
* java/lang/natVMTHrowable.cc: Delete.
* gnu/gcj/runtime/StackTrace.java: New, partly copied from
java.lang.VMThrowable.
(StackTrace(), StackTrace(int)): New constructors.
(classAt, methodAt, update, methodAtAddress): New methods.
(map): New field.
* java/lang/VMThrowable.java: Use StackTrace instead of
natVMTHrowable.
* java/lang/Class.h (getClassLoaderInternal): New.
(class Class): Be friendly with _Jv_PopClass and _Jv_PushClass.
Be friendly with gnu::gcj::runtime::StackTrace.
(Object.chain): New field.
* include/java-interp.h (class _Jv_InterpMethod): Be friendly with
gnu::gcj::runtime::StackTrace.
* prims.cc (_Jv_NewObjectArray): Use getClassLoaderInternal()
instead of getClassLoader().
* verify.cc (class _Jv_BytecodeVerifier): Likewise.
java::lang::VMThrowable.
* Makefile.am (core_java_source_files): Add MethodRef.java,
StackTrace.java.
(nat_source_files): Remove natVMThrowable.cc; add natStackTrace.cc.
* Makefile.in: Rebuild.
2002-12-03 Andrew Haley <aph@redhat.com>
* class.c (make_class_data): New field, "chain".
* decl.c (java_init_decl_processing): Likewise.
From-SVN: r59769
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/Makefile.am | 4 | ||||
-rw-r--r-- | libjava/Makefile.in | 44 | ||||
-rw-r--r-- | libjava/include/java-interp.h | 2 | ||||
-rw-r--r-- | libjava/java/lang/Class.h | 13 | ||||
-rw-r--r-- | libjava/java/lang/VMThrowable.java | 26 | ||||
-rw-r--r-- | libjava/java/lang/natClass.cc | 26 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 32 | ||||
-rw-r--r-- | libjava/prims.cc | 10 | ||||
-rw-r--r-- | libjava/verify.cc | 6 |
9 files changed, 124 insertions, 39 deletions
diff --git a/libjava/Makefile.am b/libjava/Makefile.am index 34135e7..9c7eb96 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -1720,8 +1720,10 @@ gnu/gcj/runtime/FileDeleter.java \ 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 \ @@ -2316,6 +2318,7 @@ gnu/gcj/runtime/natFinalizerThread.cc \ 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 \ @@ -2334,7 +2337,6 @@ java/lang/natString.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 \ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 239bd09..994002e 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -1470,8 +1470,10 @@ gnu/gcj/runtime/FileDeleter.java \ 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 \ @@ -2065,6 +2067,7 @@ gnu/gcj/runtime/natFinalizerThread.cc \ 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 \ @@ -2083,7 +2086,6 @@ java/lang/natString.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 \ @@ -2234,22 +2236,22 @@ gnu/gcj/convert/natOutput_SJIS.lo gnu/gcj/io/natSimpleSHSStream.lo \ 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 \ @@ -2349,14 +2351,15 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .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 \ @@ -2956,9 +2959,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.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 \ diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h index e3f9671..ef2b520 100644 --- a/libjava/include/java-interp.h +++ b/libjava/include/java-interp.h @@ -21,6 +21,7 @@ details. */ #include <java/lang/Class.h> #include <java/lang/ClassLoader.h> +#include <gnu/gcj/runtime/StackTrace.h> extern "C" { #include <ffi.h> @@ -140,6 +141,7 @@ class _Jv_InterpMethod : public _Jv_MethodBase 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); }; diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index bd2903d..6fb918a 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -20,6 +20,7 @@ details. */ #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); @@ -138,6 +139,13 @@ public: 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> *); @@ -296,6 +304,8 @@ private: 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); @@ -349,6 +359,7 @@ private: #endif friend class _Jv_BytecodeVerifier; + friend class gnu::gcj::runtime::StackTrace; // Chain for class pool. jclass next; @@ -403,6 +414,8 @@ private: 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__ */ diff --git a/libjava/java/lang/VMThrowable.java b/libjava/java/lang/VMThrowable.java index 0a2c922..4c33857 100644 --- a/libjava/java/lang/VMThrowable.java +++ b/libjava/java/lang/VMThrowable.java @@ -38,9 +38,10 @@ exception statement from your version. */ 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> @@ -50,8 +51,7 @@ import gnu.gcj.runtime.NameFinder; */ final class VMThrowable { - private gnu.gcj.RawData stackTraceAddrs; - private int length; + private gnu.gcj.runtime.StackTrace trace; /** * Private contructor, create VMThrowables with fillInStackTrace(); @@ -67,7 +67,20 @@ final class VMThrowable * @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 @@ -80,10 +93,11 @@ final class VMThrowable 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 diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index fb412f2..68fbd54 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -36,6 +36,7 @@ details. */ #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> @@ -47,7 +48,10 @@ details. */ #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> @@ -71,7 +75,6 @@ java::lang::Class::forName (jstring className, jboolean initialize, 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)); @@ -88,8 +91,23 @@ java::lang::Class::forName (jstring className, jboolean initialize, 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 * @@ -1040,6 +1058,8 @@ _Jv_CheckArrayStore (jobject arr, jobject obj) { 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)) diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc index 8bff169..debcb4f 100644 --- a/libjava/java/lang/natClassLoader.cc +++ b/libjava/java/lang/natClassLoader.cc @@ -326,6 +326,8 @@ _Jv_PrepareCompiledClass (jclass klass) _Jv_LinkOffsetTable(klass); klass->notifyAll (); + + _Jv_PushClass (klass); } @@ -587,6 +589,8 @@ _Jv_InitNewClassFields (jclass ret) ret->ancestors = NULL; ret->idt = NULL; ret->arrayclass = NULL; + ret->protectionDomain = NULL; + ret->chain = NULL; } jclass @@ -732,3 +736,31 @@ _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. + +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; +} diff --git a/libjava/prims.cc b/libjava/prims.cc index 76c2587..9244587 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -458,8 +458,8 @@ _Jv_NewObjectArray (jsize count, jclass elementClass, jobject init) 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. @@ -920,11 +920,11 @@ _Jv_CreateJavaVM (void* /*vm_args*/) 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 diff --git a/libjava/verify.cc b/libjava/verify.cc index dc88944..dbf80d4 100644 --- a/libjava/verify.cc +++ b/libjava/verify.cc @@ -405,7 +405,7 @@ private: 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] == ';') @@ -571,7 +571,7 @@ private: 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()"); } @@ -695,7 +695,7 @@ private: while (arraycount > 0) { java::lang::ClassLoader *loader - = verifier->current_class->getClassLoader(); + = verifier->current_class->getClassLoaderInternal(); k = _Jv_GetArrayClass (k, loader); --arraycount; } |