< prev index next >

src/share/vm/runtime/frame.cpp

Print this page

        

@@ -142,32 +142,44 @@
 // the idealized value in the frame object. This undoes the magic conversion
 // that happens for deoptimized frames. In addition it makes the value the
 // 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 {
+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 {
   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;
   _cb = CodeCache::find_blob_unsafe(_pc);
 
< prev index next >