* src/vm/jit/stacktrace.cpp
authorMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 10 Dec 2008 10:06:13 +0000 (11:06 +0100)
committerMichael Starzinger <michi@complang.tuwien.ac.at>
Wed, 10 Dec 2008 10:06:13 +0000 (11:06 +0100)
[ENABLE_JAVASE] (stacktrace_get_StackTraceElement): Added new function.
[ENABLE_JAVASE] (stacktrace_get_StackTraceElements): Likewise
[ENABLE_THREADS] (stacktrace_get_of_thread): Likewise (still bogus).
* src/vm/jit/stacktrace.hpp: Added prototypes for above functions.
* src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp: Use new functions.
* src/native/vm/openjdk/jvm.cpp (JVM_DumpThreads): Implemented.

src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp
src/native/vm/openjdk/jvm.cpp
src/vm/jit/stacktrace.cpp
src/vm/jit/stacktrace.hpp

index d62fe2926d48200e96df73bfec11f287184ebfc6..fca7f8d1d783d0b9396f820adfe3ddeac5983569 100644 (file)
@@ -101,66 +101,7 @@ JNIEXPORT jobjectArray JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *
 
        assert(st != NULL);
 
-       stacktrace_entry_t* ste = st->entries;
-
-       /* Create the stacktrace element array. */
-
-       java_handle_objectarray_t* oa = builtin_anewarray(st->length, class_java_lang_StackTraceElement);
-
-       if (oa == NULL)
-               return NULL;
-
-       for (int i = 0; i < st->length; i++, ste++) {
-               /* Get the codeinfo and methodinfo. */
-
-               codeinfo*   code = ste->code;
-               methodinfo* m    = code->m;
-
-               /* Get filename. */
-
-               java_handle_t* filename;
-
-               if (!(m->flags & ACC_NATIVE)) {
-                       if (m->clazz->sourcefile)
-                               filename = javastring_new(m->clazz->sourcefile);
-                       else
-                               filename = NULL;
-               }
-               else
-                       filename = NULL;
-
-               /* get line number */
-
-               int32_t linenumber;
-
-               if (m->flags & ACC_NATIVE) {
-                       linenumber = -1;
-               }
-               else {
-                       /* FIXME linenumbertable->find could change the methodinfo
-                          pointer when hitting an inlined method. */
-
-                       linenumber = code->linenumbertable->find(&m, ste->pc);
-                       linenumber = (linenumber == 0) ? -1 : linenumber;
-               }
-
-               /* get declaring class name */
-
-               java_handle_t* declaringclass = class_get_classname(m->clazz);
-
-               /* allocate a new stacktrace element */
-
-               java_handle_t* h = builtin_new(class_java_lang_StackTraceElement);
-
-               if (h == NULL)
-                       return NULL;
-
-               java_lang_StackTraceElement ste(h, filename, linenumber, declaringclass, javastring_new(m->name), ((m->flags & ACC_NATIVE) ? 1 : 0));
-
-               array_objectarray_element_set(oa, i, ste.get_handle());
-       }
-
-       return (jobjectArray) oa;
+       return stacktrace_get_StackTraceElements(st);
 }
 
 } // extern "C"
index c13f6ece6663709c966230e14039b0d905e524ad..d9079edff03cf5f5266b6e2806217a30b0a9a3b7 100644 (file)
@@ -435,64 +435,11 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
        java_lang_Throwable jlt(throwable);
        java_handle_bytearray_t* ba = jlt.get_backtrace();
 
-       // We need a critical section here as the stacktrace structure is
+       // XXX We need a critical section here as the stacktrace structure is
        // mapped onto a Java byte-array.
-       LLNI_CRITICAL_START;
-
        stacktrace_t* st = (stacktrace_t *) LLNI_array_data(ba);
 
