From 4be6784af4c150a840239673c2d6af27d048099c Mon Sep 17 00:00:00 2001 From: kevinw Date: Mon, 26 Jun 2017 02:04:40 -0700 Subject: [PATCH] 8161598: Kitchensink fails: assert(nm->insts_contains(original_pc)) failed: original PC must be in nmethod/CompiledMethod Reviewed-by: dlong --- src/cpu/x86/vm/c1_Runtime1_x86.cpp | 4 +-- src/cpu/x86/vm/frame_x86.cpp | 31 ++++++++++++++++--- src/cpu/x86/vm/frame_x86.inline.hpp | 1 + src/cpu/x86/vm/javaFrameAnchor_x86.hpp | 7 ++--- src/cpu/x86/vm/macroAssembler_x86.cpp | 16 +++++----- src/cpu/x86/vm/macroAssembler_x86.hpp | 4 +-- src/cpu/x86/vm/runtime_x86_32.cpp | 2 +- src/cpu/x86/vm/sharedRuntime_x86_32.cpp | 16 +++++----- src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 18 +++++------ src/cpu/x86/vm/stubGenerator_x86_32.cpp | 2 +- src/cpu/x86/vm/stubGenerator_x86_64.cpp | 2 +- src/cpu/x86/vm/templateInterpreter_x86_32.cpp | 4 +-- src/cpu/x86/vm/templateInterpreter_x86_64.cpp | 4 +-- src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp | 2 +- src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp | 8 ++--- src/os_cpu/linux_x86/vm/thread_linux_x86.cpp | 2 +- src/os_cpu/linux_x86/vm/thread_linux_x86.hpp | 8 ++--- .../solaris_x86/vm/thread_solaris_x86.cpp | 5 ++- .../solaris_x86/vm/thread_solaris_x86.hpp | 8 ++--- .../windows_x86/vm/thread_windows_x86.cpp | 2 +- .../windows_x86/vm/thread_windows_x86.hpp | 8 ++--- 21 files changed, 78 insertions(+), 76 deletions(-) diff --git a/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/src/cpu/x86/vm/c1_Runtime1_x86.cpp index 9810f6e1c..aaa79642d 100644 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -98,7 +98,7 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result, addre } pop(rax); #endif - reset_last_Java_frame(thread, true, align_stack); + reset_last_Java_frame(thread, true); // discard thread and arguments NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); @@ -882,7 +882,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { } __ pop(rax); #endif - __ reset_last_Java_frame(thread, true, false); + __ reset_last_Java_frame(thread, true); #ifndef _LP64 __ pop(rcx); // discard thread arg __ pop(rcx); // discard dummy diff --git a/src/cpu/x86/vm/frame_x86.cpp b/src/cpu/x86/vm/frame_x86.cpp index 1a3364313..4cadc43ca 100644 --- a/src/cpu/x86/vm/frame_x86.cpp +++ b/src/cpu/x86/vm/frame_x86.cpp @@ -370,13 +370,16 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const { JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor(); assert(!entry_frame_is_first(), "next Java fp must be non zero"); assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); + // Since we are walking the stack now this nested anchor is obviously walkable + // even if it wasn't when it was stacked. + if (!jfa->walkable()) { + // Capture _last_Java_pc (if needed) and mark anchor walkable. + jfa->capture_last_Java_pc(); + } map->clear(); assert(map->include_argument_oops(), "should be set by clear"); - if (jfa->last_Java_pc() != NULL ) { - frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc()); - return fr; - } - frame fr(jfa->last_Java_sp(), jfa->last_Java_fp()); + assert(jfa->last_Java_pc() != NULL, "not walkable"); + frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc()); return fr; } @@ -714,3 +717,21 @@ frame::frame(void* sp, void* fp, void* pc) { init((intptr_t*)sp, (intptr_t*)fp, (address)pc); } #endif + +void JavaFrameAnchor::make_walkable(JavaThread* thread) { + // last frame set? + if (last_Java_sp() == NULL) return; + // already walkable? + if (walkable()) return; + assert(Thread::current() == (Thread*)thread, "not current thread"); + assert(last_Java_sp() != NULL, "not called from Java code?"); + assert(last_Java_pc() == NULL, "already walkable"); + capture_last_Java_pc(); + assert(walkable(), "something went wrong"); +} + +void JavaFrameAnchor::capture_last_Java_pc() { + assert(_last_Java_sp != NULL, "no last frame set"); + assert(_last_Java_pc == NULL, "already walkable"); + _last_Java_pc = (address)_last_Java_sp[-1]; +} diff --git a/src/cpu/x86/vm/frame_x86.inline.hpp b/src/cpu/x86/vm/frame_x86.inline.hpp index a2649fdb1..325f78008 100644 --- a/src/cpu/x86/vm/frame_x86.inline.hpp +++ b/src/cpu/x86/vm/frame_x86.inline.hpp @@ -96,6 +96,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) { // call a specialized frame constructor instead of this one. // Then we could use the assert below. However this assert is of somewhat dubious // value. + // UPDATE: this constructor is only used by trace_method_handle_stub() now. // assert(_pc != NULL, "no pc?"); _cb = CodeCache::find_blob(_pc); diff --git a/src/cpu/x86/vm/javaFrameAnchor_x86.hpp b/src/cpu/x86/vm/javaFrameAnchor_x86.hpp index 77298e537..40eedf019 100644 --- a/src/cpu/x86/vm/javaFrameAnchor_x86.hpp +++ b/src/cpu/x86/vm/javaFrameAnchor_x86.hpp @@ -62,10 +62,9 @@ public: _last_Java_sp = src->_last_Java_sp; } - // Always walkable - bool walkable(void) { return true; } - // Never any thing to do since we are always walkable and can find address of return addresses - void make_walkable(JavaThread* thread) { } + bool walkable(void) { return _last_Java_sp != NULL && _last_Java_pc != NULL; } + void make_walkable(JavaThread* thread); + void capture_last_Java_pc(void); intptr_t* last_Java_sp(void) const { return _last_Java_sp; } diff --git a/src/cpu/x86/vm/macroAssembler_x86.cpp b/src/cpu/x86/vm/macroAssembler_x86.cpp index 30490d451..9711089a4 100644 --- a/src/cpu/x86/vm/macroAssembler_x86.cpp +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp @@ -748,8 +748,7 @@ void MacroAssembler::pushptr(AddressLiteral src) { } } -void MacroAssembler::reset_last_Java_frame(bool clear_fp, - bool clear_pc) { +void MacroAssembler::reset_last_Java_frame(bool clear_fp) { // we must set sp to zero to clear frame movptr(Address(r15_thread, JavaThread::last_Java_sp_offset()), NULL_WORD); // must clear fp, so that compiled frames are not confused; it is @@ -758,9 +757,8 @@ void MacroAssembler::reset_last_Java_frame(bool clear_fp, movptr(Address(r15_thread, JavaThread::last_Java_fp_offset()), NULL_WORD); } - if (clear_pc) { - movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); - } + // Always clear the pc because it could have been set by make_walkable() + movptr(Address(r15_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); } void MacroAssembler::set_last_Java_frame(Register last_java_sp, @@ -2561,7 +2559,7 @@ void MacroAssembler::call_VM_base(Register oop_result, } // reset last Java frame // Only interpreter should have to clear fp - reset_last_Java_frame(java_thread, true, false); + reset_last_Java_frame(java_thread, true); #ifndef CC_INTERP // C++ interp handles this in the interpreter @@ -3808,7 +3806,7 @@ void MacroAssembler::push_IU_state() { pusha(); } -void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, bool clear_pc) { +void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp) { // determine java_thread register if (!java_thread->is_valid()) { java_thread = rdi; @@ -3820,8 +3818,8 @@ void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp, movptr(Address(java_thread, JavaThread::last_Java_fp_offset()), NULL_WORD); } - if (clear_pc) - movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); + // Always clear the pc because it could have been set by make_walkable() + movptr(Address(java_thread, JavaThread::last_Java_pc_offset()), NULL_WORD); } diff --git a/src/cpu/x86/vm/macroAssembler_x86.hpp b/src/cpu/x86/vm/macroAssembler_x86.hpp index cc5e5856a..b82705626 100644 --- a/src/cpu/x86/vm/macroAssembler_x86.hpp +++ b/src/cpu/x86/vm/macroAssembler_x86.hpp @@ -289,10 +289,10 @@ class MacroAssembler: public Assembler { Register last_java_fp, address last_java_pc); - void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc); + void reset_last_Java_frame(Register thread, bool clear_fp); // thread in the default location (r15_thread on 64bit) - void reset_last_Java_frame(bool clear_fp, bool clear_pc); + void reset_last_Java_frame(bool clear_fp); // Stores void store_check(Register obj); // store check for obj - register is destroyed afterwards diff --git a/src/cpu/x86/vm/runtime_x86_32.cpp b/src/cpu/x86/vm/runtime_x86_32.cpp index 36457cb81..45110b6a0 100644 --- a/src/cpu/x86/vm/runtime_x86_32.cpp +++ b/src/cpu/x86/vm/runtime_x86_32.cpp @@ -116,7 +116,7 @@ void OptoRuntime::generate_exception_blob() { // No registers to map, rbp is known implicitly oop_maps->add_gc_map( __ pc() - start, new OopMap( framesize, 0 )); __ get_thread(rcx); - __ reset_last_Java_frame(rcx, false, false); + __ reset_last_Java_frame(rcx, false); // Restore callee-saved registers __ movptr(rbp, Address(rsp, rbp_off * wordSize)); diff --git a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp index c97b43097..34418682b 100644 --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp @@ -1333,7 +1333,7 @@ static void check_needs_gc_for_critical_native(MacroAssembler* masm, __ increment(rsp, wordSize); __ get_thread(thread); - __ reset_last_Java_frame(thread, false, true); + __ reset_last_Java_frame(thread, false); save_or_restore_arguments(masm, stack_slots, total_in_args, arg_save_area, NULL, in_regs, in_sig_bt); @@ -2251,7 +2251,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // We can finally stop using that last_Java_frame we setup ages ago - __ reset_last_Java_frame(thread, false, true); + __ reset_last_Java_frame(thread, false); // Unpack oop result if (ret_type == T_OBJECT || ret_type == T_ARRAY) { @@ -2951,7 +2951,7 @@ void SharedRuntime::generate_deopt_blob() { __ pop(rcx); __ get_thread(rcx); - __ reset_last_Java_frame(rcx, false, false); + __ reset_last_Java_frame(rcx, false); // Load UnrollBlock into EDI __ mov(rdi, rax); @@ -3117,7 +3117,7 @@ void SharedRuntime::generate_deopt_blob() { __ push(rax); __ get_thread(rcx); - __ reset_last_Java_frame(rcx, false, false); + __ reset_last_Java_frame(rcx, false); // Collect return values __ movptr(rax,Address(rsp, (RegisterSaver::raxOffset() + additional_words + 1)*wordSize)); @@ -3219,7 +3219,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ get_thread(rcx); - __ reset_last_Java_frame(rcx, false, false); + __ reset_last_Java_frame(rcx, false); // Load UnrollBlock into EDI __ movptr(rdi, rax); @@ -3331,7 +3331,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { oop_maps->add_gc_map( __ pc()-start, new OopMap( framesize, 0 ) ); __ get_thread(rdi); - __ reset_last_Java_frame(rdi, true, false); + __ reset_last_Java_frame(rdi, true); // Pop self-frame. __ leave(); // Epilog! @@ -3426,7 +3426,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t // Clear last_Java_sp again __ get_thread(java_thread); - __ reset_last_Java_frame(java_thread, false, false); + __ reset_last_Java_frame(java_thread, false); __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, noException); @@ -3501,7 +3501,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha __ addptr(rsp, wordSize); // clear last_Java_sp - __ reset_last_Java_frame(thread, true, false); + __ reset_last_Java_frame(thread, true); // check for pending exceptions Label pending; __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); diff --git a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index a3eb504c0..39a880b5e 100644 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -1388,7 +1388,7 @@ static void check_needs_gc_for_critical_native(MacroAssembler* masm, __ mov(rsp, r12); // restore sp __ reinit_heapbase(); - __ reset_last_Java_frame(false, true); + __ reset_last_Java_frame(false); save_or_restore_arguments(masm, stack_slots, total_in_args, arg_save_area, NULL, in_regs, in_sig_bt); @@ -2497,7 +2497,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, restore_native_result(masm, ret_type, stack_slots); } - __ reset_last_Java_frame(false, true); + __ reset_last_Java_frame(false); // Unpack oop result if (ret_type == T_OBJECT || ret_type == T_ARRAY) { @@ -3435,7 +3435,7 @@ void SharedRuntime::generate_deopt_blob() { // find any register it might need. oop_maps->add_gc_map(__ pc() - start, map); - __ reset_last_Java_frame(false, false); + __ reset_last_Java_frame(false); // Load UnrollBlock* into rdi __ mov(rdi, rax); @@ -3592,7 +3592,7 @@ void SharedRuntime::generate_deopt_blob() { new OopMap( frame_size_in_words, 0 )); // Clear fp AND pc - __ reset_last_Java_frame(true, true); + __ reset_last_Java_frame(true); // Collect return values __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes())); @@ -3662,7 +3662,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { oop_maps->add_gc_map(__ pc() - start, map); - __ reset_last_Java_frame(false, false); + __ reset_last_Java_frame(false); // Load UnrollBlock* into rdi __ mov(rdi, rax); @@ -3775,7 +3775,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0)); // Clear fp AND pc - __ reset_last_Java_frame(true, true); + __ reset_last_Java_frame(true); // Pop self-frame. __ leave(); // Epilog @@ -3858,7 +3858,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t Label noException; - __ reset_last_Java_frame(false, false); + __ reset_last_Java_frame(false); __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); __ jcc(Assembler::equal, noException); @@ -3928,7 +3928,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha // rax contains the address we are going to jump to assuming no exception got installed // clear last_Java_sp - __ reset_last_Java_frame(false, false); + __ reset_last_Java_frame(false); // check for pending exceptions Label pending; __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); @@ -4309,7 +4309,7 @@ void OptoRuntime::generate_exception_blob() { oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0)); - __ reset_last_Java_frame(false, true); + __ reset_last_Java_frame(false); // Restore callee-saved registers diff --git a/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 5387ba184..50a06d7a5 100644 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -2901,7 +2901,7 @@ class StubGenerator: public StubCodeGenerator { // however can use the register value directly if it is callee saved. __ get_thread(java_thread); - __ reset_last_Java_frame(java_thread, true, false); + __ reset_last_Java_frame(java_thread, true); __ leave(); // required for proper stackwalking of RuntimeStub frame diff --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 01fe4b8c5..1d38af799 100644 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -3923,7 +3923,7 @@ class StubGenerator: public StubCodeGenerator { oop_maps->add_gc_map(the_pc - start, map); - __ reset_last_Java_frame(true, true); + __ reset_last_Java_frame(true); __ leave(); // required for proper stackwalking of RuntimeStub frame diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index dfe431a7b..4d94902ee 100644 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -1289,7 +1289,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { // change thread state __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_Java); - __ reset_last_Java_frame(thread, true, true); + __ reset_last_Java_frame(thread, true); // reset handle block __ movptr(t, Address(thread, JavaThread::active_handles_offset())); @@ -1819,7 +1819,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ set_last_Java_frame(thread, noreg, rbp, __ pc()); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), thread, rax, rbx); __ get_thread(thread); - __ reset_last_Java_frame(thread, true, true); + __ reset_last_Java_frame(thread, true); // Restore the last_sp and null it out __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); diff --git a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index 156cbe95d..121738292 100644 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -1262,7 +1262,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) { __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); // reset_last_Java_frame - __ reset_last_Java_frame(true, true); + __ reset_last_Java_frame(r15_thread, true); // reset handle block __ movptr(t, Address(r15_thread, JavaThread::active_handles_offset())); @@ -1837,7 +1837,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // PC must point into interpreter here __ set_last_Java_frame(noreg, rbp, __ pc()); __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2); - __ reset_last_Java_frame(true, true); + __ reset_last_Java_frame(r15_thread, true); // Restore the last_sp and null it out __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); diff --git a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp index 8d167adaf..628895649 100644 --- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp +++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp @@ -44,7 +44,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) // If we have a last_Java_frame, then we should use it even if // isInJava == true. It should be more reliable than ucontext info. - if (jt->has_last_Java_frame()) { + if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { *fr_addr = jt->pd_last_frame(); return true; } diff --git a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp index 1d7921c71..b3bc5b6be 100644 --- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp +++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp @@ -32,12 +32,8 @@ frame pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - if (_anchor.last_Java_pc() != NULL) { - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); - } else { - // This will pick up pc from sp - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp()); - } + assert(_anchor.last_Java_pc() != NULL, "not walkable"); + return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); } public: diff --git a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp index 77affdd52..2995b3c81 100644 --- a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp +++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp @@ -45,7 +45,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) // If we have a last_Java_frame, then we should use it even if // isInJava == true. It should be more reliable than ucontext info. - if (jt->has_last_Java_frame()) { + if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { *fr_addr = jt->pd_last_frame(); return true; } diff --git a/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp b/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp index 75fb7df57..bd8cc5a5e 100644 --- a/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp +++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp @@ -32,12 +32,8 @@ frame pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - if (_anchor.last_Java_pc() != NULL) { - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); - } else { - // This will pick up pc from sp - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp()); - } + assert(_anchor.last_Java_pc() != NULL, "not walkable"); + return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); } public: diff --git a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp index 3007c6bee..b7a8b11d2 100644 --- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp +++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp @@ -44,9 +44,8 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, assert(this->is_Java_thread(), "must be JavaThread"); JavaThread* jt = (JavaThread *)this; - // last_Java_frame is always walkable and safe use it if we have it - - if (jt->has_last_Java_frame()) { + // There is small window where last_Java_frame is not walkable or safe + if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { *fr_addr = jt->pd_last_frame(); return true; } diff --git a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp index 7589a81a8..8484912d7 100644 --- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp +++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp @@ -30,12 +30,8 @@ frame pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - if (_anchor.last_Java_pc() != NULL) { - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); - } else { - // This will pick up pc from sp - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp()); - } + assert(_anchor.last_Java_pc() != NULL, "not walkable"); + return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); } public: diff --git a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp index 7180fe1d9..95f47a680 100644 --- a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp +++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp @@ -47,7 +47,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) // If we have a last_Java_frame, then we should use it even if // isInJava == true. It should be more reliable than CONTEXT info. - if (jt->has_last_Java_frame()) { + if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { *fr_addr = jt->pd_last_frame(); return true; } diff --git a/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp b/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp index 65aac3510..e3350e8a6 100644 --- a/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp +++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp @@ -32,12 +32,8 @@ frame pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - if (_anchor.last_Java_pc() != NULL) { - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); - } else { - // This will pick up pc from sp - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp()); - } + assert(_anchor.last_Java_pc() != NULL, "not walkable"); + return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); } public: -- GitLab