From d9ec8e20bf6fdd24ff12ade27568bf9503bad40d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 11 Apr 2008 16:48:39 -0600 Subject: [PATCH] implement Thread.getStackTrace, activeCount, and enumerate --- classpath/java/lang/Thread.java | 10 +++++++ classpath/java/lang/Throwable.java | 2 +- src/builtin.cpp | 43 ++++++++++++++++++++++++++++++ src/interpret.cpp | 5 ++++ src/processor.h | 3 +++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/classpath/java/lang/Thread.java b/classpath/java/lang/Thread.java index 215d825451..2f7826d32c 100644 --- a/classpath/java/lang/Thread.java +++ b/classpath/java/lang/Thread.java @@ -108,4 +108,14 @@ public class Thread implements Runnable { t.sleepLock.wait(milliseconds); } } + + public StackTraceElement[] getStackTrace() { + return Throwable.resolveTrace(getStackTrace(peer)); + } + + private static native Object getStackTrace(long peer); + + public static native int activeCount(); + + public static native int enumerate(Thread[] array); } diff --git a/classpath/java/lang/Throwable.java b/classpath/java/lang/Throwable.java index c67590b867..5250a380af 100644 --- a/classpath/java/lang/Throwable.java +++ b/classpath/java/lang/Throwable.java @@ -65,7 +65,7 @@ public class Throwable { private static native Object trace(int skipCount); - private static native StackTraceElement[] resolveTrace(Object trace); + static native StackTraceElement[] resolveTrace(Object trace); private StackTraceElement[] resolveTrace() { if (! (trace instanceof StackTraceElement[])) { diff --git a/src/builtin.cpp b/src/builtin.cpp index f711e86808..35c7f8d7a5 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -47,6 +47,19 @@ search(Thread* t, jstring name, object (*op)(Thread*, object), } } +void +enumerateThreads(Thread* t, Thread* x, object array, unsigned* index, + unsigned limit) +{ + if (*index < limit) { + set(t, array, ArrayBody + (*index * BytesPerWord), x->javaThread); + + if (x->peer) enumerateThreads(t, x->peer, array, index, limit); + + if (x->child) enumerateThreads(t, x->child, array, index, limit); + } +} + } // namespace extern "C" JNIEXPORT jstring JNICALL @@ -697,6 +710,36 @@ Java_java_lang_Thread_interrupt(Thread* t, jclass, jlong peer) interrupt(t, reinterpret_cast(peer)); } +extern "C" JNIEXPORT jobject JNICALL +Java_java_lang_Thread_getTrace(Thread* t, jclass, jlong peer) +{ + if (reinterpret_cast(peer) == t) { + return makeLocalReference(t, makeTrace(t)); + } else { + return makeLocalReference + (t, t->m->processor->getStackTrace(t, reinterpret_cast(peer))); + } +} + +extern "C" JNIEXPORT jint JNICALL +Java_java_lang_Thread_activeCount(Thread* t, jclass) +{ + return t->m->liveCount; +} + +extern "C" JNIEXPORT jint JNICALL +Java_java_lang_Thread_enumerate(Thread* t, jclass, jobjectArray array) +{ + ACQUIRE_RAW(t, t->m->stateLock); + + ENTER(t, Thread::ActiveState); + + unsigned count = min(t->m->liveCount, objectArrayLength(t, *array)); + unsigned index = 0; + enumerateThreads(t, t->m->rootThread, *array, &index, count); + return count; +} + extern "C" JNIEXPORT jlong JNICALL Java_java_net_URL_00024ResourceInputStream_open (Thread* t, jclass, jstring path) diff --git a/src/interpret.cpp b/src/interpret.cpp index 1fdd6d2bed..c430b68e5d 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -3051,6 +3051,11 @@ class MyProcessor: public Processor { } } + virtual object getStackTrace(Thread*, Thread*) { + // not implemented + return 0; + } + virtual void dispose(vm::Thread* t) { t->m->heap->free(t, sizeof(Thread), false); } diff --git a/src/processor.h b/src/processor.h index bb602d141a..459970143e 100644 --- a/src/processor.h +++ b/src/processor.h @@ -115,6 +115,9 @@ class Processor { virtual void dispose() = 0; + virtual object + getStackTrace(Thread* t, Thread* target) = 0; + object invoke(Thread* t, object method, object this_, ...) {