-       if ((index < 0) || (index >= st->length)) {
-               /* XXX This should be an IndexOutOfBoundsException (check this
-                  again). */
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       // Get the stacktrace entry.
-       stacktrace_entry_t* ste = &(st->entries[index]);
-
-       // Get the codeinfo, methodinfo and classinfo.
-       codeinfo*   code = ste->code;
-       methodinfo* m    = code->m;
-       classinfo*  c    = m->clazz;
-
-       // Get filename.
-       java_handle_t* filename;
-
-       if (!(m->flags & ACC_NATIVE)) {
-               if (c->sourcefile != NULL)
-                       filename = javastring_new(c->sourcefile);
-               else
-                       filename = NULL;
-       }
-       else
-               filename = NULL;
-
-       // Get line number.
-       int32_t linenumber;
-
-       if (m->flags & ACC_NATIVE) {
-               linenumber = -2;
-       }
-       else {
-               // FIXME linenumbertable->find could change the methodinfo
-               // pointer when hitting an inlined method.
-               linenumber = code->linenumbertable->find(&m, ste->pc);
-               linenumber = (linenumber == 0) ? -1 : linenumber;
-       }
-
-       LLNI_CRITICAL_END;
-
-       // Get declaring class name.
-       java_handle_t* declaringclass = class_get_classname(c);
-
-       // Allocate a new StackTraceElement object.
-       java_lang_StackTraceElement jlste(declaringclass, javastring_new(m->name), filename, linenumber);
-
-       if (jlste.is_null())
-               return NULL;
-
-       return (jobject) jlste.get_handle();
+       return stacktrace_get_StackTraceElement(st, index);
 }
 
 
@@ -3235,9 +3182,54 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 
 jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
 {
-       log_println("JVM_DumpThreads: IMPLEMENT ME!");
+       int32_t i;
 
-       return NULL;
+       TRACEJVMCALLS(("JVM_DumpThreads((env=%p, threadClass=%p, threads=%p)", env, threadClass, threads));
+
+       if (threads == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       // Get length of the threads array.
+       int32_t length = array_length_get((java_handle_t*) threads);
+
+       if (length <= 0) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       // Allocate array to hold stacktraces.
+       classinfo* arrayclass = class_array_of(class_java_lang_StackTraceElement, true);
+       java_handle_objectarray_t* oas = builtin_anewarray(length, arrayclass);
+
+       if (oas == NULL) {
+               return NULL;
+       }
+
+       // Iterate over all passed thread objects.
+       for (i = 0; i < length; i++) {
+               java_handle_t* thread = array_objectarray_element_get(threads, i);
+
+               // Get thread for the given thread object.
+               threadobject* t = thread_get_thread(thread);
+
+               if (t == NULL)
+                       continue;
+
+               // Get stacktrace for given thread.
+               stacktrace_t* st = stacktrace_get_of_thread(t);
+
+               if (st == NULL)
+                       continue;
+
+               // Convert stacktrace into array of StackTraceElements.
+               java_handle_objectarray_t* oa = stacktrace_get_StackTraceElements(st);
+
+               array_objectarray_element_set(oas, i, (java_handle_t*) oa);
+       }
+
+       return oas;
 }
 
 
index 514c2fd08ae38809c1052e6f5b7baf8458bb8971..6d8d51d0c4e39a76a3c0c782f95c77e087172dfd 100644 (file)
@@ -674,6 +674,123 @@ java_handle_bytearray_t *stacktrace_get_current(void)
 }
 
 
