src/cpu/x86/vm/sharedRuntime_x86_32.cpp

Print this page




1776     restore_native_result(masm, ret_type, stack_slots);
1777   }
1778 
1779   // We can finally stop using that last_Java_frame we setup ages ago
1780 
1781   __ reset_last_Java_frame(thread, false, true);
1782 
1783   // Unpack oop result
1784   if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
1785       Label L;
1786       __ cmpptr(rax, (int32_t)NULL_WORD);
1787       __ jcc(Assembler::equal, L);
1788       __ movptr(rax, Address(rax, 0));
1789       __ bind(L);
1790       __ verify_oop(rax);
1791   }
1792 
1793   // reset handle block
1794   __ movptr(rcx, Address(thread, JavaThread::active_handles_offset()));
1795 
1796   __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
1797 
1798   // Any exception pending?
1799   __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
1800   __ jcc(Assembler::notEqual, exception_pending);
1801 
1802 
1803   // no exception, we're almost done
1804 
1805   // check that only result value is on FPU stack
1806   __ verify_FPU(ret_type == T_FLOAT || ret_type == T_DOUBLE ? 1 : 0, "native_wrapper normal exit");
1807 
1808   // Fixup floating pointer results so that result looks like a return from a compiled method
1809   if (ret_type == T_FLOAT) {
1810     if (UseSSE >= 1) {
1811       // Pop st0 and store as float and reload into xmm register
1812       __ fstp_s(Address(rbp, -4));
1813       __ movflt(xmm0, Address(rbp, -4));
1814     }
1815   } else if (ret_type == T_DOUBLE) {
1816     if (UseSSE >= 2) {


1848     __ jcc(Assembler::equal, L);
1849     __ stop("no pending exception allowed on exit from monitorenter");
1850     __ bind(L);
1851     }
1852 #endif
1853     __ jmp(lock_done);
1854 
1855     // END Slow path lock
1856 
1857     // BEGIN Slow path unlock
1858     __ bind(slow_path_unlock);
1859 
1860     // Slow path unlock
1861 
1862     if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) {
1863       save_native_result(masm, ret_type, stack_slots);
1864     }
1865     // Save pending exception around call to VM (which contains an EXCEPTION_MARK)
1866 
1867     __ pushptr(Address(thread, in_bytes(Thread::pending_exception_offset())));
1868     __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
1869 
1870 
1871     // should be a peal
1872     // +wordSize because of the push above
1873     __ lea(rax, Address(rbp, lock_slot_rbp_offset));
1874     __ push(rax);
1875 
1876     __ push(obj_reg);
1877     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C)));
1878     __ addptr(rsp, 2*wordSize);
1879 #ifdef ASSERT
1880     {
1881       Label L;
1882       __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
1883       __ jcc(Assembler::equal, L);
1884       __ stop("no pending exception allowed on exit complete_monitor_unlocking_C");
1885       __ bind(L);
1886     }
1887 #endif /* ASSERT */
1888 


