diff --git a/sgx-jvm/avian/src/classpath-openjdk.cpp b/sgx-jvm/avian/src/classpath-openjdk.cpp index 7090c3425e..4cf8d62f3f 100644 --- a/sgx-jvm/avian/src/classpath-openjdk.cpp +++ b/sgx-jvm/avian/src/classpath-openjdk.cpp @@ -296,9 +296,7 @@ object makeJconstructor(Thread* t, GcMethod* vmMethod, int index = -1); object makeJfield(Thread* t, GcField* vmField, int index = -1); -void uncaughtException(Thread *t, GcThrowable *e); - -void disposeThread(Thread *t); +static uint64_t uncaughtExceptionHandler(Thread*, uintptr_t*); #ifdef AVIAN_OPENJDK_SRC void interceptFileOperations(Thread*, bool); @@ -594,13 +592,25 @@ class MyClasspath : public Classpath { THREAD_RESOURCE0(t, { GcThrowable* e = t->exception; if (e != NULL) { - PROTECT(t, e); - t->exception = NULL; - uncaughtException(t, e); + + // Prevent any exceptions thrown from the uncaught + // exception handler from unwinding the stack past + // this point. This allows us to continue cleaning + // up this resource. + uintptr_t argument = reinterpret_cast(e); + runRaw(t, uncaughtExceptionHandler, &argument); } - disposeThread(t); + vm::acquire(t, t->javaThread); + t->clearFlag(Thread::ActiveFlag); + vm::notifyAll(t, t->javaThread); + vm::release(t, t->javaThread); + + t->m->processor->invoke(t, + cast(t, roots(t)->threadTerminated()), + t->javaThread->group(), + t->javaThread); }); GcMethod* method = resolveMethod( @@ -969,37 +979,20 @@ class EmbeddedFile { unsigned pathLength; }; -void uncaughtException(Thread *t, GcThrowable *e) +static uint64_t uncaughtExceptionHandler(Thread* t, uintptr_t* arguments) { + GcThrowable* exception = cast(t, reinterpret_cast(arguments[0])); + PROTECT(t, exception); + GcMethod* dispatch = resolveMethod(t, roots(t)->bootLoader(), "java/lang/Thread", "dispatchUncaughtException", "(Ljava/lang/Throwable;)V"); if (dispatch != NULL) { - THREAD_RESOURCE0(t, { - if (t->exception != NULL) { - // The stack will be unwound when this resource is - // released, which means that uncaughtException() - // will not return. So repeat the thread clean-up here. - disposeThread(t); - } - }); - - t->m->processor->invoke(t, dispatch, t->javaThread, e); + t->m->processor->invoke(t, dispatch, t->javaThread, exception); } -} - -void disposeThread(Thread *t) { - vm::acquire(t, t->javaThread); - t->clearFlag(Thread::ActiveFlag); - vm::notifyAll(t, t->javaThread); - vm::release(t, t->javaThread); - - t->m->processor->invoke(t, - cast(t, roots(t)->threadTerminated()), - t->javaThread->group(), - t->javaThread); + return 0; } #ifdef AVIAN_OPENJDK_SRC