< prev index next >

src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp

Print this page
*** 63,10 ***
--- 63,13 ---
  #include "c1/c1_Runtime1.hpp"
  #endif
  #ifdef COMPILER2
  #include "opto/runtime.hpp"
  #endif
+ #if INCLUDE_SHENANDOAHGC
+ #include "gc/shenandoah/shenandoahRuntime.hpp"
+ #endif
  #if INCLUDE_JVMCI
  #include "jvmci/jvmciJavaClasses.hpp"
  #endif
  
  #define __ masm->

*** 157,10 ***
--- 160,12 ---
      rbp_off, rbpH_off,        // copy of rbp we will restore
      return_off, returnH_off,  // slot for return address
      reg_save_size             // size in compiler stack slots
    };
  
+   static void adjust_wide_vectors_support(bool& wide_vectors);
+ 
   public:
    static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_wide_vectors);
    static void restore_live_registers(MacroAssembler* masm, bool restore_wide_vectors = false);
  
    // Offsets into the register save area

*** 177,21 ***
    // During deoptimization only the result registers need to be restored,
    // all the other values have already been extracted.
    static void restore_result_registers(MacroAssembler* masm);
  };
  
! OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_wide_vectors) {
!   int off = 0;
-   int num_xmm_regs = XMMRegister::available_xmm_registers();
  #if COMPILER2_OR_JVMCI
!   if (save_wide_vectors && UseAVX == 0) {
!     save_wide_vectors = false; // vectors larger than 16 byte long are supported only with AVX
    }
!   assert(!save_wide_vectors || MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
  #else
!   save_wide_vectors = false; // vectors are generated only by C2 and JVMCI
  #endif
  
    // Always make the frame size 16-byte aligned, both vector and non vector stacks are always allocated
    int frame_size_in_bytes = align_up(reg_save_size*BytesPerInt, num_xmm_regs);
    // OopMap frame size is in compiler stack slots (jint's) not bytes or words
    int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
--- 182,27 ---
    // During deoptimization only the result registers need to be restored,
    // all the other values have already been extracted.
    static void restore_result_registers(MacroAssembler* masm);
  };
  
! // TODO: Should be upstreamed separately.
! void RegisterSaver::adjust_wide_vectors_support(bool& wide_vectors) {
  #if COMPILER2_OR_JVMCI
!   if (wide_vectors && UseAVX == 0) {
!     wide_vectors = false; // vectors larger than 16 byte long are supported only with AVX
    }
!   assert(!wide_vectors || MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
  #else
!   wide_vectors = false; // vectors are generated only by C2 and JVMCI
  #endif
+ }
+ 
+ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_wide_vectors) {
+   int off = 0;
+   int num_xmm_regs = XMMRegister::available_xmm_registers();
+ 
+   adjust_wide_vectors_support(save_wide_vectors);
  
    // Always make the frame size 16-byte aligned, both vector and non vector stacks are always allocated
    int frame_size_in_bytes = align_up(reg_save_size*BytesPerInt, num_xmm_regs);
    // OopMap frame size is in compiler stack slots (jint's) not bytes or words
    int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;

*** 429,18 ***
    if (frame::arg_reg_save_area_bytes != 0) {
      // Pop arg register save area
      __ addptr(rsp, frame::arg_reg_save_area_bytes);
    }
  
! #if COMPILER2_OR_JVMCI
-   if (restore_wide_vectors) {
-     assert(UseAVX > 0, "Vectors larger than 16 byte long are supported only with AVX");
-     assert(MaxVectorSize <= 64, "Only up to 64 byte long vectors are supported");
-   }
- #else
-   assert(!restore_wide_vectors, "vectors are generated only by C2");
- #endif
  
    __ vzeroupper();
  
    // On EVEX enabled targets everything is handled in pop fpu state
    if (restore_wide_vectors) {
--- 440,11 ---
    if (frame::arg_reg_save_area_bytes != 0) {
      // Pop arg register save area
      __ addptr(rsp, frame::arg_reg_save_area_bytes);
    }
  
!   adjust_wide_vectors_support(restore_wide_vectors);
  
    __ vzeroupper();
  
    // On EVEX enabled targets everything is handled in pop fpu state
    if (restore_wide_vectors) {

*** 3599,5 ***
--- 3603,72 ---
                                    false);
    return stub;
  }
  
  #endif // INCLUDE_JFR
+ 
+ RuntimeStub* SharedRuntime::generate_gc_slow_call_blob(StubId stub_id, address stub_addr, bool has_return, bool save_registers, bool save_vectors) {
+   const char* name = SharedRuntime::stub_name(stub_id);
+ 
+   CodeBuffer code(name, 2048, 64);
+   MacroAssembler* masm = new MacroAssembler(&code);
+   address start = __ pc();
+ 
+   int frame_size_in_words = 0;
+   OopMap* map;
+   if (save_registers) {
+     map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words, save_vectors);
+   } else {
+     map = new OopMap(frame_size_in_words, 0); // FIXME: Correct?
+   }
+   address frame_complete_pc = __ pc();
+ 
+   address post_call_pc;
+ 
+   // Call the runtime. This is what MacroAssember::call_VM_leaf does,
+   // but we also want to have exact post-call PC for oop map location.
+   {
+     Label L_stack_aligned, L_end;
+ 
+     #ifdef _WIN64
+       // Windows always allocates space for it's register args
+       __ subptr(rsp, frame::arg_reg_save_area_bytes);
+     #endif
+ 
+     __ testptr(rsp, 15);
+     __ jccb(Assembler::zero, L_stack_aligned);
+       __ subptr(rsp, 8);
+       __ call(RuntimeAddress(stub_addr));
+       post_call_pc = __ pc();
+       __ addptr(rsp, 8);
+       __ jmpb(L_end);
+     __ bind(L_stack_aligned);
+       __ call(RuntimeAddress(stub_addr));
+       post_call_pc = __ pc();
+     __ bind(L_end);
+ 
+     #ifdef _WIN64
+       __ addptr(rsp, frame::arg_reg_save_area_bytes);
+     #endif
+   }
+ 
+   if (save_registers && has_return) {
+     // RegisterSaver would clobber the call result when restoring.
+     // Carry the result out of this stub by overwriting saved register.
+     __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax);
+   }
+ 
+   OopMapSet* oop_maps = new OopMapSet();
+   oop_maps->add_gc_map(post_call_pc - start, map);
+ 
+   if (save_registers) {
+     RegisterSaver::restore_live_registers(masm, save_vectors);
+   }
+   __ ret(0);
+ 
+   return RuntimeStub::new_runtime_stub(name,
+                                        &code,
+                                        frame_complete_pc - start,
+                                        frame_size_in_words,
+                                        oop_maps,
+                                        true);
+ }
< prev index next >