2414   // make room on stack for the return address
2415   // It will be patched later with the throwing pc. The correct value is not
2416   // available now because loading it from memory would destroy registers.
2417   __ push(0);
2418 
2419   // Save everything in sight.
2420 
2421   // No need to update map as each call to save_live_registers will produce identical oopmap
2422   (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
2423 
2424   // Now it is safe to overwrite any register
2425 
2426   // store the correct deoptimization type
2427   __ push(Deoptimization::Unpack_exception);
2428 
2429   // load throwing pc from JavaThread and patch it as the return address
2430   // of the current frame. Then clear the field in JavaThread
2431   __ get_thread(rdi);
2432   __ movptr(rdx, Address(rdi, JavaThread::exception_pc_offset()));
2433   __ movptr(Address(rbp, wordSize), rdx);
2434   __ movptr(Address(rdi, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
2435 
2436 #ifdef ASSERT
2437   // verify that there is really an exception oop in JavaThread
2438   __ movptr(rax, Address(rdi, JavaThread::exception_oop_offset()));
2439   __ verify_oop(rax);
2440 
2441   // verify that there is no pending exception
2442   Label no_pending_exception;
2443   __ movptr(rax, Address(rdi, Thread::pending_exception_offset()));
2444   __ testptr(rax, rax);
2445   __ jcc(Assembler::zero, no_pending_exception);
2446   __ stop("must not have pending exception here");
2447   __ bind(no_pending_exception);
2448 #endif
2449 
2450   __ bind(cont);
2451 
2452   // Compiled code leaves the floating point stack dirty, empty it.
2453   __ empty_FPU_stack();
2454 


2472 
2473   __ get_thread(rcx);
2474   __ reset_last_Java_frame(rcx, false, false);
2475 
2476   // Load UnrollBlock into EDI
2477   __ mov(rdi, rax);
2478 
2479   // Move the unpack kind to a safe place in the UnrollBlock because
2480   // we are very short of registers
2481 
2482   Address unpack_kind(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes());
2483   // retrieve the deopt kind from where we left it.
2484   __ pop(rax);
2485   __ movl(unpack_kind, rax);                      // save the unpack_kind value
2486 
2487    Label noException;
2488   __ cmpl(rax, Deoptimization::Unpack_exception);   // Was exception pending?
2489   __ jcc(Assembler::notEqual, noException);
2490   __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset()));
2491   __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset()));
2492   __ movptr(Address(rcx, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
2493   __ movptr(Address(rcx, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
2494 
2495   __ verify_oop(rax);
2496 
2497   // Overwrite the result registers with the exception results.
2498   __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax);
2499   __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx);
2500 
2501   __ bind(noException);
2502 
2503   // Stack is back to only having register save data on the stack.
2504   // Now restore the result registers. Everything else is either dead or captured
2505   // in the vframeArray.
2506 
2507   RegisterSaver::restore_result_registers(masm);
2508 
2509   // All of the register save area has been popped of the stack. Only the
2510   // return address remains.
2511 
2512   // Pop all the frames we must move/replace.
2513   //


2565   __ subptr(rbx, 4*wordSize);           // we'll push pc and ebp by hand and
2566 #ifdef ASSERT
2567   __ push(0xDEADDEAD);                  // Make a recognizable pattern
2568   __ push(0xDEADDEAD);
2569 #else /* ASSERT */
2570   __ subptr(rsp, 2*wordSize);           // skip the "static long no_param"
2571 #endif /* ASSERT */
2572 #else /* CC_INTERP */
2573   __ subptr(rbx, 2*wordSize);           // we'll push pc and rbp, by hand
2574 #endif /* CC_INTERP */
2575   __ pushptr(Address(rcx, 0));          // save return address
2576   __ enter();                           // save old & set new rbp,
2577   __ subptr(rsp, rbx);                  // Prolog!
2578   __ movptr(rbx, sp_temp);              // sender's sp
2579 #ifdef CC_INTERP
2580   __ movptr(Address(rbp,
2581                   -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))),
2582           rbx); // Make it walkable
2583 #else /* CC_INTERP */
2584   // This value is corrected by layout_activation_impl
2585   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD );
2586   __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
2587 #endif /* CC_INTERP */
2588   __ movptr(sp_temp, rsp);              // pass to next frame
2589   __ addptr(rsi, wordSize);             // Bump array pointer (sizes)
2590   __ addptr(rcx, wordSize);             // Bump array pointer (pcs)
2591   __ decrementl(counter);             // decrement counter
2592   __ jcc(Assembler::notZero, loop);
2593   __ pushptr(Address(rcx, 0));          // save final return address
2594 
2595   // Re-push self-frame
2596   __ enter();                           // save old & set new rbp,
2597 
2598   //  Return address and rbp, are in place
2599   // We'll push additional args later. Just allocate a full sized
2600   // register save area
2601   __ subptr(rsp, (frame_size_in_words-additional_words - 2) * wordSize);
2602 
2603   // Restore frame locals after moving the frame
2604   __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax);
2605   __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx);


2785   __ subptr(rbx, 4*wordSize);           // we'll push pc and ebp by hand and
2786 #ifdef ASSERT
2787   __ push(0xDEADDEAD);                  // Make a recognizable pattern
2788   __ push(0xDEADDEAD);                  // (parm to RecursiveInterpreter...)
2789 #else /* ASSERT */
2790   __ subptr(rsp, 2*wordSize);           // skip the "static long no_param"
2791 #endif /* ASSERT */
2792 #else /* CC_INTERP */
2793   __ subptr(rbx, 2*wordSize);           // we'll push pc and rbp, by hand
2794 #endif /* CC_INTERP */
2795   __ pushptr(Address(rcx, 0));          // save return address
2796   __ enter();                           // save old & set new rbp,
2797   __ subptr(rsp, rbx);                  // Prolog!
2798   __ movptr(rbx, sp_temp);              // sender's sp
2799 #ifdef CC_INTERP
2800   __ movptr(Address(rbp,
2801                   -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))),
2802           rbx); // Make it walkable
2803 #else /* CC_INTERP */
2804   // This value is corrected by layout_activation_impl
2805   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD );
2806   __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
2807 #endif /* CC_INTERP */
2808   __ movptr(sp_temp, rsp);              // pass to next frame
2809   __ addptr(rsi, wordSize);             // Bump array pointer (sizes)
2810   __ addptr(rcx, wordSize);             // Bump array pointer (pcs)
2811   __ decrementl(counter);             // decrement counter
2812   __ jcc(Assembler::notZero, loop);
2813   __ pushptr(Address(rcx, 0));            // save final return address
2814 
2815   // Re-push self-frame
2816   __ enter();                           // save old & set new rbp,
2817   __ subptr(rsp, (framesize-2) * wordSize);   // Prolog!
2818 
2819 
2820   // set last_Java_sp, last_Java_fp
2821   __ get_thread(rdi);
2822   __ set_last_Java_frame(rdi, noreg, rbp, NULL);
2823 
2824   // Call C code.  Need thread but NOT official VM entry
2825   // crud.  We cannot block on this call, no GC can happen.  Call should


