8005817: Shark: implement deoptimization support
authortwisti
Fri, 11 Jan 2013 16:47:23 -0800
changeset 15205 17da82a12ff4
parent 15204 a8960bf92b09
child 15206 b86a40ac02ff
8005817: Shark: implement deoptimization support Reviewed-by: twisti Contributed-by: Roman Kennke <rkennke@redhat.com>
hotspot/src/cpu/zero/vm/frame_zero.cpp
hotspot/src/cpu/zero/vm/frame_zero.inline.hpp
hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp
hotspot/src/share/vm/shark/sharkInvariants.hpp
hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp	Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp	Fri Jan 11 16:47:23 2013 -0800
@@ -98,10 +98,20 @@
 #endif // CC_INTERP
 
 void frame::patch_pc(Thread* thread, address pc) {
-  // We borrow this call to set the thread pointer in the interpreter
-  // state; the hook to set up deoptimized frames isn't supplied it.
-  assert(pc == NULL, "should be");
-  get_interpreterState()->set_thread((JavaThread *) thread);
+
+  if (pc != NULL) {
+    _cb = CodeCache::find_blob(pc);
+    SharkFrame* sharkframe = zeroframe()->as_shark_frame();
+    sharkframe->set_pc(pc);
+    _pc = pc;
+    _deopt_state = is_deoptimized;
+
+  } else {
+    // We borrow this call to set the thread pointer in the interpreter
+    // state; the hook to set up deoptimized frames isn't supplied it.
+    assert(pc == NULL, "should be");
+    get_interpreterState()->set_thread((JavaThread *) thread);
+  }
 }
 
 bool frame::safe_for_sender(JavaThread *thread) {
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Fri Jan 11 16:47:23 2013 -0800
@@ -45,27 +45,36 @@
   case ZeroFrame::ENTRY_FRAME:
     _pc = StubRoutines::call_stub_return_pc();
     _cb = NULL;
+    _deopt_state = not_deoptimized;
     break;
 
   case ZeroFrame::INTERPRETER_FRAME:
     _pc = NULL;
     _cb = NULL;
+    _deopt_state = not_deoptimized;
     break;
 
-  case ZeroFrame::SHARK_FRAME:
+  case ZeroFrame::SHARK_FRAME: {
     _pc = zero_sharkframe()->pc();
     _cb = CodeCache::find_blob_unsafe(pc());
+    address original_pc = nmethod::get_deopt_original_pc(this);
+    if (original_pc != NULL) {
+      _pc = original_pc;
+      _deopt_state = is_deoptimized;
+    } else {
+      _deopt_state = not_deoptimized;
+    }
     break;
-
+  }
   case ZeroFrame::FAKE_STUB_FRAME:
     _pc = NULL;
     _cb = NULL;
+    _deopt_state = not_deoptimized;
     break;
 
   default:
     ShouldNotReachHere();
   }
-  _deopt_state = not_deoptimized;
 }
 
 // Accessors
--- a/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Fri Jan 11 16:47:23 2013 -0800
@@ -68,6 +68,10 @@
     return (address) value_of_word(pc_off);
   }
 
+  void set_pc(address pc) const {
+    *((address*) addr_of_word(pc_off)) = pc;
+  }
+
   intptr_t* unextended_sp() const {
     return (intptr_t *) value_of_word(unextended_sp_off);
   }
--- a/hotspot/src/share/vm/shark/sharkInvariants.hpp	Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkInvariants.hpp	Fri Jan 11 16:47:23 2013 -0800
@@ -99,12 +99,14 @@
   DebugInformationRecorder* debug_info() const {
     return env()->debug_info();
   }
+  SharkCodeBuffer* code_buffer() const {
+    return builder()->code_buffer();
+  }
+
+ public:
   Dependencies* dependencies() const {
     return env()->dependencies();
   }
-  SharkCodeBuffer* code_buffer() const {
-    return builder()->code_buffer();
-  }
 
   // Commonly used classes
  protected:
--- a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Fri Jan 11 16:47:23 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Fri Jan 11 16:47:23 2013 -0800
@@ -1030,7 +1030,6 @@
       dest_method->holder() == java_lang_Object_klass())
     return dest_method;
 
-#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE
   // This code can replace a virtual call with a direct call if this
   // class is the only one in the entire set of loaded classes that
   // implements this method.  This makes the compiled code dependent
@@ -1064,6 +1063,8 @@
   if (monomorphic_target != NULL) {
     assert(!monomorphic_target->is_abstract(), "shouldn't be");
 
+    function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target);
+
     // Opto has a bunch of type checking here that I don't
     // understand.  It's to inhibit casting in one direction,
     // possibly because objects in Opto can have inexact
@@ -1097,7 +1098,6 @@
   // with non-monomorphic targets if the receiver has an exact
   // type.  We don't mark types this way, so we can't do this.
 
-#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE
 
   return NULL;
 }
@@ -1298,8 +1298,9 @@
 
   // Try to inline the call
   if (!call_is_virtual) {
-    if (SharkInliner::attempt_inline(call_method, current_state()))
+    if (SharkInliner::attempt_inline(call_method, current_state())) {
       return;
+    }
   }
 
   // Find the method we are calling