Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp (revision 468484) +++ vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp (working copy) @@ -215,6 +215,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_vm_VMStack_getStackTrace (JNIEnv * jenv, jclass, jobject state) { + ASSERT_RAISE_AREA; if (NULL == state) return NULL; @@ -235,6 +236,10 @@ genv->java_lang_Throwable_Class, "fillInStackTrace", "()Ljava/lang/Throwable;"); + static Method_Handle threadRunImpl = class_lookup_method( + genv->java_lang_Thread_Class, + "runImpl", "()V"); + unsigned skip; // skip frames up to one with fillInStackTrace method and remember this @@ -249,6 +254,8 @@ } } + if (frames[size -1].method == threadRunImpl) size--; + if (skip < size) { Method *method = frames[skip].method; // skip Throwable constructor @@ -386,13 +393,14 @@ // skip the VMStart$MainThread if one exits from the bottom of the stack // along with 2 reflection frames used to invoke method main - static String* starter_String = genv->string_pool.lookup("java/lang/VMStart$MainThread"); + static String* starter_String = genv->string_pool.lookup("java/lang/Thread"); Method_Handle method = frames[size-1].method; assert(method); // skip only for main application thread - if (!strcmp(method_get_name(method), "run") + if (!strcmp(method_get_name(method), "runImpl") && method->get_class()->name == starter_String) { - size -= size < 3 ? size : 3; + + size --; } assert(hythread_is_suspend_enabled()); Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java (revision 468484) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java (working copy) @@ -658,6 +658,16 @@ } } + void runImpl() { + synchronized (lock) { + this.isAlive = true; + this.started = true; + lock.notifyAll(); + } + + run(); + } + /** * @com.intel.drl.spec_ref */ @@ -716,7 +726,7 @@ /** * @com.intel.drl.spec_ref */ - public void start() { + public synchronized void start() { synchronized (lock) { if (started) { //this thread was started @@ -724,13 +734,16 @@ "This thread was already started!"); } - this.isAlive = true; if (VMThreadManager.start(this, stackSize, daemon, priority) != 0) { throw new OutOfMemoryError("Failed to create new thread"); } - started = true; + while(!this.started) { + try { + lock.wait(); + } catch (InterruptedException e) {/* continue waiting*/} + } } } Index: vm/interpreter/src/interpreter_ti.cpp =================================================================== --- vm/interpreter/src/interpreter_ti.cpp (revision 468484) +++ vm/interpreter/src/interpreter_ti.cpp (working copy) @@ -40,9 +40,9 @@ assert(clss); if (strcmp(method_get_name(first_frame->method), "runImpl") == 0 && - strcmp(class_get_name(clss), "java/lang/VMStart$MainThread") == 0) + strcmp(class_get_name(clss), "java/lang/Thread") == 0) { - return 3; + return 1; } } Index: vm/interpreter/src/interpreter.cpp =================================================================== --- vm/interpreter/src/interpreter.cpp (revision 468484) +++ vm/interpreter/src/interpreter.cpp (working copy) @@ -2521,6 +2521,11 @@ void interpreter(StackFrame &frame) { + uint8 *first = NULL; + uint8 ip0 = 0; + bool breakpoint_processed = false; + int stackLength = 0; + DEBUG_TRACE_PLAIN("interpreter: " << frame.method->get_class()->name->bytes << " " << frame.method->get_name()->bytes @@ -2529,11 +2534,14 @@ assert(frame.method->is_static() || frame.This); M2N_ALLOC_MACRO; - assert(!check_current_thread_exception()); + if (get_thread_ptr()->p_exception_object_ti || exn_raised()) { + frame.exc = get_current_thread_exception(); + goto got_exception; + } assert(!hythread_is_suspend_enabled()); - uint8 *first = (uint8*) get_thread_ptr()->firstFrame; - int stackLength = ((uint8*)first) - ((uint8*)&frame); + first = (uint8*) get_thread_ptr()->firstFrame; + stackLength = ((uint8*)first) - ((uint8*)&frame); if (stackLength > 500000) { // FIXME: hardcoded stack limit if (!(get_thread_ptr()->interpreter_state & INTERP_STATE_STACK_OVERFLOW)) { get_thread_ptr()->interpreter_state |= INTERP_STATE_STACK_OVERFLOW; @@ -2569,10 +2577,10 @@ vm_monitor_enter_wrapper(ml->monitor); } - bool breakpoint_processed = false; + breakpoint_processed = false; while (true) { - uint8 ip0 = *frame.ip; + ip0 = *frame.ip; DEBUG_BYTECODE(endl << "(" << frame.stack.getIndex() << ") " << opcodeNames[ip0] << ": "); @@ -2608,11 +2616,6 @@ } breakpoint_processed = false; - //assert(!exn_raised()); - if (get_thread_ptr()->p_exception_object_ti || exn_raised()) { - frame.exc = get_current_thread_exception(); - goto got_exception; - } } #ifdef INTERPRETER_DEEP_DEBUG @@ -2621,7 +2624,12 @@ assert(!hythread_is_suspend_enabled()); assert(&frame == getLastStackFrame()); - assert(!exn_raised()); + + if (get_thread_ptr()->p_exception_object_ti || exn_raised()) { + frame.exc = get_current_thread_exception(); + goto got_exception; + } + switch(ip0) { case OPCODE_NOP: Opcode_NOP(frame); break; Index: vm/thread/src/thread_java_basic.c =================================================================== --- vm/thread/src/thread_java_basic.c (revision 468484) +++ vm/thread/src/thread_java_basic.c (working copy) @@ -409,7 +409,10 @@ tm_native_thread = hythread_self(); tm_java_thread = hythread_get_private_data(tm_native_thread); excn = tm_java_thread->stop_exception; + tm_native_thread->suspend_request = 0; + hysem_post(tm_native_thread->resume_event); + jthread_throw_exception_object(excn); } @@ -456,7 +459,7 @@ tm_java_thread = hythread_get_private_data(tm_native_thread); // Install safepoint callback that would throw exception - env = tm_java_thread->jenv; + env = jthread_get_JNI_env(jthread_self()); tm_java_thread->stop_exception = (*env)->NewGlobalRef(env,excn); return hythread_set_safepoint_callback(tm_native_thread, stop_callback); @@ -679,7 +682,7 @@ //printf("run method find enter\n"); if (!run_method) { clazz = (*env) -> FindClass(env, "java/lang/Thread"); - run_method = (*env) -> GetMethodID(env, clazz, "run", "()V"); + run_method = (*env) -> GetMethodID(env, clazz, "runImpl", "()V"); } status=release_start_lock(); //printf("run method find exit\n"); Index: vm/thread/src/thread_native_suspend.c =================================================================== --- vm/thread/src/thread_native_suspend.c (revision 468484) +++ vm/thread/src/thread_native_suspend.c (working copy) @@ -354,7 +354,7 @@ //let the thread execute safe point in the case it's already suspended //// status = hysem_post(thread->resume_event); - assert (status == TM_ERROR_NONE); + } if (thread->current_condition) {