3003   __ movptr(rbx, Address(thread, JavaThread::vm_result_offset()));
3004   __ movptr(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx);
3005 
3006   __ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax);
3007 
3008   RegisterSaver::restore_live_registers(masm);
3009 
3010   // We are back the the original state on entry and ready to go.
3011 
3012   __ jmp(rax);
3013 
3014   // Pending exception after the safepoint
3015 
3016   __ bind(pending);
3017 
3018   RegisterSaver::restore_live_registers(masm);
3019 
3020   // exception pending => remove activation and forward to exception handler
3021 
3022   __ get_thread(thread);
3023   __ movptr(Address(thread, JavaThread::vm_result_offset()), (int32_t)NULL_WORD);
3024   __ movptr(rax, Address(thread, Thread::pending_exception_offset()));
3025   __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
3026 
3027   // -------------
3028   // make sure all code is generated
3029   masm->flush();
3030 
3031   // return the  blob
3032   // frame_size_words or bytes??
3033   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_words, oop_maps, true);
3034 }
3035 
3036 void SharedRuntime::generate_stubs() {
3037 
3038   _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method),
3039                                         "wrong_method_stub");
3040 
3041   _ic_miss_blob      = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss),
3042                                         "ic_miss_stub");
3043 




1776     restore_native_result(masm, ret_type, stack_slots);
1777   }
1778 
1779   // We can finally stop using that last_Java_frame we setup ages ago
1780 
1781   __ reset_last_Java_frame(thread, false, true);
1782 
1783   // Unpack oop result
1784   if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
1785       Label L;
1786       __ cmpptr(rax, (int32_t)NULL_WORD);
1787       __ jcc(Assembler::equal, L);
1788       __ movptr(rax, Address(rax, 0));
1789       __ bind(L);
1790       __ verify_oop(rax);
1791   }
1792 
1793   // reset handle block
1794   __ movptr(rcx, Address(thread, JavaThread::active_handles_offset()));
1795 
1796   __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
1797 
1798   // Any exception pending?
1799   __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
1800   __ jcc(Assembler::notEqual, exception_pending);
1801 
1802 
1803   // no exception, we're almost done
1804 
1805   // check that only result value is on FPU stack
1806   __ verify_FPU(ret_type == T_FLOAT || ret_type == T_DOUBLE ? 1 : 0, "native_wrapper normal exit");
1807 
1808   // Fixup floating pointer results so that result looks like a return from a compiled method
1809   if (ret_type == T_FLOAT) {
1810     if (UseSSE >= 1) {
1811       // Pop st0 and store as float and reload into xmm register
1812       __ fstp_s(Address(rbp, -4));
1813       __ movflt(xmm0, Address(rbp, -4));
1814     }
1815   } else if (ret_type == T_DOUBLE) {
1816     if (UseSSE >= 2) {


1848     __ jcc(Assembler::equal, L);
1849     __ stop("no pending exception allowed on exit from monitorenter");
1850     __ bind(L);
1851     }
1852 #endif
1853     __ jmp(lock_done);
1854 
1855     // END Slow path lock
1856 
1857     // BEGIN Slow path unlock
1858     __ bind(slow_path_unlock);
1859 
1860     // Slow path unlock
1861 
1862     if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) {
1863       save_native_result(masm, ret_type, stack_slots);
1864     }
1865     // Save pending exception around call to VM (which contains an EXCEPTION_MARK)
1866 
1867     __ pushptr(Address(thread, in_bytes(Thread::pending_exception_offset())));
1868     __ movptr(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD);
1869 
1870 
1871     // should be a peal
1872     // +wordSize because of the push above
1873     __ lea(rax, Address(rbp, lock_slot_rbp_offset));
1874     __ push(rax);
1875 
1876     __ push(obj_reg);
1877     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C)));
1878     __ addptr(rsp, 2*wordSize);
1879 #ifdef ASSERT
1880     {
1881       Label L;
1882       __ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
1883       __ jcc(Assembler::equal, L);
1884       __ stop("no pending exception allowed on exit complete_monitor_unlocking_C");
1885       __ bind(L);
1886     }
1887 #endif /* ASSERT */
1888 