+/**
+ * Creates a java.lang.StackTraceElement for one element of the given
+ * stacktrace.
+ *
+ * @param st Given stacktrace.
+ * @param index Index of element inside stacktrace.
+ * @return The filled StackTraceElement object.
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* stacktrace_get_StackTraceElement(stacktrace_t* st, int32_t index)
+{
+       if ((index < 0) || (index >= st->length)) {
+               /* XXX This should be an IndexOutOfBoundsException (check this
+                  again). */
+               exceptions_throw_arrayindexoutofboundsexception();
+               return NULL;
+       }
+
+       // Get the stacktrace entry.
+       stacktrace_entry_t* ste = &(st->entries[index]);
+
+       // Get the codeinfo, methodinfo and classinfo.
+       codeinfo*   code = ste->code;
+       methodinfo* m    = code->m;
+       classinfo*  c    = m->clazz;
+
+       // Get filename.
+       java_handle_t* filename;
+
+       if (!(m->flags & ACC_NATIVE)) {
+               if (c->sourcefile != NULL)
+                       filename = javastring_new(c->sourcefile);
+               else
+                       filename = NULL;
+       }
+       else
+               filename = NULL;
+
+       // Get line number.
+       int32_t linenumber;
+
+       if (m->flags & ACC_NATIVE) {
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+               linenumber = -1;
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+               linenumber = -2;
+#else
+# error unknown classpath configuration
+#endif
+       }
+       else {
+               // FIXME linenumbertable->find could change the methodinfo
+               // pointer when hitting an inlined method.
+               linenumber = code->linenumbertable->find(&m, ste->pc);
+               linenumber = (linenumber == 0) ? -1 : linenumber;
+       }
+
+       // Get declaring class name.
+       java_handle_t* declaringclass = class_get_classname(c);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       // Allocate a new StackTraceElement object.
+       java_handle_t* h = builtin_new(class_java_lang_StackTraceElement);
+
+       if (h == NULL)
+                       return NULL;
+
+       java_lang_StackTraceElement jlste(h, filename, linenumber, declaringclass, javastring_new(m->name), ((m->flags & ACC_NATIVE) ? 1 : 0));
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       // Allocate a new StackTraceElement object.
+       java_lang_StackTraceElement jlste(declaringclass, javastring_new(m->name), filename, linenumber);
+
+       if (jlste.is_null())
+               return NULL;
+#else
+# error unknown classpath configuration
+#endif
+
+       return jlste.get_handle();
+}
+#endif
+
+
+/**
+ * Creates a complete array of java.lang.StackTraceElement objects
+ * for the given stacktrace.
+ *
+ * @param st Given stacktrace.
+ * @return Array of filled StackTraceElement objects.
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t* st)
+{
+       // Create the stacktrace element array.
+       java_handle_objectarray_t* oa = builtin_anewarray(st->length, class_java_lang_StackTraceElement);
+
+       if (oa == NULL)
+               return NULL;
+
+       // Iterate over all stacktrace elements.
+       for (int i = 0; i < st->length; i++) {
+
+               // Get stacktrace element at current index.
+               java_handle_t* h = stacktrace_get_StackTraceElement(st, i);
+
+               if (h == NULL)
+                       return NULL;
+
+               // Store stacktrace element in array.
+               array_objectarray_element_set(oa, i, h);
+       }
+
+       return oa;
+}
+#endif
+
+
 /* stacktrace_get_caller_class *************************************************
 
    Get the class on the stack at the given depth.  This function skips
@@ -1187,6 +1304,36 @@ void stacktrace_print_current(void)
 }
 
 
+/**
+ * Creates a stacktrace for the given thread.
+ *
+ * @param t Given thread.
+ * @return Current stacktrace of the given thread.
+ *
+ * XXX: Creation of the stacktrace starts at the most recent
+ * stackframeinfo block. If the thread is not inside the native
+ * world, the created stacktrace is not complete!
+ */
+#if defined(ENABLE_THREADS)
+stacktrace_t* stacktrace_get_of_thread(threadobject* t)
+{
+       stackframeinfo_t*        sfi;
+       java_handle_bytearray_t* ba;
+       stacktrace_t*            st;
+
+       sfi = t->_stackframeinfo;
+       ba  = stacktrace_get(sfi);
+
+       if (ba == NULL)
+               return NULL;
+
+       st  = (stacktrace_t*) LLNI_array_data(ba);
+
+       return st;
+}
+#endif
+
+
 /* stacktrace_print_of_thread **************************************************
 
    Print the current stacktrace of the given thread.
index 6aa0ecf5baf2553dda180c58ee84c3e8a796495d..2c2920c826b55de4d14e1b517dd824f176b06fce 100644 (file)
@@ -106,6 +106,8 @@ java_handle_bytearray_t   *stacktrace_get(stackframeinfo_t *sfi);
 java_handle_bytearray_t   *stacktrace_get_current(void);
 
 #if defined(ENABLE_JAVASE)
+java_handle_t*             stacktrace_get_StackTraceElement(stacktrace_t *st, int32_t index);
+java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t *st);
 classinfo                 *stacktrace_get_caller_class(int depth);
 classloader_t             *stacktrace_first_nonnull_classloader(void);
 java_handle_objectarray_t *stacktrace_getClassContext(void);
@@ -117,6 +119,7 @@ void                       stacktrace_print(stacktrace_t *st);
 void                       stacktrace_print_current(void);
 
 #if defined(ENABLE_THREADS)
+stacktrace_t*              stacktrace_get_of_thread(threadobject *t);
 void                       stacktrace_print_of_thread(threadobject *t);
 #endif