Index: vm/port/src/lil/em64t/pim/lil_code_generator_em64t.cpp =================================================================== --- vm/port/src/lil/em64t/pim/lil_code_generator_em64t.cpp (revision 585138) +++ vm/port/src/lil/em64t/pim/lil_code_generator_em64t.cpp (working copy) @@ -102,7 +102,7 @@ /* 4) INITILIZE STACK INFORMATION */ if (has_m2n) { - stk_m2n_size = (unsigned)m2n_get_size(); + stk_m2n_size = (unsigned)(m2n_get_size() - 2*sizeof(void*)); } else { // preserve space for callee-saves registers stk_m2n_size = lil_cs_get_max_locals(stub) * GR_SIZE; Index: vm/port/src/lil/em64t/pim/m2n_em64t_internal.h =================================================================== --- vm/port/src/lil/em64t/pim/m2n_em64t_internal.h (revision 585138) +++ vm/port/src/lil/em64t/pim/m2n_em64t_internal.h (working copy) @@ -78,8 +78,7 @@ * returns size of m2n frame in bytes */ inline size_t m2n_get_size() { - // omit regs - return sizeof(M2nFrame) - 16; + return sizeof(M2nFrame); } /** Index: vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp =================================================================== --- vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp (revision 585138) +++ vm/port/src/lil/em64t/pim/stack_iterator_em64t.cpp (working copy) @@ -503,7 +503,7 @@ #ifdef WIN32 const static uint64 red_zone_size = 0x00; #else - const static uint64 red_zone_size = 0x80; + const static uint64 red_zone_size = 0x88; #endif si->jit_frame_context.rsp = si->jit_frame_context.rsp - red_zone_size - sizeof(void*); *((uint64*) si->jit_frame_context.rsp) = *(si->jit_frame_context.p_rip); Index: vm/port/src/lil/ipf/pim/m2n_ipf.cpp =================================================================== --- vm/port/src/lil/ipf/pim/m2n_ipf.cpp (revision 585138) +++ vm/port/src/lil/ipf/pim/m2n_ipf.cpp (working copy) @@ -194,6 +194,10 @@ *get_stacked_register_address(m2n_get_bsp(m2nf), M2N_FRAME_TYPE) = m2nf_type; } +size_t m2n_get_size() { + return sizeof(M2nFrame); +} + //***** Stub Interface // Flushes register stack of the current thread into backing store and calls target procedure. Index: vm/vmcore/include/exceptions_jit.h =================================================================== --- vm/vmcore/include/exceptions_jit.h (revision 585138) +++ vm/vmcore/include/exceptions_jit.h (working copy) @@ -42,13 +42,13 @@ // Must be called with the current thread "suspended" in managed code and regs holds the suspended values. // Exception defined as in previous two functions. // Mutates the regs value, which should be used to "resume" the managed code. -void exn_athrow_regs(Registers* regs, Class_Handle exn_class, bool java_code); +void exn_athrow_regs(Registers* regs, Class_Handle exn_class, bool java_code, bool transfer_control=false); // exception catch callback to restore stack after Stack Overflow Error void exception_catch_callback(); // exception catch support for JVMTI -void jvmti_exception_catch_callback(Registers* regs); +void jvmti_exception_catch_callback(); //**** Runtime exception support Index: vm/vmcore/src/jvmti/jvmti_capability.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_capability.cpp (revision 585138) +++ vm/vmcore/src/jvmti/jvmti_capability.cpp (working copy) @@ -88,7 +88,7 @@ 1, // can_access_local_variables 0, // can_maintain_original_method_order 0, // can_generate_single_step_events - 0, // can_generate_exception_events + 1, // can_generate_exception_events 1, // can_generate_frame_pop_events 0, // can_generate_breakpoint_events 1, // can_suspend Index: vm/vmcore/src/exception/exceptions_jit.cpp =================================================================== --- vm/vmcore/src/exception/exceptions_jit.cpp (revision 585138) +++ vm/vmcore/src/exception/exceptions_jit.cpp (working copy) @@ -188,7 +188,7 @@ // copied from the final stack iterator. // function can be safe point & should be called with disable recursion = 1 -static void exn_propagate_exception( +static ManagedObject * exn_propagate_exception( StackIterator * si, ManagedObject ** exn_obj, Class_Handle exn_class, @@ -248,6 +248,7 @@ } #ifdef VM_STATS + assert(exn_class); exn_class->class_thrown(); UNSAFE_REGION_START VM_Statistics::get_vm_stats().num_exceptions++; @@ -375,7 +376,7 @@ si_set_return_pointer(si, (void **) exn_obj); si_free(throw_si); - return; + return NULL; } } @@ -409,18 +410,16 @@ // Reload exception object pointer because it could have // moved while calling JVMTI callback if (exn_raised()) { - return; + si_free(throw_si); + return NULL; } *exn_obj = jvmti_jit_exception_event_callback_call(*exn_obj, interrupted_method_jit, interrupted_method, interrupted_method_location, NULL, NULL, NULL); - set_exception_object_internal(*exn_obj); - - *exn_obj = NULL; - si_set_return_pointer(si, (void **) exn_obj); si_free(throw_si); + return *exn_obj; } //exn_propagate_exception #ifndef _IPF_ @@ -490,27 +489,38 @@ assert(!exn_raised()); DebugUtilsTI* ti = VM_Global_State::loader_env->TI; - exn_propagate_exception(si, &local_exn_obj, exn_class, exn_constr, + exn_obj = exn_propagate_exception(si, &local_exn_obj, exn_class, exn_constr, jit_exn_constr_args, vm_exn_constr_args); + + if (exn_raised()) { + si_free(si); + return; + } + M2nFrame* m2nFrame = m2n_get_last_frame(); ObjectHandles* last_m2n_frame_handles = m2n_get_local_handles(m2nFrame); if (last_m2n_frame_handles) { free_local_object_handles2(last_m2n_frame_handles); } + set_exception_object_internal(exn_obj); if (ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_EXCEPTION_EVENT)) { Registers regs = {0}; VM_thread *thread = p_TLS_vmthread; NativeCodePtr callback = (NativeCodePtr) - asm_jvmti_exception_catch_callback; + jvmti_exception_catch_callback; si_copy_to_registers(si, ®s); vm_set_exception_registers(thread, regs); si_set_callback(si, &callback); } else if (p_TLS_vmthread->restore_guard_page) { + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; NativeCodePtr callback = (NativeCodePtr) - asm_exception_catch_callback; + exception_catch_callback; + si_copy_to_registers(si, ®s); + vm_set_exception_registers(thread, regs); si_set_callback(si, &callback); } @@ -541,45 +551,70 @@ // Mutates the regs value, which should be used to "resume" the managed code. // function can be safe point & should be called with disable reqursion = 1 -void exn_athrow_regs(Registers * regs, Class_Handle exn_class, bool java_code) +void exn_athrow_regs(Registers * regs, Class_Handle exn_class, bool java_code, bool transfer_control) { assert(!hythread_is_suspend_enabled()); assert(exn_class); #ifndef _IPF_ - M2nFrame *m2nf; + M2nFrame *cur_m2nf = (M2nFrame *) STD_ALLOCA(m2n_get_size()); + M2nFrame *unw_m2nf; + ManagedObject *exn_obj = NULL; StackIterator *si; + DebugUtilsTI* ti = VM_Global_State::loader_env->TI; + VM_thread* vmthread = p_TLS_vmthread; if (java_code) { - m2nf = m2n_push_suspended_frame(regs); + m2n_push_suspended_frame(vmthread, cur_m2nf, regs); } BEGIN_RAISE_AREA; si = si_create_from_native(); ManagedObject *local_exn_obj = NULL; - exn_propagate_exception(si, &local_exn_obj, exn_class, NULL, NULL, NULL); - si_copy_to_registers(si, regs); + exn_obj = exn_propagate_exception(si, &local_exn_obj, exn_class, NULL, NULL, NULL); -#ifdef _WIN32 - END_RAISE_AREA; -#else - /* - * FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME - * Gregory - - * This is a workaround for bug HARMONY-4873. This code should - * actually be replaced with END_RAISE_AREA when the bug is fixed - */ - set_unwindable(unwindable); + //free local handles + ObjectHandles* last_m2n_frame_handles = m2n_get_local_handles(cur_m2nf); + + if (last_m2n_frame_handles) { + free_local_object_handles2(last_m2n_frame_handles); } -#endif - m2n_set_last_frame(si_get_m2n(si)); + if (ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_EXCEPTION_EVENT)) { + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; + NativeCodePtr callback = (NativeCodePtr) + jvmti_exception_catch_callback; + + si_copy_to_registers(si, ®s); + vm_set_exception_registers(thread, regs); + si_set_callback(si, &callback); + } else if (p_TLS_vmthread->restore_guard_page) { + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; + NativeCodePtr callback = (NativeCodePtr) + exception_catch_callback; + si_copy_to_registers(si, ®s); + vm_set_exception_registers(thread, regs); + si_set_callback(si, &callback); + } + + si_copy_to_registers(si, regs); + + if (transfer_control) { + set_exception_object_internal(exn_obj); + si_transfer_control(si); + assert(!"si_transfer_control should not return"); + } + + unw_m2nf = si_get_m2n(si); si_free(si); - if (java_code) { - STD_FREE(m2nf); - } + END_RAISE_AREA; + + set_exception_object_internal(exn_obj); + m2n_set_last_frame(unw_m2nf); #endif } //exn_athrow_regs @@ -588,25 +623,48 @@ // exception catch callback to restore stack after Stack Overflow Error void exception_catch_callback() { + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; + assert(thread); + + if (thread->regs) { + regs = *(Registers*)thread->regs; + } + if (p_TLS_vmthread->restore_guard_page) { set_guard_stack(); } + + M2nFrame* m2n = (M2nFrame *) STD_ALLOCA(m2n_get_size()); + m2n_push_suspended_frame(thread, m2n, ®s); + M2nFrame* prev_m2n = m2n_get_previous_frame(m2n); + + StackIterator *si = + si_create_from_registers(®s, false, prev_m2n); + si_transfer_control(si); } // exception catch support for JVMTI, also restore stack after Stack Overflow Error -void jvmti_exception_catch_callback(Registers* regs) { +void jvmti_exception_catch_callback() { + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; + assert(thread); + + if (thread->regs) { + regs = *(Registers*)thread->regs; + } + if (p_TLS_vmthread->restore_guard_page) { set_guard_stack(); } - M2nFrame *m2nf = m2n_push_suspended_frame(regs); + M2nFrame* m2n = (M2nFrame *) STD_ALLOCA(m2n_get_size()); + m2n_push_suspended_frame(thread, m2n, ®s); + M2nFrame* prev_m2n = m2n_get_previous_frame(m2n); - StackIterator *si = si_create_from_native(); + StackIterator *si = + si_create_from_registers(®s, false, prev_m2n); - if (si_is_native(si)) { - si_goto_previous(si); - } - if (!si_is_native(si)) { CodeChunkInfo* catch_cci = si_get_code_chunk_info(si); @@ -625,9 +683,7 @@ assert(0); #endif } - - m2n_set_last_frame(m2n_get_previous_frame(m2nf)); - STD_FREE(m2nf); + si_transfer_control(si); } ////////////////////////////////////////////////////////////////////////// Index: vm/vmcore/src/util/em64t/base/compile_em64t.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/compile_em64t.cpp (revision 585138) +++ vm/vmcore/src/util/em64t/base/compile_em64t.cpp (working copy) @@ -58,7 +58,7 @@ assert(m2n_get_size() % 8 == 0); // 15 = 1(alignment) + n(fp) + n(gp) registers were preserved on the stack uint64 * const inputs_addr = m2n_base_addr - - (m2n_get_size() / 8) + - (m2n_get_size() / 8) + 2 - 1 - MAX_GR - MAX_FR; // 1(return ip); #ifdef _WIN64 @@ -176,7 +176,7 @@ const int32 gr_stack_size = (1 + MAX_GR)*GR_STACK_SIZE + SHADOW; -const int32 stack_size = (int32)m2n_get_size() +const int32 stack_size = (int32)(m2n_get_size() - 2*sizeof(void*)) + MAX_FR*FR_STACK_SIZE + gr_stack_size + ALIGNMENT; @@ -246,7 +246,7 @@ stub = call(stub, (char *)&compile_me); // pop m2n from the stack - const int32 bytes_to_m2n_bottom = (int32)(stack_size - m2n_get_size()); + const int32 bytes_to_m2n_bottom = (int32)(stack_size - (m2n_get_size() - 2*sizeof(void*))); stub = m2n_gen_pop_m2n(stub, false, 0, bytes_to_m2n_bottom, 1); // restore gp inputs from the stack Index: vm/vmcore/src/util/linux/signals_ia32.cpp =================================================================== --- vm/vmcore/src/util/linux/signals_ia32.cpp (revision 585138) +++ vm/vmcore/src/util/linux/signals_ia32.cpp (working copy) @@ -100,79 +100,55 @@ uc->uc_mcontext.gregs[REG_EFL] = regs->eflags; } -// exception catch support for stack restore -extern "C" { - static void __attribute__ ((used, cdecl)) exception_catch_callback_wrapper(){ - exception_catch_callback(); - } +void regs_push_param(Registers* pregs, POINTER_SIZE_INT param, int UNREF num) +{ + pregs->esp = pregs->esp - 4; + *((uint32*)pregs->esp) = param; } -void __attribute__ ((cdecl)) asm_exception_catch_callback() { - asm ( - "pushl %%eax;\n" - "pushl %%ebx;\n" - "pushl %%ecx;\n" - "pushl %%edx;\n" - "call exception_catch_callback_wrapper;\n" - "popl %%edx;\n" - "popl %%ecx;\n" - "popl %%ebx;\n" - "popl %%eax;\n" - : /* no output operands */ - : /* no input operands */ - ); +void regs_push_return_address(Registers* pregs, void* ret_addr) +{ + pregs->esp = pregs->esp - 4; + *((void**)pregs->esp) = ret_addr; } -// exception catch support for JVMTI extern "C" { - static void __attribute__ ((used, cdecl)) jvmti_exception_catch_callback_wrapper(Registers regs){ - jvmti_exception_catch_callback(®s); +void __attribute__ ((used, cdecl)) c_exception_handler(Class* exn_class, bool java_code) { + // this exception handler is executed *after* NT exception handler returned + DebugUtilsTI* ti = VM_Global_State::loader_env->TI; + // Create local copy for registers because registers in TLS can be changed + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; + assert(thread); + assert(exn_class); + + if (thread->regs) { + regs = *(Registers*)thread->regs; } -} -void __attribute__ ((cdecl)) asm_jvmti_exception_catch_callback() { - //naked_jvmti_exception_catch_callback: - asm ( - "addl $-36, %%esp;\n" - "movl %%eax, -36(%%ebp);\n" - "movl %%ebx, -32(%%ebp);\n" - "movl %%ecx, -28(%%ebp);\n" - "movl %%edx, -24(%%ebp);\n" - "movl %%esp, %%eax;\n" - "movl (%%ebp), %%ebx;\n" - "movl 4(%%ebp), %%ecx;\n" - "addl $44, %%eax;\n" - "movl %%edi, -20(%%ebp);\n" - "movl %%esi, -16(%%ebp);\n" - "movl %%ebx, -12(%%ebp);\n" - "movl %%eax, -8(%%ebp);\n" - "movl %%ecx, -4(%%ebp);\n" - "call jvmti_exception_catch_callback_wrapper;\n" - "movl -36(%%ebp), %%eax;\n" - "movl -32(%%ebp), %%ebx;\n" - "movl -28(%%ebp), %%ecx;\n" - "movl -24(%%ebp), %%edx;\n" - "addl $36, %%esp;\n" - : /* no output operands */ - : /* no input operands */ - ); + exn_athrow_regs(®s, exn_class, java_code, true); } +} static void throw_from_sigcontext(ucontext_t *uc, Class* exc_clss) { Registers regs; linux_ucontext_to_regs(®s, uc); - uint32 exception_esp = regs.esp; DebugUtilsTI* ti = VM_Global_State::loader_env->TI; bool java_code = (vm_identify_eip((void *)regs.eip) == VM_TYPE_JAVA); - exn_athrow_regs(®s, exc_clss, java_code); - assert(exception_esp <= regs.esp); - if (ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_EXCEPTION_EVENT)) { - regs.esp = regs.esp - 4; - *((uint32*) regs.esp) = regs.eip; - regs.eip = ((uint32)asm_jvmti_exception_catch_callback); - } + VM_thread* vmthread = p_TLS_vmthread; + NativeCodePtr callback = (NativeCodePtr) c_exception_handler; + + vm_set_exception_registers(vmthread, regs); + regs_push_param(®s, java_code, 1/*2nd arg */); + assert(exc_clss); + regs_push_param(®s, (POINTER_SIZE_INT)exc_clss, 0/* 1st arg */); + // imitate return IP on stack + regs_push_return_address(®s, NULL); + + // set up the real exception handler address + regs.set_ip(callback); linux_regs_to_ucontext(uc, ®s); } @@ -412,7 +388,7 @@ size_t used_stack_size = stack_addr - ((char*)&stack_addr); int available_stack_size; - if (((char*)&stack_addr) > (stack_addr - get_stack_size() + get_guard_page_size() + get_guard_stack_size())) { + if (!(p_TLS_vmthread->restore_guard_page)) { available_stack_size = get_stack_size() - used_stack_size - 2 * get_guard_page_size() - get_guard_stack_size(); } else { @@ -457,6 +433,12 @@ return get_restore_stack_size() < available_stack_size; } +void remove_guard_stack() { + vm_thread_t vm_thread = jthread_self_vm_thread_unsafe(); + assert(vm_thread); + remove_guard_stack(vm_thread); +} + void remove_guard_stack(vm_thread_t vm_thread) { int err; char* stack_addr = (char*) get_stack_addr(); @@ -509,6 +491,10 @@ ucontext_t *uc = (ucontext_t *)context; Global_Env *env = VM_Global_State::loader_env; + vm_thread_t vm_thread = p_TLS_vmthread; + remove_guard_stack(vm_thread); + vm_thread->restore_guard_page = true; + if (java_throw_from_sigcontext( uc, env->java_lang_StackOverflowError_Class)) { return; @@ -520,10 +506,7 @@ throw_from_sigcontext( uc, env->java_lang_StackOverflowError_Class); } else { - vm_thread_t vm_thread = p_TLS_vmthread; - remove_guard_stack(vm_thread); exn_raise_by_class(env->java_lang_StackOverflowError_Class); - vm_thread->restore_guard_page = true; } } } Index: vm/vmcore/src/util/linux/signals_ipf.cpp =================================================================== --- vm/vmcore/src/util/linux/signals_ipf.cpp (revision 585138) +++ vm/vmcore/src/util/linux/signals_ipf.cpp (working copy) @@ -356,6 +356,11 @@ return get_restore_stack_size() < available_stack_size; } +void remove_guard_stack() { + vm_thread_t vm_thread = jthread_self_vm_thread_unsafe(); + assert(vm_thread); + remove_guard_stack(vm_thread); +} void remove_guard_stack(vm_thread_t vm_thread) { int err; Index: vm/vmcore/src/util/linux/signals_em64t.cpp =================================================================== --- vm/vmcore/src/util/linux/signals_em64t.cpp (revision 585138) +++ vm/vmcore/src/util/linux/signals_em64t.cpp (working copy) @@ -114,64 +114,56 @@ uc->uc_mcontext.gregs[REG_EFL] = regs->eflags; } -// exception catch support for stack restore -extern "C" { - static void __attribute__ ((used)) exception_catch_callback_wrapper(){ - exception_catch_callback(); +// Max. 6 arguments can be set up +void regs_push_param(Registers* pregs, POINTER_SIZE_INT param, int num) +{ + switch (num) + { + case 0: + pregs->rdi = param; + return; + case 1: + pregs->rsi = param; + return; + case 2: + pregs->rdx = param; + return; + case 3: + pregs->rcx = param; + return; + case 4: + pregs->r8 = param; + return; + case 5: + pregs->r9 = param; + return; } } -void asm_exception_catch_callback() { - asm ( - "pushq %%rax;\n" - "pushq %%rbx;\n" - "pushq %%rcx;\n" - "pushq %%rdx;\n" - "pushq %%rsi;\n" - "pushq %%rdi;\n" - "pushq %%r8;\n" - "pushq %%r9;\n" - "pushq %%r10;\n" - "pushq %%r11;\n" - "call exception_catch_callback_wrapper;\n" - "popq %%r11;\n" - "popq %%r10;\n" - "popq %%r9;\n" - "popq %%r8;\n" - "popq %%rdi;\n" - "popq %%rsi;\n" - "popq %%rdx;\n" - "popq %%rcx;\n" - "popq %%rbx;\n" - "popq %%rax;\n" - : /* no output operands */ - : /* no input operands */ - ); -#ifdef _DEBUG - asm ( - "movq %%rbp, %%rsp\n" - "popq %%rbp\n" - "retq $0x80;\n" - : /* no output operands */ - : /* no input operands */ - ); -#else // _DEBUG - asm ( - "retq $0x80;\n" - : /* no output operands */ - : /* no input operands */ - ); -#endif // ! _DEBUG} +void regs_push_return_address(Registers* pregs, void* ret_addr) +{ + pregs->rsp = pregs->rsp - 8; + *((void**)pregs->rsp) = ret_addr; } -// exception catch support for JVMTI -void asm_jvmti_exception_catch_callback() { - // FIXME: not implemented - fprintf(stderr, "FIXME: asm_jvmti_exception_catch_callback: not implemented\n"); - assert(0); - abort(); +extern "C" { +void __attribute__ ((used, cdecl)) c_exception_handler(Class* exn_class, bool java_code) { + // this exception handler is executed *after* NT exception handler returned + DebugUtilsTI* ti = VM_Global_State::loader_env->TI; + // Create local copy for registers because registers in TLS can be changed + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; + assert(thread); + assert(exn_class); + if (thread->regs) { + regs = *(Registers*)thread->regs; + } + + exn_athrow_regs(®s, exn_class, java_code, true); } +} + static void throw_from_sigcontext(ucontext_t *uc, Class* exc_clss) { Registers regs; @@ -179,8 +171,21 @@ DebugUtilsTI* ti = VM_Global_State::loader_env->TI; bool java_code = (vm_identify_eip((void *)regs.rip) == VM_TYPE_JAVA); + VM_thread* vmthread = p_TLS_vmthread; + NativeCodePtr callback = (NativeCodePtr) c_exception_handler; + const static uint64 red_zone_size = 0x80; - exn_athrow_regs(®s, exc_clss, java_code); + vm_set_exception_registers(vmthread, regs); + regs.rsp -= red_zone_size; + regs_push_param(®s, java_code, 1); + assert(exc_clss); + regs_push_param(®s, (POINTER_SIZE_INT)exc_clss, 0); + // imitate return IP on stack + regs_push_return_address(®s, NULL); + regs_push_return_address(®s, NULL); + + // set up the real exception handler address + regs.set_ip(callback); linux_regs_to_ucontext(uc, ®s); } @@ -384,7 +389,7 @@ size_t used_stack_size = stack_addr - ((char*)&stack_addr); int available_stack_size; - if (((char*)&stack_addr) > (stack_addr - get_stack_size() + get_guard_page_size() + get_guard_stack_size())) { + if (!(p_TLS_vmthread->restore_guard_page)) { available_stack_size = get_stack_size() - used_stack_size - 2 * get_guard_page_size() - get_guard_stack_size(); } else { @@ -426,6 +431,12 @@ return get_restore_stack_size() < available_stack_size; } +void remove_guard_stack() { + vm_thread_t vm_thread = jthread_self_vm_thread_unsafe(); + assert(vm_thread); + remove_guard_stack(vm_thread); +} + void remove_guard_stack(vm_thread_t vm_thread) { int err; char* stack_addr = (char*) get_stack_addr(); @@ -476,6 +487,10 @@ ucontext_t *uc = (ucontext_t *)context; Global_Env *env = VM_Global_State::loader_env; + vm_thread_t vm_thread = p_TLS_vmthread; + remove_guard_stack(vm_thread); + vm_thread->restore_guard_page = true; + if (java_throw_from_sigcontext( uc, env->java_lang_StackOverflowError_Class)) { return; @@ -487,7 +502,6 @@ throw_from_sigcontext( uc, env->java_lang_StackOverflowError_Class); } else { - remove_guard_stack(p_TLS_vmthread); exn_raise_by_class(env->java_lang_StackOverflowError_Class); } } Index: vm/vmcore/src/util/win/em64t/exception_handlers.asm =================================================================== --- vm/vmcore/src/util/win/em64t/exception_handlers.asm (revision 585138) +++ vm/vmcore/src/util/win/em64t/exception_handlers.asm (working copy) @@ -4,12 +4,6 @@ PUBLIC asm_c_exception_handler EXTRN c_exception_handler:PROC -PUBLIC asm_exception_catch_callback -EXTRN exception_catch_callback_wrapper:PROC - -PUBLIC asm_jvmti_exception_catch_callback -EXTRN jvmti_exception_catch_callback_wrapper:PROC - _TEXT SEGMENT vectored_exception_handler PROC @@ -69,77 +63,6 @@ asm_c_exception_handler ENDP -asm_exception_catch_callback PROC - -; void __cdecl exception_catch_callback_wrapper() -; Args: -; rcx - none -; rdx - none -; r8 - none -; r9 - none - - pushfq - cld - push rax - push rbx - push rcx - push rdx - push r8 - push r9 - push r10 - push r11 - sub rsp, 32 ; allocate stack for 4 registers - call exception_catch_callback_wrapper - add rsp, 32 - pop r11 - pop r10 - pop r9 - pop r8 - pop rdx - pop rcx - pop rbx - pop rax - popfq - ret - -asm_exception_catch_callback ENDP - - -asm_jvmti_exception_catch_callback PROC - -; void __cdecl jvmti_exception_catch_callback_wrapper() -; Args: -; rcx - none -; rdx - none -; r8 - none -; r9 - none - - pushfq - cld - push rax - push rbx - push rcx - push rdx - push r8 - push r9 - push r10 - push r11 - sub rsp, 32 ; allocate stack for 4 registers - call jvmti_exception_catch_callback_wrapper - add rsp, 32 - pop r11 - pop r10 - pop r9 - pop r8 - pop rdx - pop rcx - pop rbx - pop rax - popfq - ret - -asm_jvmti_exception_catch_callback ENDP - _TEXT ENDS END Index: vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp =================================================================== --- vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp (revision 585138) +++ vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp (working copy) @@ -196,6 +196,12 @@ jthread_self_vm_thread_unsafe()->restore_guard_page = false; } +void remove_guard_stack() { + vm_thread_t vm_thread = jthread_self_vm_thread_unsafe(); + assert(vm_thread); + remove_guard_stack(vm_thread); +} + void remove_guard_stack(vm_thread_t vm_thread) { void* stack_addr = get_stack_addr(); size_t stack_size = get_stack_size(); @@ -264,21 +270,6 @@ return get_restore_stack_size() < available_stack_size; } - -// exception catch callback to restore stack after Stack Overflow Error -void __cdecl exception_catch_callback_wrapper(){ - exception_catch_callback(); -} - -// exception catch support for JVMTI -void __cdecl jvmti_exception_catch_callback_wrapper(){ - Registers regs = {0}; - if (p_TLS_vmthread->regs) { - regs = *(Registers*)p_TLS_vmthread->regs; - } - jvmti_exception_catch_callback(®s); -} - LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception) { DWORD code = nt_exception->ExceptionRecord->ExceptionCode; @@ -461,37 +452,9 @@ regs = *(Registers*)thread->regs; } - M2nFrame* prev_m2n = m2n_get_last_frame(); - M2nFrame* m2n = NULL; - if (in_java) { - m2n = m2n_push_suspended_frame(®s); - } else { - prev_m2n = m2n_get_previous_frame(prev_m2n); - } - TRACE2("signals", ("should throw exception %p at IP=%p, SP=%p", exn_class, regs.get_ip(), regs_get_sp(®s))); - exn_athrow_regs(®s, exn_class, false); + exn_athrow_regs(®s, exn_class, in_java, true); - if (ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_EXCEPTION_EVENT)) { - // Set return address to current IP - regs_push_return_address(®s, regs.get_ip()); - // Set IP to callback address - regs.set_ip(asm_jvmti_exception_catch_callback); - } else if (thread->restore_guard_page) { - // Set return address to current IP - regs_push_return_address(®s, regs.get_ip()); - // Set IP to callback address - regs.set_ip(asm_exception_catch_callback); - } - - StackIterator *si = - si_create_from_registers(®s, false, prev_m2n); - - if (m2n) - STD_FREE(m2n); - - vm_set_exception_registers(thread, regs); - si_transfer_control(si); assert(!"si_transfer_control should not return"); } Index: vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp =================================================================== --- vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp (revision 585138) +++ vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp (working copy) @@ -67,48 +67,6 @@ fprintf(stderr, " EIP: 0x%08x\n", nt_exception->ContextRecord->Eip); } -void __declspec(naked) asm_exception_catch_callback() { - __asm { - push ebp - mov ebp, esp - push eax - push ebx - push ecx - push edx - pushfd - cld - call exception_catch_callback_wrapper - popfd - pop edx - pop ecx - pop ebx - pop eax - leave - ret - } -} - -void __declspec(naked) asm_jvmti_exception_catch_callback() { - __asm { - push ebp - mov ebp, esp - push eax - push ebx - push ecx - push edx - pushfd - cld - call jvmti_exception_catch_callback_wrapper - popfd - pop edx - pop ecx - pop ebx - pop eax - leave - ret - } -} - LONG __declspec(naked) NTAPI vectored_exception_handler(LPEXCEPTION_POINTERS nt_exception) { __asm {