changeset 2886:cec1757a0134

7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely Reviewed-by: never, bdelsart
author twisti
date Thu, 27 Oct 2011 04:43:37 -0700
parents d8cb48376797
children e0658a9b3f87
files src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp src/cpu/sparc/vm/c1_Runtime1_sparc.cpp src/cpu/x86/vm/c1_CodeStubs_x86.cpp src/cpu/x86/vm/c1_Runtime1_x86.cpp src/share/vm/c1/c1_Runtime1.cpp src/share/vm/c1/c1_Runtime1.hpp src/share/vm/opto/runtime.cpp
diffstat 7 files changed, 55 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Wed Oct 26 06:08:56 2011 -0700
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Thu Oct 27 04:43:37 2011 -0700
@@ -367,10 +367,10 @@
 
 void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
-  __ call(SharedRuntime::deopt_blob()->unpack_with_reexecution());
+  __ call(Runtime1::entry_for(Runtime1::deoptimize_id), relocInfo::runtime_call_type);
   __ delayed()->nop();
   ce->add_call_info_here(_info);
-  debug_only(__ should_not_reach_here());
+  DEBUG_ONLY(__ should_not_reach_here());
 }
 
 
--- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Wed Oct 26 06:08:56 2011 -0700
+++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu Oct 27 04:43:37 2011 -0700
@@ -766,7 +766,22 @@
 
         __ ret();
         __ delayed()->restore();
+      }
+      break;
 
+    case deoptimize_id:
+      {
+        __ set_info("deoptimize", dont_gc_arguments);
+        OopMap* oop_map = save_live_registers(sasm);
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize));
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, oop_map);
+        restore_live_registers(sasm);
+        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
+        assert(deopt_blob != NULL, "deoptimization blob must have been created");
+        AddressLiteral dest(deopt_blob->unpack_with_reexecution());
+        __ jump_to(dest, O0);
+        __ delayed()->restore();
       }
       break;
 
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Wed Oct 26 06:08:56 2011 -0700
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Thu Oct 27 04:43:37 2011 -0700
@@ -387,9 +387,9 @@
 
 void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
-  __ call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack_with_reexecution()));
+  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id)));
   ce->add_call_info_here(_info);
-  debug_only(__ should_not_reach_here());
+  DEBUG_ONLY(__ should_not_reach_here());
 }
 
 
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Wed Oct 26 06:08:56 2011 -0700
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Oct 27 04:43:37 2011 -0700
@@ -1447,7 +1447,22 @@
         oop_maps = new OopMapSet();
         oop_maps->add_gc_map(call_offset, map);
         restore_live_registers(sasm, save_fpu_registers);
+      }
+      break;
 
+    case deoptimize_id:
+      {
+        StubFrame f(sasm, "deoptimize", dont_gc_arguments);
+        const int num_rt_args = 1;  // thread
+        OopMap* oop_map = save_live_registers(sasm, num_rt_args);
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize));
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, oop_map);
+        restore_live_registers(sasm);
+        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
+        assert(deopt_blob != NULL, "deoptimization blob must have been created");
+        __ leave();
+        __ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
       }
       break;
 
--- a/src/share/vm/c1/c1_Runtime1.cpp	Wed Oct 26 06:08:56 2011 -0700
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Thu Oct 27 04:43:37 2011 -0700
@@ -681,6 +681,23 @@
   }
 JRT_END
 
+// Cf. OptoRuntime::deoptimize_caller_frame
+JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* thread))
+  // Called from within the owner thread, so no need for safepoint
+  RegisterMap reg_map(thread, false);
+  frame stub_frame = thread->last_frame();
+  assert(stub_frame.is_runtime_frame(), "sanity check");
+  frame caller_frame = stub_frame.sender(&reg_map);
+
+  // We are coming from a compiled method; check this is true.
+  assert(CodeCache::find_nmethod(caller_frame.pc()) != NULL, "sanity");
+
+  // Deoptimize the caller frame.
+  Deoptimization::deoptimize_frame(thread, caller_frame.id());
+
+  // Return to the now deoptimized frame.
+JRT_END
+
 
 static klassOop resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
   Bytecode_field field_access(caller, bci);
--- a/src/share/vm/c1/c1_Runtime1.hpp	Wed Oct 26 06:08:56 2011 -0700
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Thu Oct 27 04:43:37 2011 -0700
@@ -63,6 +63,7 @@
   stub(monitorenter_nofpu)             /* optimized version that does not preserve fpu registers */ \
   stub(monitorexit)                  \
   stub(monitorexit_nofpu)              /* optimized version that does not preserve fpu registers */ \
+  stub(deoptimize)                   \
   stub(access_field_patching)        \
   stub(load_klass_patching)          \
   stub(g1_pre_barrier_slow)          \
@@ -152,6 +153,8 @@
   static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock);
   static void monitorexit (JavaThread* thread, BasicObjectLock* lock);
 
+  static void deoptimize(JavaThread* thread);
+
   static int access_field_patching(JavaThread* thread);
   static int move_klass_patching(JavaThread* thread);
 
--- a/src/share/vm/opto/runtime.cpp	Wed Oct 26 06:08:56 2011 -0700
+++ b/src/share/vm/opto/runtime.cpp	Thu Oct 27 04:43:37 2011 -0700
@@ -1130,7 +1130,7 @@
     assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
     frame caller_frame = stub_frame.sender(&reg_map);
 
-    // bypass VM_DeoptimizeFrame and deoptimize the frame directly
+    // Deoptimize the caller frame.
     Deoptimization::deoptimize_frame(thread, caller_frame.id());
   }
 }