# HG changeset patch # User asaha # Date 1500057322 25200 # Node ID 7bcf6e0c266c9ce1eb4cb26e066b7fe858be5c6a # Parent 01b347e2b10b2d8009557e2fd612005b7ff73a3d# Parent 7245ee7fa44a8855305f04015f5b7cc581e41cb4 Merge diff -r 01b347e2b10b -r 7bcf6e0c266c .hgtags --- a/.hgtags Fri Jul 14 11:00:50 2017 -0700 +++ b/.hgtags Fri Jul 14 11:35:22 2017 -0700 @@ -985,6 +985,8 @@ df6af363337eff5b22ae7940b0981231fdf5dfb4 jdk8u141-b13 3a1543e089c32592be9c201c6e021295fbf5fdc1 jdk8u141-b14 23f1790147d838ddb1133cc79dc08e7c9ba5ab44 jdk8u141-b15 +9ffa0d7ed932045a0b4ceb095fb52444eed39c1b jdk8u141-b31 +ae8cae699f62b845703c891e0e7633e2089a3ec4 jdk8u141-b32 2d5100bddeb80cf767485b787fc3051311e3d7b9 jdk8u151-b00 596b584c68b73ec635347807571463580deb955f jdk8u151-b01 1f6f436360d5cd375b806aec1c78abb8fcb4e5f6 jdk8u151-b02 diff -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -98,7 +98,7 @@ } 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 @@ } __ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/frame_x86.cpp --- a/src/cpu/x86/vm/frame_x86.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/frame_x86.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -370,13 +370,16 @@ 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 @@ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/frame_x86.inline.hpp --- a/src/cpu/x86/vm/frame_x86.inline.hpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/frame_x86.inline.hpp Fri Jul 14 11:35:22 2017 -0700 @@ -96,6 +96,7 @@ // 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/javaFrameAnchor_x86.hpp --- a/src/cpu/x86/vm/javaFrameAnchor_x86.hpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/javaFrameAnchor_x86.hpp Fri Jul 14 11:35:22 2017 -0700 @@ -62,10 +62,9 @@ _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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/macroAssembler_x86.cpp --- a/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -748,8 +748,7 @@ } } -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 @@ 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 @@ } // 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 @@ 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 @@ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/macroAssembler_x86.hpp --- a/src/cpu/x86/vm/macroAssembler_x86.hpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/macroAssembler_x86.hpp Fri Jul 14 11:35:22 2017 -0700 @@ -289,10 +289,10 @@ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/runtime_x86_32.cpp --- a/src/cpu/x86/vm/runtime_x86_32.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/runtime_x86_32.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -116,7 +116,7 @@ // 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -1333,7 +1333,7 @@ __ 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 @@ // 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 @@ __ 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 @@ __ 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 @@ __ 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 @@ 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 @@ // 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 @@ __ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -1388,7 +1388,7 @@ __ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/stubGenerator_x86_32.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -2901,7 +2901,7 @@ // 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/stubGenerator_x86_64.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -3923,7 +3923,7 @@ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -1289,7 +1289,7 @@ // 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 @@ __ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -1262,7 +1262,7 @@ __ 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 @@ // 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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp --- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -44,7 +44,7 @@ // 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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp --- a/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp Fri Jul 14 11:35:22 2017 -0700 @@ -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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/linux_x86/vm/thread_linux_x86.cpp --- a/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -45,7 +45,7 @@ // 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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/linux_x86/vm/thread_linux_x86.hpp --- a/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp Fri Jul 14 11:35:22 2017 -0700 @@ -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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp --- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -44,9 +44,8 @@ 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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp --- a/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp Fri Jul 14 11:35:22 2017 -0700 @@ -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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/windows_x86/vm/thread_windows_x86.cpp --- a/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -47,7 +47,7 @@ // 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 -r 01b347e2b10b -r 7bcf6e0c266c src/os_cpu/windows_x86/vm/thread_windows_x86.hpp --- a/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp Fri Jul 14 11:35:22 2017 -0700 @@ -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 -r 01b347e2b10b -r 7bcf6e0c266c src/share/vm/services/lowMemoryDetector.cpp --- a/src/share/vm/services/lowMemoryDetector.cpp Fri Jul 14 11:00:50 2017 -0700 +++ b/src/share/vm/services/lowMemoryDetector.cpp Fri Jul 14 11:35:22 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -298,19 +298,41 @@ Klass* k = Management::sun_management_Sensor_klass(CHECK); instanceKlassHandle sensorKlass (THREAD, k); Handle sensor_h(THREAD, _sensor_obj); - Handle usage_h = MemoryService::create_MemoryUsage_obj(_usage, CHECK); + + Symbol* trigger_method_signature; JavaValue result(T_VOID); JavaCallArguments args(sensor_h); args.push_int((int) count); - args.push_oop(usage_h); + + Handle usage_h = MemoryService::create_MemoryUsage_obj(_usage, THREAD); + // Call Sensor::trigger(int, MemoryUsage) to send notification to listeners. + // When OOME occurs and fails to allocate MemoryUsage object, call + // Sensor::trigger(int) instead. The pending request will be processed + // but no notification will be sent. + if (HAS_PENDING_EXCEPTION) { + assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOME here"); + CLEAR_PENDING_EXCEPTION; + trigger_method_signature = vmSymbols::int_void_signature(); + } else { + trigger_method_signature = vmSymbols::trigger_method_signature(); + args.push_oop(usage_h); + } JavaCalls::call_virtual(&result, sensorKlass, vmSymbols::trigger_name(), - vmSymbols::trigger_method_signature(), + trigger_method_signature, &args, - CHECK); + THREAD); + + if (HAS_PENDING_EXCEPTION) { + // We just clear the OOM pending exception that we might have encountered + // in Java's tiggerAction(), and continue with updating the counters since + // the Java counters have been updated too. + assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOME here"); + CLEAR_PENDING_EXCEPTION; + } } {