--- old/src/share/vm/c1/c1_Runtime1.cpp 2011-10-21 04:46:39.346435664 -0700 +++ new/src/share/vm/c1/c1_Runtime1.cpp 2011-10-21 04:46:39.067090407 -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(®_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); --- old/src/share/vm/c1/c1_Runtime1.hpp 2011-10-21 04:46:40.646117302 -0700 +++ new/src/share/vm/c1/c1_Runtime1.hpp 2011-10-21 04:46:40.386022103 -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); --- old/src/share/vm/opto/runtime.cpp 2011-10-21 04:46:41.821976016 -0700 +++ new/src/share/vm/opto/runtime.cpp 2011-10-21 04:46:41.550796992 -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(®_map); - // bypass VM_DeoptimizeFrame and deoptimize the frame directly + // Deoptimize the caller frame. Deoptimization::deoptimize_frame(thread, caller_frame.id()); } } --- old/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp 2011-10-21 04:46:43.044344863 -0700 +++ new/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp 2011-10-21 04:46:42.776852406 -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()); } --- old/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp 2011-10-21 04:46:44.276441751 -0700 +++ new/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp 2011-10-21 04:46:44.008155167 -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; --- old/src/cpu/x86/vm/c1_CodeStubs_x86.cpp 2011-10-21 04:46:45.557613408 -0700 +++ new/src/cpu/x86/vm/c1_CodeStubs_x86.cpp 2011-10-21 04:46:45.283821588 -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()); } --- old/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2011-10-21 04:46:46.866770823 -0700 +++ new/src/cpu/x86/vm/c1_Runtime1_x86.cpp 2011-10-21 04:46:46.584481242 -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;