2414   // make room on stack for the return address
2415   // It will be patched later with the throwing pc. The correct value is not
2416   // available now because loading it from memory would destroy registers.
2417   __ push(0);
2418 
2419   // Save everything in sight.
2420 
2421   // No need to update map as each call to save_live_registers will produce identical oopmap
2422   (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
2423 
2424   // Now it is safe to overwrite any register
2425 
2426   // store the correct deoptimization type
2427   __ push(Deoptimization::Unpack_exception);
2428 
2429   // load throwing pc from JavaThread and patch it as the return address
2430   // of the current frame. Then clear the field in JavaThread
2431   __ get_thread(rdi);
2432   __ movptr(rdx, Address(rdi, JavaThread::exception_pc_offset()));
2433   __ movptr(Address(rbp, wordSize), rdx);
2434   __ movptr(Address(rdi, JavaThread::exception_pc_offset()), NULL_WORD);
2435 
2436 #ifdef ASSERT
2437   // verify that there is really an exception oop in JavaThread
2438   __ movptr(rax, Address(rdi, JavaThread::exception_oop_offset()));
2439   __ verify_oop(rax);
2440 
2441   // verify that there is no pending exception
2442   Label no_pending_exception;
2443   __ movptr(rax, Address(rdi, Thread::pending_exception_offset()));
2444   __ testptr(rax, rax);
2445   __ jcc(Assembler::zero, no_pending_exception);
2446   __ stop("must not have pending exception here");
2447   __ bind(no_pending_exception);
2448 #endif
2449 
2450   __ bind(cont);
2451 
2452   // Compiled code leaves the floating point stack dirty, empty it.
2453   __ empty_FPU_stack();
2454 


2472 
2473   __ get_thread(rcx);
2474   __ reset_last_Java_frame(rcx, false, false);
2475 
2476   // Load UnrollBlock into EDI
2477   __ mov(rdi, rax);
2478 
2479   // Move the unpack kind to a safe place in the UnrollBlock because
2480   // we are very short of registers
2481 
2482   Address unpack_kind(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes());
2483   // retrieve the deopt kind from where we left it.
2484   __ pop(rax);
2485   __ movl(unpack_kind, rax);                      // save the unpack_kind value
2486 
2487    Label noException;
2488   __ cmpl(rax, Deoptimization::Unpack_exception);   // Was exception pending?
2489   __ jcc(Assembler::notEqual, noException);
2490   __ movptr(rax, Address(rcx, JavaThread::exception_oop_offset()));
2491   __ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset()));
2492   __ movptr(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD);
2493   __ movptr(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD);
2494 
2495   __ verify_oop(rax);
2496 
2497   // Overwrite the result registers with the exception results.
2498   __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax);
2499   __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx);
2500 
2501   __ bind(noException);
2502 
2503   // Stack is back to only having register save data on the stack.
2504   // Now restore the result registers. Everything else is either dead or captured
2505   // in the vframeArray.
2506 
2507   RegisterSaver::restore_result_registers(masm);
2508 
2509   // All of the register save area has been popped of the stack. Only the
2510   // return address remains.
2511 
2512   // Pop all the frames we must move/replace.
2513   //


