src/cpu/x86/vm/sharedRuntime_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot Sdiff src/cpu/x86/vm

src/cpu/x86/vm/sharedRuntime_x86_64.cpp

Print this page




 783     __ subptr(rsp, comp_words_on_stack * wordSize);
 784   }
 785 
 786 
 787   // Ensure compiled code always sees stack at proper alignment
 788   __ andptr(rsp, -16);
 789 
 790   // push the return address and misalign the stack that youngest frame always sees
 791   // as far as the placement of the call instruction
 792   __ push(rax);
 793 
 794   // Put saved SP in another register
 795   const Register saved_sp = rax;
 796   __ movptr(saved_sp, r11);
 797 
 798   // Will jump to the compiled code just as if compiled code was doing it.
 799   // Pre-load the register-jump target early, to schedule it better.
 800   __ movptr(r11, Address(rbx, in_bytes(Method::from_compiled_offset())));
 801 
 802 #if INCLUDE_JVMCI
 803   if (EnableJVMCI) {
 804     // check if this call should be routed towards a specific entry point
 805     __ cmpptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
 806     Label no_alternative_target;
 807     __ jcc(Assembler::equal, no_alternative_target);
 808     __ movptr(r11, Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
 809     __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
 810     __ bind(no_alternative_target);
 811   }
 812 #endif // INCLUDE_JVMCI
 813 
 814   // Now generate the shuffle code.  Pick up all register args and move the
 815   // rest through the floating point stack top.
 816   for (int i = 0; i < total_args_passed; i++) {
 817     if (sig_bt[i] == T_VOID) {
 818       // Longs and doubles are passed in native word order, but misaligned
 819       // in the 32-bit build.
 820       assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
 821       continue;
 822     }
 823 


2741 }
2742 
2743 // this function returns the adjust size (in number of words) to a c2i adapter
2744 // activation for use during deoptimization
2745 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {
2746   return (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2747 }
2748 
2749 
2750 uint SharedRuntime::out_preserve_stack_slots() {
2751   return 0;
2752 }
2753 
2754 //------------------------------generate_deopt_blob----------------------------
2755 void SharedRuntime::generate_deopt_blob() {
2756   // Allocate space for the code
2757   ResourceMark rm;
2758   // Setup code generation tools
2759   int pad = 0;
2760 #if INCLUDE_JVMCI
2761   if (EnableJVMCI) {
2762     pad += 512; // Increase the buffer size when compiling for JVMCI
2763   }
2764 #endif
2765   CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
2766   MacroAssembler* masm = new MacroAssembler(&buffer);
2767   int frame_size_in_words;
2768   OopMap* map = NULL;
2769   OopMapSet *oop_maps = new OopMapSet();
2770 
2771   // -------------
2772   // This code enters when returning to a de-optimized nmethod.  A return
2773   // address has been pushed on the the stack, and return values are in
2774   // registers.
2775   // If we are doing a normal deopt then we were called from the patched
2776   // nmethod from the point we returned to the nmethod. So the return
2777   // address on the stack is wrong by NativeCall::instruction_size
2778   // We will adjust the value so it looks like we have the original return
2779   // address on the stack (like when we eagerly deoptimized).
2780   // In the case of an exception pending when deoptimizing, we enter
2781   // with a return address on the stack that points after the call we patched


2815   if (EnableJVMCI && UseJVMCICompiler) {
2816     // JVMCI does not use this kind of deoptimization
2817     __ should_not_reach_here();
2818   }
2819 #endif
2820 
2821   // Reexecute case
2822   // return address is the pc describes what bci to do re-execute at
2823 
2824   // No need to update map as each call to save_live_registers will produce identical oopmap
2825   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2826 
2827   __ movl(r14, Deoptimization::Unpack_reexecute); // callee-saved
2828   __ jmp(cont);
2829 
2830 #if INCLUDE_JVMCI
2831   Label after_fetch_unroll_info_call;
2832   int implicit_exception_uncommon_trap_offset = 0;
2833   int uncommon_trap_offset = 0;
2834 
2835   if (EnableJVMCI) {
2836     implicit_exception_uncommon_trap_offset = __ pc() - start;
2837 
2838     __ pushptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2839     __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())), (int32_t)NULL_WORD);
2840 
2841     uncommon_trap_offset = __ pc() - start;
2842 
2843     // Save everything in sight.
2844     RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2845     // fetch_unroll_info needs to call last_java_frame()
2846     __ set_last_Java_frame(noreg, noreg, NULL);
2847 
2848     __ movl(c_rarg1, Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())));
2849     __ movl(Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())), -1);
2850 
2851     __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
2852     __ mov(c_rarg0, r15_thread);
2853     __ movl(c_rarg2, r14); // exec mode
2854     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
2855     oop_maps->add_gc_map( __ pc()-start, map->deep_copy());


