From ab469b6587db979cdb734d8c7119c55589847b29 Mon Sep 17 00:00:00 2001 From: Pavel Afremov Date: Tue, 29 May 2007 18:34:56 +0400 Subject: [PATCH] First version of class unloading support in lazy stack creation. This version prevents class unloading if there is any stored exception. In Throwable class implementation array of java.lang.Class was added. This array contains classes of each method on the stack. --- .../javasrc/java/lang/Throwable.java | 9 +++- .../javasrc/org/apache/harmony/vm/VMStack.java | 24 +++++++++- .../native/org_apache_harmony_vm_VMStack.cpp | 47 +++++++++++++++++++- .../native/org_apache_harmony_vm_VMStack.h | 7 +++ 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/vm/vmcore/src/kernel_classes/javasrc/java/lang/Throwable.java b/vm/vmcore/src/kernel_classes/javasrc/java/lang/Throwable.java index fd418c5..b6d157d 100644 --- a/vm/vmcore/src/kernel_classes/javasrc/java/lang/Throwable.java +++ b/vm/vmcore/src/kernel_classes/javasrc/java/lang/Throwable.java @@ -41,8 +41,10 @@ public class Throwable implements Serializable { private final String detailMessage; private StackTraceElement[] stackTrace; - - private transient Object state; + + private transient Class [] stackClasses; + + private transient Object state; /** * @com.intel.drl.spec_ref @@ -80,6 +82,7 @@ public class Throwable implements Serializable { */ public Throwable fillInStackTrace() { state = VMStack.getStackState(); + stackClasses = VMStack.getStackClasses(state); return this; } @@ -110,6 +113,8 @@ public class Throwable implements Serializable { public StackTraceElement[] getStackTrace() { if (stackTrace == null) { stackTrace = VMStack.getStackTrace(state); + state = null; + stackClasses = null; } StackTraceElement[] st = new StackTraceElement[stackTrace.length]; System.arraycopy(stackTrace, 0, st, 0, stackTrace.length); diff --git a/vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/vm/VMStack.java b/vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/vm/VMStack.java index 35101eb..65320a2 100644 --- a/vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/vm/VMStack.java +++ b/vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/vm/VMStack.java @@ -88,7 +88,27 @@ public final class VMStack { * @return handler of the current stack. */ public static native Object getStackState(); - + + /** + * Collects and returns the classes of invoked methods as an array of the + * {@link Class} objects. This method may be used by + * java.lang.Throwable class implementation. + *

+ * Resulting stack should contain native stack frames as well as reflection + * stack frames. + *

+ * Note, that it returns classes for all stack, without any checks. + * It's fast, simple version of {@link VMStack#getClasses() VMStack.getClasses()} + * method, and used from Throwable class implementation. + * + * @param state handler returned by the + * {@link VMStack#getStackState() VMStack.getStackState()} method. + * @return array of Class elements. If stack is + * empty then null should be returned. + * @api2vm + */ + public static native Class[] getStackClasses(Object state); + /** * Collects and returns the stack of invoked methods as an array of the * {@link StackTraceElement} objects. This method may be used by @@ -108,7 +128,7 @@ public final class VMStack { * @api2vm */ public static native StackTraceElement[] getStackTrace(Object state); - + /** * This method does exactly the same things as the * {@link VMClassRegistry#getClassLoader(Class) diff --git a/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp b/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp index 39594d8..9f1908f 100644 --- a/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp +++ b/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp @@ -241,7 +241,6 @@ Java_java_security_AccessController_getStackDomains(JNIEnv *jenv, jclass UNREF) return arr; } - /* * Class: org_apache_harmony_vm_VMStack * Method: getStackState @@ -277,6 +276,52 @@ JNIEXPORT jobject JNICALL Java_org_apache_harmony_vm_VMStack_getStackState /* * Class: org_apache_harmony_vm_VMStack + * Method: getStackClasses + * Signature: (Ljava/lang/Object;)[Ljava/lang/Class; + */ +JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_vm_VMStack_getStackClasses + (JNIEnv *jenv, jclass, jobject state) +{ + ASSERT_RAISE_AREA; + if (NULL == state) + return NULL; + + Global_Env* genv = jni_get_vm_env(jenv); + + // state object contains raw data as long array + jlongArray array = (jlongArray)state; + assert(array); + + // copy data to array + jlong* array_data = jenv->GetLongArrayElements(array, NULL); + + // get depth of the stack + StackTraceFrame* frames = (StackTraceFrame*) array_data; + unsigned size = jenv->GetArrayLength(array) * 8 / sizeof(StackTraceFrame); + + // get class array class + jclass cac = struct_Class_to_java_lang_Class_Handle(genv->JavaLangClass_Class); + assert(cac); + + // create java array + jobjectArray arr = jenv->NewObjectArray(size, cac, NULL); + if (arr == NULL) { + return NULL; + } + + // find and store classes of the methods on the stack + for (unsigned i=0; i < size; i++) { + Method* m = frames[i].method; + Class* c = m->get_class(); + jclass jc = struct_Class_to_java_lang_Class_Handle(c); + jenv->SetObjectArrayElement(arr, i, jc); + } + + return arr; +} + +/* + * Class: org_apache_harmony_vm_VMStack * Method: getStackTrace * Signature: (Ljava/lang/Object;)[Ljava/lang/StackTraceElement; */ diff --git a/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.h b/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.h index 643c700..8018a31 100644 --- a/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.h +++ b/vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.h @@ -62,6 +62,13 @@ JNIEXPORT jobject JNICALL Java_org_apache_harmony_vm_VMStack_getStackState(JNIEnv *, jclass); /* + * Method: org.apache.harmony.vm.VMStack.getStackClasse(Ljava/lang/Object;)[Ljava/lang/Class + */ +JNIEXPORT jobjectArray JNICALL +Java_org_apache_harmony_vm_VMStack_getStackClasses(JNIEnv *, jclass, + jobject); + +/* * Method: org.apache.harmony.vm.VMStack.getStackTrace(Ljava/lang/Object;)[Ljava/lang/StackTraceElement; */ JNIEXPORT jobjectArray JNICALL -- 1.5.0.3