2565   __ subptr(rbx, 4*wordSize);           // we'll push pc and ebp by hand and
2566 #ifdef ASSERT
2567   __ push(0xDEADDEAD);                  // Make a recognizable pattern
2568   __ push(0xDEADDEAD);
2569 #else /* ASSERT */
2570   __ subptr(rsp, 2*wordSize);           // skip the "static long no_param"
2571 #endif /* ASSERT */
2572 #else /* CC_INTERP */
2573   __ subptr(rbx, 2*wordSize);           // we'll push pc and rbp, by hand
2574 #endif /* CC_INTERP */
2575   __ pushptr(Address(rcx, 0));          // save return address
2576   __ enter();                           // save old & set new rbp,
2577   __ subptr(rsp, rbx);                  // Prolog!
2578   __ movptr(rbx, sp_temp);              // sender's sp
2579 #ifdef CC_INTERP
2580   __ movptr(Address(rbp,
2581                   -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))),
2582           rbx); // Make it walkable
2583 #else /* CC_INTERP */
2584   // This value is corrected by layout_activation_impl
2585   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
2586   __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
2587 #endif /* CC_INTERP */
2588   __ movptr(sp_temp, rsp);              // pass to next frame
2589   __ addptr(rsi, wordSize);             // Bump array pointer (sizes)
2590   __ addptr(rcx, wordSize);             // Bump array pointer (pcs)
2591   __ decrementl(counter);             // decrement counter
2592   __ jcc(Assembler::notZero, loop);
2593   __ pushptr(Address(rcx, 0));          // save final return address
2594 
2595   // Re-push self-frame
2596   __ enter();                           // save old & set new rbp,
2597 
2598   //  Return address and rbp, are in place
2599   // We'll push additional args later. Just allocate a full sized
2600   // register save area
2601   __ subptr(rsp, (frame_size_in_words-additional_words - 2) * wordSize);
2602 
2603   // Restore frame locals after moving the frame
2604   __ movptr(Address(rsp, RegisterSaver::raxOffset()*wordSize), rax);
2605   __ movptr(Address(rsp, RegisterSaver::rdxOffset()*wordSize), rdx);


2785   __ subptr(rbx, 4*wordSize);           // we'll push pc and ebp by hand and
2786 #ifdef ASSERT
2787   __ push(0xDEADDEAD);                  // Make a recognizable pattern
2788   __ push(0xDEADDEAD);                  // (parm to RecursiveInterpreter...)
2789 #else /* ASSERT */
2790   __ subptr(rsp, 2*wordSize);           // skip the "static long no_param"
2791 #endif /* ASSERT */
2792 #else /* CC_INTERP */
2793   __ subptr(rbx, 2*wordSize);           // we'll push pc and rbp, by hand
2794 #endif /* CC_INTERP */
2795   __ pushptr(Address(rcx, 0));          // save return address
2796   __ enter();                           // save old & set new rbp,
2797   __ subptr(rsp, rbx);                  // Prolog!
2798   __ movptr(rbx, sp_temp);              // sender's sp
2799 #ifdef CC_INTERP
2800   __ movptr(Address(rbp,
2801                   -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))),
2802           rbx); // Make it walkable
2803 #else /* CC_INTERP */
2804   // This value is corrected by layout_activation_impl
2805   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD );
2806   __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), rbx); // Make it walkable
2807 #endif /* CC_INTERP */
2808   __ movptr(sp_temp, rsp);              // pass to next frame
2809   __ addptr(rsi, wordSize);             // Bump array pointer (sizes)
2810   __ addptr(rcx, wordSize);             // Bump array pointer (pcs)
2811   __ decrementl(counter);             // decrement counter
2812   __ jcc(Assembler::notZero, loop);
2813   __ pushptr(Address(rcx, 0));            // save final return address
2814 
2815   // Re-push self-frame
2816   __ enter();                           // save old & set new rbp,
2817   __ subptr(rsp, (framesize-2) * wordSize);   // Prolog!
2818 
2819 
2820   // set last_Java_sp, last_Java_fp
2821   __ get_thread(rdi);
2822   __ set_last_Java_frame(rdi, noreg, rbp, NULL);
2823 
2824   // Call C code.  Need thread but NOT official VM entry
2825   // crud.  We cannot block on this call, no GC can happen.  Call should


3003   __ movptr(rbx, Address(thread, JavaThread::vm_result_offset()));
3004   __ movptr(Address(rsp, RegisterSaver::rbx_offset() * wordSize), rbx);
3005 
3006   __ movptr(Address(rsp, RegisterSaver::rax_offset() * wordSize), rax);
3007 
3008   RegisterSaver::restore_live_registers(masm);
3009 
3010   // We are back the the original state on entry and ready to go.
3011 
3012   __ jmp(rax);
3013 
3014   // Pending exception after the safepoint
3015 
3016   __ bind(pending);
3017 
3018   RegisterSaver::restore_live_registers(masm);
3019 
3020   // exception pending => remove activation and forward to exception handler
3021 
3022   __ get_thread(thread);
3023   __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
3024   __ movptr(rax, Address(thread, Thread::pending_exception_offset()));
3025   __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
3026 
3027   // -------------
3028   // make sure all code is generated
3029   masm->flush();
3030 
3031   // return the  blob
3032   // frame_size_words or bytes??
3033   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_words, oop_maps, true);
3034 }
3035 
3036 void SharedRuntime::generate_stubs() {
3037 
3038   _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method),
3039                                         "wrong_method_stub");
3040 
3041   _ic_miss_blob      = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss),
3042                                         "ic_miss_stub");
3043