2930   { Label L;
2931     __ cmpptr(Address(r15_thread,
2932                     JavaThread::last_Java_fp_offset()),
2933             (int32_t)0);
2934     __ jcc(Assembler::equal, L);
2935     __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared");
2936     __ bind(L);
2937   }
2938 #endif // ASSERT
2939   __ mov(c_rarg0, r15_thread);
2940   __ movl(c_rarg1, r14); // exec_mode
2941   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
2942 
2943   // Need to have an oopmap that tells fetch_unroll_info where to
2944   // find any register it might need.
2945   oop_maps->add_gc_map(__ pc() - start, map);
2946 
2947   __ reset_last_Java_frame(false);
2948 
2949 #if INCLUDE_JVMCI
2950   if (EnableJVMCI) {
2951     __ bind(after_fetch_unroll_info_call);
2952   }
2953 #endif
2954 
2955   // Load UnrollBlock* into rdi
2956   __ mov(rdi, rax);
2957 
2958   __ movl(r14, Address(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
2959    Label noException;
2960   __ cmpl(r14, Deoptimization::Unpack_exception);   // Was exception pending?
2961   __ jcc(Assembler::notEqual, noException);
2962   __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset()));
2963   // QQQ this is useless it was NULL above
2964   __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset()));
2965   __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
2966   __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
2967 
2968   __ verify_oop(rax);
2969 
2970   // Overwrite the result registers with the exception results.


3095   __ reset_last_Java_frame(true);
3096 
3097   // Collect return values
3098   __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes()));
3099   __ movptr(rax, Address(rsp, RegisterSaver::rax_offset_in_bytes()));
3100   // I think this is useless (throwing pc?)
3101   __ movptr(rdx, Address(rsp, RegisterSaver::rdx_offset_in_bytes()));
3102 
3103   // Pop self-frame.
3104   __ leave();                           // Epilog
3105 
3106   // Jump to interpreter
3107   __ ret(0);
3108 
3109   // Make sure all code is generated
3110   masm->flush();
3111 
3112   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
3113   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
3114 #if INCLUDE_JVMCI
3115   if (EnableJVMCI) {
3116     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
3117     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
3118   }
3119 #endif
3120 }
3121 
3122 #ifdef COMPILER2
3123 //------------------------------generate_uncommon_trap_blob--------------------
3124 void SharedRuntime::generate_uncommon_trap_blob() {
3125   // Allocate space for the code
3126   ResourceMark rm;
3127   // Setup code generation tools
3128   CodeBuffer buffer("uncommon_trap_blob", 2048, 1024);
3129   MacroAssembler* masm = new MacroAssembler(&buffer);
3130 
3131   assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned");
3132 
3133   address start = __ pc();
3134 
3135   if (UseRTMLocking) {




 783     __ subptr(rsp, comp_words_on_stack * wordSize);
 784   }
 785 
 786 
 787   // Ensure compiled code always sees stack at proper alignment
 788   __ andptr(rsp, -16);
 789 
 790   // push the return address and misalign the stack that youngest frame always sees
 791   // as far as the placement of the call instruction
 792   __ push(rax);
 793 
 794   // Put saved SP in another register
 795   const Register saved_sp = rax;
 796   __ movptr(saved_sp, r11);
 797 
 798   // Will jump to the compiled code just as if compiled code was doing it.
 799   // Pre-load the register-jump target early, to schedule it better.
 800   __ movptr(r11, Address(rbx, in_bytes(Method::from_compiled_offset())));
 801 
 802 #if INCLUDE_JVMCI
 803   if (EnableJVMCI || UseAOT) {
 804     // check if this call should be routed towards a specific entry point
 805     __ cmpptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
 806     Label no_alternative_target;
 807     __ jcc(Assembler::equal, no_alternative_target);
 808     __ movptr(r11, Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
 809     __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
 810     __ bind(no_alternative_target);
 811   }
 812 #endif // INCLUDE_JVMCI
 813 
 814   // Now generate the shuffle code.  Pick up all register args and move the
 815   // rest through the floating point stack top.
 816   for (int i = 0; i < total_args_passed; i++) {
 817     if (sig_bt[i] == T_VOID) {
 818       // Longs and doubles are passed in native word order, but misaligned
 819       // in the 32-bit build.
 820       assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
 821       continue;
 822     }
 823 


2741 }
2742 
2743 // this function returns the adjust size (in number of words) to a c2i adapter
2744 // activation for use during deoptimization
2745 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {
2746   return (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2747 }
2748 
2749 
2750 uint SharedRuntime::out_preserve_stack_slots() {
2751   return 0;
2752 }
2753 
2754 //------------------------------generate_deopt_blob----------------------------
2755 void SharedRuntime::generate_deopt_blob() {
2756   // Allocate space for the code
2757   ResourceMark rm;
2758   // Setup code generation tools
2759   int pad = 0;
2760 #if INCLUDE_JVMCI
2761   if (EnableJVMCI || UseAOT) {
2762     pad += 512; // Increase the buffer size when compiling for JVMCI
2763   }
2764 #endif
2765   CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
2766   MacroAssembler* masm = new MacroAssembler(&buffer);
2767   int frame_size_in_words;
2768   OopMap* map = NULL;
2769   OopMapSet *oop_maps = new OopMapSet();
2770 
2771   // -------------
2772   // This code enters when returning to a de-optimized nmethod.  A return
2773   // address has been pushed on the the stack, and return values are in
2774   // registers.
2775   // If we are doing a normal deopt then we were called from the patched
2776   // nmethod from the point we returned to the nmethod. So the return
2777   // address on the stack is wrong by NativeCall::instruction_size
2778   // We will adjust the value so it looks like we have the original return
2779   // address on the stack (like when we eagerly deoptimized).
2780   // In the case of an exception pending when deoptimizing, we enter
2781   // with a return address on the stack that points after the call we patched


2815   if (EnableJVMCI && UseJVMCICompiler) {
2816     // JVMCI does not use this kind of deoptimization
2817     __ should_not_reach_here();
2818   }
2819 #endif
2820 
2821   // Reexecute case
2822   // return address is the pc describes what bci to do re-execute at
2823 
2824   // No need to update map as each call to save_live_registers will produce identical oopmap
2825   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2826 
2827   __ movl(r14, Deoptimization::Unpack_reexecute); // callee-saved
2828   __ jmp(cont);
2829 
2830 #if INCLUDE_JVMCI
2831   Label after_fetch_unroll_info_call;
2832   int implicit_exception_uncommon_trap_offset = 0;
2833   int uncommon_trap_offset = 0;
2834 
2835   if (EnableJVMCI || UseAOT) {
2836     implicit_exception_uncommon_trap_offset = __ pc() - start;
2837 
2838     __ pushptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2839     __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())), (int32_t)NULL_WORD);
2840 
2841     uncommon_trap_offset = __ pc() - start;
2842 
2843     // Save everything in sight.
2844     RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2845     // fetch_unroll_info needs to call last_java_frame()
2846     __ set_last_Java_frame(noreg, noreg, NULL);
2847 
2848     __ movl(c_rarg1, Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())));
2849     __ movl(Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())), -1);
2850 
2851     __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
2852     __ mov(c_rarg0, r15_thread);
2853     __ movl(c_rarg2, r14); // exec mode
2854     __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
2855     oop_maps->add_gc_map( __ pc()-start, map->deep_copy());


