diff --git a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp index e155153045fbad190206fb6888079be5e1f74b07..a54b68c451384bbf11a243ce126d7e28d7ef83d3 100644 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp @@ -367,10 +367,10 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { 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()); } diff --git a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp index 23bf235d0b33ca20e686c389ce3aab4e94042d27..64f15e0b64a1107eac4017c7a890f73b10afe0d4 100644 --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp @@ -766,7 +766,22 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { __ 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; diff --git a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp index 5e2d7feb996d54097163176cd1f3ebd06dadc872..f276df9e537168d5505f8159e11eac947b7b828a 100644 --- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp +++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp @@ -387,9 +387,9 @@ void PatchingStub::emit_code(LIR_Assembler* ce) { 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()); } diff --git a/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/src/cpu/x86/vm/c1_Runtime1_x86.cpp index 9ad2e58c67bb29b4ef44a881cffc39073039a8e0..9d13221705802a0dedab7e91646f50c40f4bfed9 100644 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -1447,7 +1447,22 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { 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; diff --git a/src/share/vm/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp index 675d389933c7705d86c79ad609d0a716a97987c9..183be88c731c9e59c94581bed838dc6f4801f746 100644 --- a/src/share/vm/c1/c1_Runtime1.cpp +++ b/src/share/vm/c1/c1_Runtime1.cpp @@ -681,6 +681,23 @@ JRT_LEAF(void, Runtime1::monitorexit(JavaThread* thread, BasicObjectLock* lock)) } 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(®_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); diff --git a/src/share/vm/c1/c1_Runtime1.hpp b/src/share/vm/c1/c1_Runtime1.hpp index 5499740f1f4d7687d309c10962d71ea4824c983e..20325640bf1362cc78d65254ca5ac40f52097bb3 100644 --- a/src/share/vm/c1/c1_Runtime1.hpp +++ b/src/share/vm/c1/c1_Runtime1.hpp @@ -63,6 +63,7 @@ class StubAssembler; 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 @@ class Runtime1: public AllStatic { 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); diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp index 0c2f84c85b94723f9c282f999dd75e3b070f6205..46c90f49fd92c66d1b83af63782a58affcdfb1d8 100644 --- a/src/share/vm/opto/runtime.cpp +++ b/src/share/vm/opto/runtime.cpp @@ -1130,7 +1130,7 @@ void OptoRuntime::deoptimize_caller_frame(JavaThread *thread, bool doit) { assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check"); frame caller_frame = stub_frame.sender(®_map); - // bypass VM_DeoptimizeFrame and deoptimize the frame directly + // Deoptimize the caller frame. Deoptimization::deoptimize_frame(thread, caller_frame.id()); } }