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

src/cpu/x86/vm/c1_Runtime1_x86.cpp

Print this page




  31 #include "nativeInst_x86.hpp"
  32 #include "oops/compiledICHolder.hpp"
  33 #include "oops/oop.inline.hpp"
  34 #include "prims/jvmtiExport.hpp"
  35 #include "register_x86.hpp"
  36 #include "runtime/sharedRuntime.hpp"
  37 #include "runtime/signature.hpp"
  38 #include "runtime/vframeArray.hpp"
  39 #include "utilities/macros.hpp"
  40 #include "vmreg_x86.inline.hpp"
  41 #if INCLUDE_ALL_GCS
  42 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  43 #endif
  44 
  45 
  46 // Implementation of StubAssembler
  47 
  48 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
  49   // setup registers
  50   const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions)
  51   assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different");
  52   assert(oop_result1 != thread && metadata_result != thread, "registers must be different");
  53   assert(args_size >= 0, "illegal args_size");
  54   bool align_stack = false;
  55 #ifdef _LP64
  56   // At a method handle call, the stack may not be properly aligned
  57   // when returning with an exception.
  58   align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
  59 #endif
  60 
  61 #ifdef _LP64
  62   mov(c_rarg0, thread);
  63   set_num_rt_args(0); // Nothing on stack
  64 #else
  65   set_num_rt_args(1 + args_size);
  66 
  67   // push java thread (becomes first argument of C function)
  68   get_thread(thread);
  69   push(thread);
  70 #endif // _LP64
  71 


  93     cmpptr(thread, rax);
  94     jcc(Assembler::equal, L);
  95     int3();
  96     stop("StubAssembler::call_RT: rdi not callee saved?");
  97     bind(L);
  98   }
  99   pop(rax);
 100 #endif
 101   reset_last_Java_frame(thread, true, align_stack);
 102 
 103   // discard thread and arguments
 104   NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
 105 
 106   // check for pending exceptions
 107   { Label L;
 108     cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
 109     jcc(Assembler::equal, L);
 110     // exception pending => remove activation and forward to exception handler
 111     movptr(rax, Address(thread, Thread::pending_exception_offset()));
 112     // make sure that the vm_results are cleared
 113     if (oop_result1->is_valid()) {
 114       movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
 115     }
 116     if (metadata_result->is_valid()) {
 117       movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
 118     }
 119     if (frame_size() == no_frame_size) {
 120       leave();
 121       jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
 122     } else if (_stub_id == Runtime1::forward_exception_id) {
 123       should_not_reach_here();
 124     } else {
 125       jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
 126     }
 127     bind(L);
 128   }
 129   // get oop results if there are any and reset the values in the thread
 130   if (oop_result1->is_valid()) {
 131     get_vm_result(oop_result1, thread);
 132   }
 133   if (metadata_result->is_valid()) {
 134     get_vm_result_2(metadata_result, thread);
 135   }
 136   return call_offset;
 137 }
 138 
 139 
 140 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) {
 141 #ifdef _LP64
 142   mov(c_rarg1, arg1);
 143 #else
 144   push(arg1);
 145 #endif // _LP64
 146   return call_RT(oop_result1, metadata_result, entry, 1);
 147 }
 148 
 149 
 150 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
 151 #ifdef _LP64
 152   if (c_rarg1 == arg2) {
 153     if (c_rarg2 == arg1) {


 311 // Tries to smart of about FP registers.  In particular we separate
 312 // saving and describing the FPU registers for deoptimization since we
 313 // have to save the FPU registers twice if we describe them and on P4
 314 // saving FPU registers which don't contain anything appears
 315 // expensive.  The deopt blob is the only thing which needs to
 316 // describe FPU registers.  In all other cases it should be sufficient
 317 // to simply save their current value.
 318 
 319 static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
 320                                 bool save_fpu_registers = true) {
 321 
 322   // In 64bit all the args are in regs so there are no additional stack slots
 323   LP64_ONLY(num_rt_args = 0);
 324   LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
 325   int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread
 326   sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word );
 327 
 328   // record saved value locations in an OopMap
 329   // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread
 330   OopMap* map = new OopMap(frame_size_in_slots, 0);
 331   map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg());
 332   map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg());
 333   map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg());
 334   map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg());
 335   map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg());
 336   map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg());
 337 #ifdef _LP64
 338   map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args),  r8->as_VMReg());
 339   map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args),  r9->as_VMReg());
 340   map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10->as_VMReg());
 341   map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11->as_VMReg());
 342   map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12->as_VMReg());
 343   map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13->as_VMReg());
 344   map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14->as_VMReg());
 345   map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15->as_VMReg());
 346 
 347   // This is stupid but needed.
 348   map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next());
 349   map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next());
 350   map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next());
 351   map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next());
 352   map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next());
 353   map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next());
 354 
 355   map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args),  r8->as_VMReg()->next());
 356   map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args),  r9->as_VMReg()->next());
 357   map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10->as_VMReg()->next());
 358   map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11->as_VMReg()->next());
 359   map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12->as_VMReg()->next());
 360   map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13->as_VMReg()->next());
 361   map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14->as_VMReg()->next());
 362   map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next());
 363 #endif // _LP64
 364 
 365   if (save_fpu_registers) {
 366     if (UseSSE < 2) {
 367       int fpu_off = float_regs_as_doubles_off;
 368       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 369         VMReg fpu_name_0 = FrameMap::fpu_regname(n);
 370         map->set_callee_saved(VMRegImpl::stack2reg(fpu_off +     num_rt_args), fpu_name_0);
 371         // %%% This is really a waste but we'll keep things as they were for now
 372         if (true) {
 373           map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + 1 + num_rt_args), fpu_name_0->next());
 374         }
 375         fpu_off += 2;
 376       }
 377       assert(fpu_off == fpu_state_off, "incorrect number of fpu stack slots");
 378     }
 379 
 380     if (UseSSE >= 2) {
 381       int xmm_off = xmm_regs_as_doubles_off;
 382       for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
 383         VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
 384         map->set_callee_saved(VMRegImpl::stack2reg(xmm_off +     num_rt_args), xmm_name_0);
 385         // %%% This is really a waste but we'll keep things as they were for now
 386         if (true) {
 387           map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next());
 388         }
 389         xmm_off += 2;
 390       }
 391       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 392 
 393     } else if (UseSSE == 1) {
 394       int xmm_off = xmm_regs_as_doubles_off;
 395       for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
 396         VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
 397         map->set_callee_saved(VMRegImpl::stack2reg(xmm_off +     num_rt_args), xmm_name_0);
 398         xmm_off += 2;
 399       }
 400       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 401     }
 402   }
 403 
 404   return map;
 405 }
 406 
 407 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
 408                                    bool save_fpu_registers = true) {
 409   __ block_comment("save_live_registers");
 410 
 411   __ pusha();         // integer registers
 412 
 413   // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
 414   // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset");
 415 
 416   __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);




  31 #include "nativeInst_x86.hpp"
  32 #include "oops/compiledICHolder.hpp"
  33 #include "oops/oop.inline.hpp"
  34 #include "prims/jvmtiExport.hpp"
  35 #include "register_x86.hpp"
  36 #include "runtime/sharedRuntime.hpp"
  37 #include "runtime/signature.hpp"
  38 #include "runtime/vframeArray.hpp"
  39 #include "utilities/macros.hpp"
  40 #include "vmreg_x86.inline.hpp"
  41 #if INCLUDE_ALL_GCS
  42 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  43 #endif
  44 
  45 
  46 // Implementation of StubAssembler
  47 
  48 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
  49   // setup registers
  50   const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions)
  51   assert(!(oop_result1.is_valid() || metadata_result.is_valid()) || oop_result1 != metadata_result, "registers must be different");
  52   assert(oop_result1 != thread && metadata_result != thread, "registers must be different");
  53   assert(args_size >= 0, "illegal args_size");
  54   bool align_stack = false;
  55 #ifdef _LP64
  56   // At a method handle call, the stack may not be properly aligned
  57   // when returning with an exception.
  58   align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
  59 #endif
  60 
  61 #ifdef _LP64
  62   mov(c_rarg0, thread);
  63   set_num_rt_args(0); // Nothing on stack
  64 #else
  65   set_num_rt_args(1 + args_size);
  66 
  67   // push java thread (becomes first argument of C function)
  68   get_thread(thread);
  69   push(thread);
  70 #endif // _LP64
  71 


  93     cmpptr(thread, rax);
  94     jcc(Assembler::equal, L);
  95     int3();
  96     stop("StubAssembler::call_RT: rdi not callee saved?");
  97     bind(L);
  98   }
  99   pop(rax);
 100 #endif
 101   reset_last_Java_frame(thread, true, align_stack);
 102 
 103   // discard thread and arguments
 104   NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
 105 
 106   // check for pending exceptions
 107   { Label L;
 108     cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
 109     jcc(Assembler::equal, L);
 110     // exception pending => remove activation and forward to exception handler
 111     movptr(rax, Address(thread, Thread::pending_exception_offset()));
 112     // make sure that the vm_results are cleared
 113     if (oop_result1.is_valid()) {
 114       movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
 115     }
 116     if (metadata_result.is_valid()) {
 117       movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
 118     }
 119     if (frame_size() == no_frame_size) {
 120       leave();
 121       jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
 122     } else if (_stub_id == Runtime1::forward_exception_id) {
 123       should_not_reach_here();
 124     } else {
 125       jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
 126     }
 127     bind(L);
 128   }
 129   // get oop results if there are any and reset the values in the thread
 130   if (oop_result1.is_valid()) {
 131     get_vm_result(oop_result1, thread);
 132   }
 133   if (metadata_result.is_valid()) {
 134     get_vm_result_2(metadata_result, thread);
 135   }
 136   return call_offset;
 137 }
 138 
 139 
 140 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) {
 141 #ifdef _LP64
 142   mov(c_rarg1, arg1);
 143 #else
 144   push(arg1);
 145 #endif // _LP64
 146   return call_RT(oop_result1, metadata_result, entry, 1);
 147 }
 148 
 149 
 150 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
 151 #ifdef _LP64
 152   if (c_rarg1 == arg2) {
 153     if (c_rarg2 == arg1) {


 311 // Tries to smart of about FP registers.  In particular we separate
 312 // saving and describing the FPU registers for deoptimization since we
 313 // have to save the FPU registers twice if we describe them and on P4
 314 // saving FPU registers which don't contain anything appears
 315 // expensive.  The deopt blob is the only thing which needs to
 316 // describe FPU registers.  In all other cases it should be sufficient
 317 // to simply save their current value.
 318 
 319 static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
 320                                 bool save_fpu_registers = true) {
 321 
 322   // In 64bit all the args are in regs so there are no additional stack slots
 323   LP64_ONLY(num_rt_args = 0);
 324   LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
 325   int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread
 326   sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word );
 327 
 328   // record saved value locations in an OopMap
 329   // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread
 330   OopMap* map = new OopMap(frame_size_in_slots, 0);
 331   map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax.as_VMReg());
 332   map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx.as_VMReg());
 333   map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx.as_VMReg());
 334   map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx.as_VMReg());
 335   map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi.as_VMReg());
 336   map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi.as_VMReg());
 337 #ifdef _LP64
 338   map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args),  r8.as_VMReg());
 339   map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args),  r9.as_VMReg());
 340   map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10.as_VMReg());
 341   map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11.as_VMReg());
 342   map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12.as_VMReg());
 343   map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13.as_VMReg());
 344   map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14.as_VMReg());
 345   map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15.as_VMReg());
 346 
 347   // This is stupid but needed.
 348   map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax.as_VMReg()->next());
 349   map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx.as_VMReg()->next());
 350   map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx.as_VMReg()->next());
 351   map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx.as_VMReg()->next());
 352   map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi.as_VMReg()->next());
 353   map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi.as_VMReg()->next());
 354 
 355   map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args),  r8.as_VMReg()->next());
 356   map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args),  r9.as_VMReg()->next());
 357   map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10.as_VMReg()->next());
 358   map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11.as_VMReg()->next());
 359   map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12.as_VMReg()->next());
 360   map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13.as_VMReg()->next());
 361   map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14.as_VMReg()->next());
 362   map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15.as_VMReg()->next());
 363 #endif // _LP64
 364 
 365   if (save_fpu_registers) {
 366     if (UseSSE < 2) {
 367       int fpu_off = float_regs_as_doubles_off;
 368       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 369         VMReg fpu_name_0 = FrameMap::fpu_regname(n);
 370         map->set_callee_saved(VMRegImpl::stack2reg(fpu_off +     num_rt_args), fpu_name_0);
 371         // %%% This is really a waste but we'll keep things as they were for now
 372         if (true) {
 373           map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + 1 + num_rt_args), fpu_name_0->next());
 374         }
 375         fpu_off += 2;
 376       }
 377       assert(fpu_off == fpu_state_off, "incorrect number of fpu stack slots");
 378     }
 379 
 380     if (UseSSE >= 2) {
 381       int xmm_off = xmm_regs_as_doubles_off;
 382       for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
 383         VMReg xmm_name_0 = as_XMMRegister(n).as_VMReg();
 384         map->set_callee_saved(VMRegImpl::stack2reg(xmm_off +     num_rt_args), xmm_name_0);
 385         // %%% This is really a waste but we'll keep things as they were for now
 386         if (true) {
 387           map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next());
 388         }
 389         xmm_off += 2;
 390       }
 391       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 392 
 393     } else if (UseSSE == 1) {
 394       int xmm_off = xmm_regs_as_doubles_off;
 395       for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
 396         VMReg xmm_name_0 = as_XMMRegister(n).as_VMReg();
 397         map->set_callee_saved(VMRegImpl::stack2reg(xmm_off +     num_rt_args), xmm_name_0);
 398         xmm_off += 2;
 399       }
 400       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 401     }
 402   }
 403 
 404   return map;
 405 }
 406 
 407 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
 408                                    bool save_fpu_registers = true) {
 409   __ block_comment("save_live_registers");
 410 
 411   __ pusha();         // integer registers
 412 
 413   // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
 414   // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset");
 415 
 416   __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);


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