2930   { Label L;
2931     __ cmpptr(Address(r15_thread,
2932                     JavaThread::last_Java_fp_offset()),
2933             (int32_t)0);
2934     __ jcc(Assembler::equal, L);
2935     __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared");
2936     __ bind(L);
2937   }
2938 #endif // ASSERT
2939   __ mov(c_rarg0, r15_thread);
2940   __ movl(c_rarg1, r14); // exec_mode
2941   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
2942 
2943   // Need to have an oopmap that tells fetch_unroll_info where to
2944   // find any register it might need.
2945   oop_maps->add_gc_map(__ pc() - start, map);
2946 
2947   __ reset_last_Java_frame(false);
2948 
2949 #if INCLUDE_JVMCI
2950   if (EnableJVMCI || UseAOT) {
2951     __ bind(after_fetch_unroll_info_call);
2952   }
2953 #endif
2954 
2955   // Load UnrollBlock* into rdi
2956   __ mov(rdi, rax);
2957 
2958   __ movl(r14, Address(rdi, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
2959    Label noException;
2960   __ cmpl(r14, Deoptimization::Unpack_exception);   // Was exception pending?
2961   __ jcc(Assembler::notEqual, noException);
2962   __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset()));
2963   // QQQ this is useless it was NULL above
2964   __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset()));
2965   __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
2966   __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
2967 
2968   __ verify_oop(rax);
2969 
2970   // Overwrite the result registers with the exception results.


3095   __ reset_last_Java_frame(true);
3096 
3097   // Collect return values
3098   __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes()));
3099   __ movptr(rax, Address(rsp, RegisterSaver::rax_offset_in_bytes()));
3100   // I think this is useless (throwing pc?)
3101   __ movptr(rdx, Address(rsp, RegisterSaver::rdx_offset_in_bytes()));
3102 
3103   // Pop self-frame.
3104   __ leave();                           // Epilog
3105 
3106   // Jump to interpreter
3107   __ ret(0);
3108 
3109   // Make sure all code is generated
3110   masm->flush();
3111 
3112   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
3113   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
3114 #if INCLUDE_JVMCI
3115   if (EnableJVMCI || UseAOT) {
3116     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
3117     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
3118   }
3119 #endif
3120 }
3121 
3122 #ifdef COMPILER2
3123 //------------------------------generate_uncommon_trap_blob--------------------
3124 void SharedRuntime::generate_uncommon_trap_blob() {
3125   // Allocate space for the code
3126   ResourceMark rm;
3127   // Setup code generation tools
3128   CodeBuffer buffer("uncommon_trap_blob", 2048, 1024);
3129   MacroAssembler* masm = new MacroAssembler(&buffer);
3130 
3131   assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned");
3132 
3133   address start = __ pc();
3134 
3135   if (UseRTMLocking) {


src/cpu/x86/vm/sharedRuntime_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File