--- old/src/share/vm/runtime/frame.cpp 2016-10-25 10:40:09.468777720 +0200 +++ new/src/share/vm/runtime/frame.cpp 2016-10-25 10:40:09.420777688 +0200 @@ -144,28 +144,40 @@ // hardware would want to see in the native frame. The only user (at this point) // is deoptimization. It likely no one else should ever use it. -address frame::raw_pc() const { - if (is_deoptimized_frame()) { - nmethod* nm = cb()->as_nmethod_or_null(); - if (nm->is_method_handle_return(pc())) - return nm->deopt_mh_handler_begin() - pc_return_offset; - else - return nm->deopt_handler_begin() - pc_return_offset; +address frame::raw_pc(Thread* thread) const { + // On Intel the return_address is always the word on the stack + address ret_pc = *(address*)(sp() - 1); + if (SharedRuntime::is_memento_stack_trace_return_handler(ret_pc)) { + assert(thread->memento_original_return_address() != NULL, "memento original return address must be set if patched"); + return ret_pc; } else { - return (pc() - pc_return_offset); + if (is_deoptimized_frame()) { + nmethod* nm = cb()->as_nmethod_or_null(); + if (nm->is_method_handle_return(pc())) + return nm->deopt_mh_handler_begin() - pc_return_offset; + else + return nm->deopt_handler_begin() - pc_return_offset; + } else { + return (pc() - pc_return_offset); + } } } // Change the pc in a frame object. This does not change the actual pc in // actual frame. To do that use patch_pc. // -void frame::set_pc(address newpc ) { +void frame::set_pc(Thread* thread, address newpc) { #ifdef ASSERT if (_cb != NULL && _cb->is_nmethod()) { assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant violation"); } #endif // ASSERT + if (SharedRuntime::is_memento_stack_trace_return_handler(newpc)) { + newpc = thread->memento_original_return_address(); + assert(newpc != NULL, "memento original return address must be set if patched"); + } + // Unsafe to use the is_deoptimzed tester after changing pc _deopt_state = unknown; _pc = newpc;