Index: vm/vmcore/include/exceptions.h =================================================================== --- vm/vmcore/include/exceptions.h (revision 599441) +++ vm/vmcore/include/exceptions.h (working copy) @@ -240,8 +240,8 @@ #define BEGIN_RAISE_AREA \ { \ -if (is_unwindable()) exn_rethrow_if_pending();\ -bool unwindable = set_unwindable(false); +bool unwindable = set_unwindable(false);\ +if (unwindable) exn_rethrow_if_pending(); #define END_RAISE_AREA \ if (unwindable) exn_rethrow_if_pending();\ @@ -270,9 +270,10 @@ void exn_rethrow(); void exn_rethrow_if_pending(); -void set_guard_stack(); +bool set_guard_stack(); void remove_guard_stack(vm_thread_t vm_thread); void init_stack_info(); +void* get_exception_catch_stack_addr(void* curr_ip); VMEXPORT size_t get_available_stack_size(); VMEXPORT bool check_available_stack_size(size_t required_size); VMEXPORT size_t get_default_stack_size(); Index: vm/vmcore/src/exception/exceptions.cpp =================================================================== --- vm/vmcore/src/exception/exceptions.cpp (revision 599441) +++ vm/vmcore/src/exception/exceptions.cpp (working copy) @@ -118,6 +118,17 @@ tmn_suspend_disable_recursive(); clear_exception_internal(); tmn_suspend_enable_recursive(); + + // if quard stack should be restored - restores it + if (p_TLS_vmthread->restore_guard_page) { + bool result = set_guard_stack(); + + // if guard stack can't be restored raise SOE + if (result == false) { + Global_Env *env = VM_Global_State::loader_env; + exn_raise_by_class(env->java_lang_StackOverflowError_Class); + } + } } bool is_unwindable() @@ -340,6 +351,8 @@ assert(!hythread_is_suspend_enabled()); + BEGIN_RAISE_AREA; + #ifndef VM_LAZY_EXCEPTION ManagedObject *exn = get_exception_object_internal(); assert(exn); @@ -374,6 +387,8 @@ } #endif DIE(("It's Unreachable place.")); + + END_RAISE_AREA; } //exn_rethrow void exn_rethrow_if_pending() Index: vm/vmcore/src/exception/exceptions_jit.cpp =================================================================== --- vm/vmcore/src/exception/exceptions_jit.cpp (revision 599441) +++ vm/vmcore/src/exception/exceptions_jit.cpp (working copy) @@ -638,16 +638,38 @@ 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_create_from_registers uses large stack space, + // so guard page restored after its invoke. + if (p_TLS_vmthread->restore_guard_page) { + bool result = set_guard_stack(); + + if (result == false) { + Global_Env *env = VM_Global_State::loader_env; + + if (si_is_native(si)) { + m2n_set_last_frame(prev_m2n); + + if ((interpreter_enabled() || (!prev_m2n) + || (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) { + exn_raise_by_class(env->java_lang_StackOverflowError_Class); + } else { + si_free(si); + exn_throw_by_class(env->java_lang_StackOverflowError_Class); + } + } else { + si_free(si); + exn_throw_by_class(env->java_lang_StackOverflowError_Class); + } + } + } + si_transfer_control(si); } @@ -661,10 +683,6 @@ 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); @@ -672,6 +690,33 @@ StackIterator *si = si_create_from_registers(®s, false, prev_m2n); + // si_create_from_registers uses large stack space, + // so guard page restored after its invoke, + // but befor ti agent callback invokation, + // because it should work on protected page. + if (p_TLS_vmthread->restore_guard_page) { + bool result = set_guard_stack(); + + if (result == false) { + Global_Env *env = VM_Global_State::loader_env; + + if (si_is_native(si)) { + m2n_set_last_frame(prev_m2n); + + if ((interpreter_enabled() || (!prev_m2n) + || (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) { + exn_raise_by_class(env->java_lang_StackOverflowError_Class); + } else { + si_free(si); + exn_throw_by_class(env->java_lang_StackOverflowError_Class); + } + } else { + si_free(si); + exn_throw_by_class(env->java_lang_StackOverflowError_Class); + } + } + } + if (!si_is_native(si)) { CodeChunkInfo* catch_cci = si_get_code_chunk_info(si); Index: vm/vmcore/src/util/linux/signals_ia32.cpp =================================================================== --- vm/vmcore/src/util/linux/signals_ia32.cpp (revision 599441) +++ vm/vmcore/src/util/linux/signals_ia32.cpp (working copy) @@ -414,15 +414,26 @@ set_guard_stack(); } -void set_guard_stack() { +size_t get_mem_protect_stack_size() { + return 0x0100; +} + +size_t get_restore_stack_size() { + return get_mem_protect_stack_size() + 0x0100; +} + +bool set_guard_stack() { int err; char* stack_addr = (char*) get_stack_addr(); size_t stack_size = get_stack_size(); size_t guard_stack_size = get_guard_stack_size(); size_t guard_page_size = get_guard_page_size(); - assert(((size_t)(&stack_addr)) > ((size_t)((char*)stack_addr - stack_size - + guard_stack_size + 2 * guard_page_size))); + if (((size_t)(&stack_addr) - get_mem_protect_stack_size()) + < ((size_t)((char*)stack_addr - stack_size + + guard_stack_size + 2 * guard_page_size))) { + return false; + } err = mprotect(stack_addr - stack_size + guard_page_size + guard_stack_size, guard_page_size, PROT_NONE ); @@ -444,6 +455,8 @@ // notify that stack is OK and there are no needs to restore it jthread_self_vm_thread_unsafe()->restore_guard_page = false; + + return true; } size_t get_available_stack_size() { @@ -483,10 +496,6 @@ } } -size_t get_restore_stack_size() { - return 0x0200; -} - bool check_stack_size_enough_for_exception_catch(void* sp) { char* stack_adrr = (char*) get_stack_addr(); size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)sp); Index: vm/vmcore/src/util/linux/signals_em64t.cpp =================================================================== --- vm/vmcore/src/util/linux/signals_em64t.cpp (revision 599441) +++ vm/vmcore/src/util/linux/signals_em64t.cpp (working copy) @@ -320,8 +320,6 @@ return common_guard_page_size; } -void set_guard_stack(); - void init_stack_info() { vm_thread_t vm_thread = jthread_self_vm_thread_unsafe(); char* stack_addr = (char *)find_stack_addr(); @@ -363,15 +361,26 @@ set_guard_stack(); } -void set_guard_stack() { +size_t get_mem_protect_stack_size() { + return 0x0400; +} + +size_t get_restore_stack_size() { + return get_mem_protect_stack_size() + 0x0400; +} + +bool set_guard_stack() { int err; char* stack_addr = (char*) get_stack_addr(); size_t stack_size = get_stack_size(); size_t guard_stack_size = get_guard_stack_size(); size_t guard_page_size = get_guard_page_size(); - assert(((size_t)(&stack_addr)) > ((size_t)((char*)stack_addr - stack_size - + guard_stack_size + 2 * guard_page_size))); + if (((size_t)(&stack_addr) - get_mem_protect_stack_size()) + < ((size_t)((char*)stack_addr - stack_size + + guard_stack_size + 2 * guard_page_size))) { + return false; + } err = mprotect(stack_addr - stack_size + guard_page_size + guard_stack_size, guard_page_size, PROT_NONE); @@ -384,6 +393,8 @@ err = sigaltstack (&sigalt, NULL); jthread_self_vm_thread_unsafe()->restore_guard_page = false; + + return true; } size_t get_available_stack_size() { @@ -420,10 +431,6 @@ } } -size_t get_restore_stack_size() { - return 0x0800; -} - bool check_stack_size_enough_for_exception_catch(void* sp) { char* stack_adrr = (char*) get_stack_addr(); size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)sp); 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 599441) +++ vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp (working copy) @@ -169,17 +169,24 @@ # endif } -void set_guard_stack() { +size_t get_mem_protect_stack_size() { + return 0x0100; +} + +size_t get_restore_stack_size() { + return get_mem_protect_stack_size() + 0x0100; +} + +bool set_guard_stack() { void* stack_addr = get_stack_addr(); size_t stack_size = get_stack_size(); size_t page_size = get_guard_page_size(); size_t guard_stack_size = get_guard_stack_size(); - //assert(((size_t)(&stack_addr)) > ((size_t)((char*)stack_addr - stack_size + 2 * page_size + guard_stack_size))); - if (((size_t)(&stack_addr)) < ((size_t)((char*)stack_addr - stack_size + 2 * page_size + guard_stack_size))) { - Global_Env *env = VM_Global_State::loader_env; - exn_raise_by_class(env->java_lang_StackOverflowError_Class); - return; + if (((size_t)(&stack_addr) - get_mem_protect_stack_size()) + < ((size_t)((char*)stack_addr - stack_size + + 2 * page_size + guard_stack_size))) { + return false; } if (!VirtualFree((char*)stack_addr - stack_size + page_size, @@ -194,6 +201,8 @@ assert(0); } jthread_self_vm_thread_unsafe()->restore_guard_page = false; + + return true; } void remove_guard_stack() { @@ -257,10 +266,6 @@ } } -size_t get_restore_stack_size() { - return 0x0200; -} - bool check_stack_size_enough_for_exception_catch(void* sp) { char* stack_adrr = (char*) get_stack_addr(); size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)sp);