< prev index next >

src/cpu/x86/vm/c1_Runtime1_x86.cpp

Print this page
rev 12906 : [mq]: gc_interface


  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/assembler.hpp"
  27 #include "c1/c1_Defs.hpp"
  28 #include "c1/c1_MacroAssembler.hpp"
  29 #include "c1/c1_Runtime1.hpp"
  30 #include "interpreter/interpreter.hpp"
  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/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


 190   push(arg2);
 191   push(arg1);
 192 #endif // _LP64
 193   return call_RT(oop_result1, metadata_result, entry, 3);
 194 }
 195 
 196 
 197 // Implementation of StubFrame
 198 
 199 class StubFrame: public StackObj {
 200  private:
 201   StubAssembler* _sasm;
 202 
 203  public:
 204   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments);
 205   void load_argument(int offset_in_words, Register reg);
 206 
 207   ~StubFrame();
 208 };
 209 









 210 
 211 #define __ _sasm->
 212 
 213 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
 214   _sasm = sasm;
 215   __ set_info(name, must_gc_arguments);
 216   __ enter();
 217 }
 218 
 219 // load parameters that were stored with LIR_Assembler::store_parameter
 220 // Note: offsets for store_parameter and load_argument must match
 221 void StubFrame::load_argument(int offset_in_words, Register reg) {
 222   // rbp, + 0: link
 223   //     + 1: return address
 224   //     + 2: argument with offset 0
 225   //     + 3: argument with offset 1
 226   //     + 4: ...
 227 
 228   __ movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
 229 }
 230 
 231 
 232 StubFrame::~StubFrame() {
 233   __ leave();
 234   __ ret(0);
 235 }
 236 
 237 #undef __
 238 
 239 
 240 // Implementation of Runtime1
 241 
 242 #define __ sasm->
 243 
 244 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
 245 const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2;
 246 
 247 // Stack layout for saving/restoring  all the registers needed during a runtime
 248 // call (this includes deoptimization)
 249 // Note: note that users of this frame may well have arguments to some runtime
 250 // while these values are on the stack. These positions neglect those arguments
 251 // but the code in save_live_registers will take the argument count into
 252 // account.
 253 //
 254 #ifdef _LP64
 255   #define SLOT2(x) x,
 256   #define SLOT_PER_WORD 2
 257 #else
 258   #define SLOT2(x)
 259   #define SLOT_PER_WORD 1
 260 #endif // _LP64
 261 
 262 enum reg_save_layout {
 263   // 64bit needs to keep stack 16 byte aligned. So we add some alignment dummies to make that


 288   r11_off, r11H_off,                                                                        // 392, 396
 289   r10_off, r10H_off,                                                                        // 400, 404
 290   r9_off, r9H_off,                                                                          // 408, 412
 291   r8_off, r8H_off,                                                                          // 416, 420
 292   rdi_off, rdiH_off,                                                                        // 424, 428
 293 #else
 294   rdi_off = extra_space_offset,
 295 #endif // _LP64
 296   rsi_off, SLOT2(rsiH_off)                                                                  // 432, 436
 297   rbp_off, SLOT2(rbpH_off)                                                                  // 440, 444
 298   rsp_off, SLOT2(rspH_off)                                                                  // 448, 452
 299   rbx_off, SLOT2(rbxH_off)                                                                  // 456, 460
 300   rdx_off, SLOT2(rdxH_off)                                                                  // 464, 468
 301   rcx_off, SLOT2(rcxH_off)                                                                  // 472, 476
 302   rax_off, SLOT2(raxH_off)                                                                  // 480, 484
 303   saved_rbp_off, SLOT2(saved_rbpH_off)                                                      // 488, 492
 304   return_off, SLOT2(returnH_off)                                                            // 496, 500
 305   reg_save_frame_size   // As noted: neglects any parameters to runtime                     // 504
 306 };
 307 
 308 
 309 
 310 // Save off registers which might be killed by calls into the runtime.
 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


 396           }
 397         }
 398         xmm_off += 2;
 399       }
 400       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 401 
 402     } else if (UseSSE == 1) {
 403       int xmm_off = xmm_regs_as_doubles_off;
 404       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 405         VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
 406         map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
 407         xmm_off += 2;
 408       }
 409       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 410     }
 411   }
 412 
 413   return map;
 414 }
 415 
 416 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
 417                                    bool save_fpu_registers = true) {

 418   __ block_comment("save_live_registers");
 419 
 420   __ pusha();         // integer registers
 421 
 422   // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
 423   // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset");
 424 
 425   __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
 426 
 427 #ifdef ASSERT
 428   __ movptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef);
 429 #endif
 430 
 431   if (save_fpu_registers) {
 432     if (UseSSE < 2) {
 433       // save FPU stack
 434       __ fnsave(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size));
 435       __ fwait();
 436 
 437 #ifdef ASSERT


 471       }
 472 #endif
 473       for (int n = 0; n < xmm_bypass_limit; n++) {
 474         XMMRegister xmm_name = as_XMMRegister(n);
 475         __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
 476         offset += 8;
 477       }
 478     } else if (UseSSE == 1) {
 479       // save XMM registers as float because double not supported without SSE2(num MMX == num fpu)
 480       int offset = 0;
 481       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 482         XMMRegister xmm_name = as_XMMRegister(n);
 483         __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
 484         offset += 8;
 485       }
 486     }
 487   }
 488 
 489   // FPU stack must be empty now
 490   __ verify_FPU(0, "save_live_registers");
 491 
 492   return generate_oop_map(sasm, num_rt_args, save_fpu_registers);
 493 }
 494 


 495 
 496 static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true) {
 497   if (restore_fpu_registers) {
 498     if (UseSSE >= 2) {
 499       // restore XMM registers
 500       int xmm_bypass_limit = FrameMap::nof_xmm_regs;
 501 #ifdef _LP64
 502       if (UseAVX < 3) {
 503         xmm_bypass_limit = xmm_bypass_limit / 2;
 504       }
 505 #endif
 506       int offset = 0;
 507       for (int n = 0; n < xmm_bypass_limit; n++) {
 508         XMMRegister xmm_name = as_XMMRegister(n);
 509         __ movdbl(xmm_name, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
 510         offset += 8;
 511       }
 512     } else if (UseSSE == 1) {
 513       // restore XMM registers(num MMX == num fpu)
 514       int offset = 0;
 515       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 516         XMMRegister xmm_name = as_XMMRegister(n);


 527     }
 528 
 529   } else {
 530     // check that FPU stack is really empty
 531     __ verify_FPU(0, "restore_live_registers");
 532   }
 533 
 534 #ifdef ASSERT
 535   {
 536     Label ok;
 537     __ cmpptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef);
 538     __ jcc(Assembler::equal, ok);
 539     __ stop("bad offsets in frame");
 540     __ bind(ok);
 541   }
 542 #endif // ASSERT
 543 
 544   __ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
 545 }
 546 


 547 
 548 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
 549   __ block_comment("restore_live_registers");
 550 
 551   restore_fpu(sasm, restore_fpu_registers);
 552   __ popa();
 553 }
 554 












 555 
 556 static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
 557   __ block_comment("restore_live_registers_except_rax");
 558 
 559   restore_fpu(sasm, restore_fpu_registers);
 560 
 561 #ifdef _LP64
 562   __ movptr(r15, Address(rsp, 0));
 563   __ movptr(r14, Address(rsp, wordSize));
 564   __ movptr(r13, Address(rsp, 2 * wordSize));
 565   __ movptr(r12, Address(rsp, 3 * wordSize));
 566   __ movptr(r11, Address(rsp, 4 * wordSize));
 567   __ movptr(r10, Address(rsp, 5 * wordSize));
 568   __ movptr(r9,  Address(rsp, 6 * wordSize));
 569   __ movptr(r8,  Address(rsp, 7 * wordSize));
 570   __ movptr(rdi, Address(rsp, 8 * wordSize));
 571   __ movptr(rsi, Address(rsp, 9 * wordSize));
 572   __ movptr(rbp, Address(rsp, 10 * wordSize));
 573   // skip rsp
 574   __ movptr(rbx, Address(rsp, 12 * wordSize));


1583 #endif // _LP64
1584         __ jmp(do_return);
1585 
1586         __ bind(return0);
1587         __ fpop();
1588 #ifndef _LP64
1589         __ xorptr(rdx,rdx);
1590         __ xorptr(rax,rax);
1591 #else
1592         __ xorptr(rax, rax);
1593 #endif // _LP64
1594 
1595         __ bind(do_return);
1596         __ addptr(rsp, 32);
1597         LP64_ONLY(__ pop(rdx);)
1598         __ pop(rcx);
1599         __ pop(rsi);
1600         __ ret(0);
1601       }
1602       break;
1603 
1604 #if INCLUDE_ALL_GCS
1605     case g1_pre_barrier_slow_id:
1606       {
1607         StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
1608         // arg0 : previous value of memory
1609 
1610         BarrierSet* bs = Universe::heap()->barrier_set();
1611         if (bs->kind() != BarrierSet::G1SATBCTLogging) {
1612           __ movptr(rax, (int)id);
1613           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax);
1614           __ should_not_reach_here();
1615           break;
1616         }
1617         __ push(rax);
1618         __ push(rdx);
1619 
1620         const Register pre_val = rax;
1621         const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
1622         const Register tmp = rdx;
1623 
1624         NOT_LP64(__ get_thread(thread);)
1625 
1626         Address queue_active(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1627                                               SATBMarkQueue::byte_offset_of_active()));
1628         Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1629                                              SATBMarkQueue::byte_offset_of_index()));
1630         Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
1631                                         SATBMarkQueue::byte_offset_of_buf()));
1632 
1633         Label done;
1634         Label runtime;
1635 
1636         // Is marking still active?
1637         if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
1638           __ cmpl(queue_active, 0);
1639         } else {
1640           assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
1641           __ cmpb(queue_active, 0);
1642         }
1643         __ jcc(Assembler::equal, done);
1644 
1645         // Can we store original value in the thread's buffer?
1646 
1647         __ movptr(tmp, queue_index);
1648         __ testptr(tmp, tmp);
1649         __ jcc(Assembler::zero, runtime);
1650         __ subptr(tmp, wordSize);
1651         __ movptr(queue_index, tmp);
1652         __ addptr(tmp, buffer);
1653 
1654         // prev_val (rax)
1655         f.load_argument(0, pre_val);
1656         __ movptr(Address(tmp, 0), pre_val);
1657         __ jmp(done);
1658 
1659         __ bind(runtime);
1660 
1661         save_live_registers(sasm, 3);
1662 
1663         // load the pre-value
1664         f.load_argument(0, rcx);
1665         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread);
1666 
1667         restore_live_registers(sasm);
1668 
1669         __ bind(done);
1670 
1671         __ pop(rdx);
1672         __ pop(rax);
1673       }
1674       break;
1675 
1676     case g1_post_barrier_slow_id:
1677       {
1678         StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments);
1679 
1680 
1681         // arg0: store_address
1682         Address store_addr(rbp, 2*BytesPerWord);
1683 
1684         CardTableModRefBS* ct =
1685           barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
1686         assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
1687 
1688         Label done;
1689         Label enqueued;
1690         Label runtime;
1691 
1692         // At this point we know new_value is non-NULL and the new_value crosses regions.
1693         // Must check to see if card is already dirty
1694 
1695         const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
1696 
1697         Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1698                                              DirtyCardQueue::byte_offset_of_index()));
1699         Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
1700                                         DirtyCardQueue::byte_offset_of_buf()));
1701 
1702         __ push(rax);
1703         __ push(rcx);
1704 
1705         const Register cardtable = rax;
1706         const Register card_addr = rcx;
1707 
1708         f.load_argument(0, card_addr);
1709         __ shrptr(card_addr, CardTableModRefBS::card_shift);
1710         // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
1711         // a valid address and therefore is not properly handled by the relocation code.
1712         __ movptr(cardtable, (intptr_t)ct->byte_map_base);
1713         __ addptr(card_addr, cardtable);
1714 
1715         NOT_LP64(__ get_thread(thread);)
1716 
1717         __ cmpb(Address(card_addr, 0), (int)G1SATBCardTableModRefBS::g1_young_card_val());
1718         __ jcc(Assembler::equal, done);
1719 
1720         __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
1721         __ cmpb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
1722         __ jcc(Assembler::equal, done);
1723 
1724         // storing region crossing non-NULL, card is clean.
1725         // dirty card and log.
1726 
1727         __ movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
1728 
1729         const Register tmp = rdx;
1730         __ push(rdx);
1731 
1732         __ movptr(tmp, queue_index);
1733         __ testptr(tmp, tmp);
1734         __ jcc(Assembler::zero, runtime);
1735         __ subptr(tmp, wordSize);
1736         __ movptr(queue_index, tmp);
1737         __ addptr(tmp, buffer);
1738         __ movptr(Address(tmp, 0), card_addr);
1739         __ jmp(enqueued);
1740 
1741         __ bind(runtime);
1742 
1743         save_live_registers(sasm, 3);
1744 
1745         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
1746 
1747         restore_live_registers(sasm);
1748 
1749         __ bind(enqueued);
1750         __ pop(rdx);
1751 
1752         __ bind(done);
1753         __ pop(rcx);
1754         __ pop(rax);
1755       }
1756       break;
1757 #endif // INCLUDE_ALL_GCS
1758 
1759     case predicate_failed_trap_id:
1760       {
1761         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1762 
1763         OopMap* map = save_live_registers(sasm, 1);
1764 
1765         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1766         oop_maps = new OopMapSet();
1767         oop_maps->add_gc_map(call_offset, map);
1768         restore_live_registers(sasm);
1769         __ leave();
1770         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1771         assert(deopt_blob != NULL, "deoptimization blob must have been created");
1772 
1773         __ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1774       }
1775       break;
1776 
1777     default:


  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "asm/assembler.hpp"
  27 #include "c1/c1_Defs.hpp"
  28 #include "c1/c1_MacroAssembler.hpp"
  29 #include "c1/c1_Runtime1.hpp"
  30 #include "interpreter/interpreter.hpp"
  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 
  42 // Implementation of StubAssembler
  43 
  44 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
  45   // setup registers
  46   const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions)
  47   assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different");
  48   assert(oop_result1 != thread && metadata_result != thread, "registers must be different");
  49   assert(args_size >= 0, "illegal args_size");
  50   bool align_stack = false;
  51 #ifdef _LP64
  52   // At a method handle call, the stack may not be properly aligned
  53   // when returning with an exception.
  54   align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
  55 #endif
  56 
  57 #ifdef _LP64
  58   mov(c_rarg0, thread);
  59   set_num_rt_args(0); // Nothing on stack
  60 #else


 186   push(arg2);
 187   push(arg1);
 188 #endif // _LP64
 189   return call_RT(oop_result1, metadata_result, entry, 3);
 190 }
 191 
 192 
 193 // Implementation of StubFrame
 194 
 195 class StubFrame: public StackObj {
 196  private:
 197   StubAssembler* _sasm;
 198 
 199  public:
 200   StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments);
 201   void load_argument(int offset_in_words, Register reg);
 202 
 203   ~StubFrame();
 204 };
 205 
 206 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
 207   set_info(name, must_gc_arguments);
 208   enter();
 209 }
 210 
 211 void StubAssembler::epilogue() {
 212   leave();
 213   ret(0);
 214 }
 215 
 216 #define __ _sasm->
 217 
 218 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
 219   _sasm = sasm;
 220   __ prologue(name, must_gc_arguments);

 221 }
 222 
 223 // load parameters that were stored with LIR_Assembler::store_parameter
 224 // Note: offsets for store_parameter and load_argument must match
 225 void StubFrame::load_argument(int offset_in_words, Register reg) {
 226   __ load_parameter(offset_in_words, reg);






 227 }
 228 
 229 
 230 StubFrame::~StubFrame() {
 231   __ epilogue();

 232 }
 233 
 234 #undef __
 235 
 236 
 237 // Implementation of Runtime1
 238 


 239 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
 240 const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2;
 241 
 242 // Stack layout for saving/restoring  all the registers needed during a runtime
 243 // call (this includes deoptimization)
 244 // Note: note that users of this frame may well have arguments to some runtime
 245 // while these values are on the stack. These positions neglect those arguments
 246 // but the code in save_live_registers will take the argument count into
 247 // account.
 248 //
 249 #ifdef _LP64
 250   #define SLOT2(x) x,
 251   #define SLOT_PER_WORD 2
 252 #else
 253   #define SLOT2(x)
 254   #define SLOT_PER_WORD 1
 255 #endif // _LP64
 256 
 257 enum reg_save_layout {
 258   // 64bit needs to keep stack 16 byte aligned. So we add some alignment dummies to make that


 283   r11_off, r11H_off,                                                                        // 392, 396
 284   r10_off, r10H_off,                                                                        // 400, 404
 285   r9_off, r9H_off,                                                                          // 408, 412
 286   r8_off, r8H_off,                                                                          // 416, 420
 287   rdi_off, rdiH_off,                                                                        // 424, 428
 288 #else
 289   rdi_off = extra_space_offset,
 290 #endif // _LP64
 291   rsi_off, SLOT2(rsiH_off)                                                                  // 432, 436
 292   rbp_off, SLOT2(rbpH_off)                                                                  // 440, 444
 293   rsp_off, SLOT2(rspH_off)                                                                  // 448, 452
 294   rbx_off, SLOT2(rbxH_off)                                                                  // 456, 460
 295   rdx_off, SLOT2(rdxH_off)                                                                  // 464, 468
 296   rcx_off, SLOT2(rcxH_off)                                                                  // 472, 476
 297   rax_off, SLOT2(raxH_off)                                                                  // 480, 484
 298   saved_rbp_off, SLOT2(saved_rbpH_off)                                                      // 488, 492
 299   return_off, SLOT2(returnH_off)                                                            // 496, 500
 300   reg_save_frame_size   // As noted: neglects any parameters to runtime                     // 504
 301 };
 302 


 303 // Save off registers which might be killed by calls into the runtime.
 304 // Tries to smart of about FP registers.  In particular we separate
 305 // saving and describing the FPU registers for deoptimization since we
 306 // have to save the FPU registers twice if we describe them and on P4
 307 // saving FPU registers which don't contain anything appears
 308 // expensive.  The deopt blob is the only thing which needs to
 309 // describe FPU registers.  In all other cases it should be sufficient
 310 // to simply save their current value.
 311 
 312 static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
 313                                 bool save_fpu_registers = true) {
 314 
 315   // In 64bit all the args are in regs so there are no additional stack slots
 316   LP64_ONLY(num_rt_args = 0);
 317   LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
 318   int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread
 319   sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word);
 320 
 321   // record saved value locations in an OopMap
 322   // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread


 389           }
 390         }
 391         xmm_off += 2;
 392       }
 393       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 394 
 395     } else if (UseSSE == 1) {
 396       int xmm_off = xmm_regs_as_doubles_off;
 397       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 398         VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
 399         map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
 400         xmm_off += 2;
 401       }
 402       assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
 403     }
 404   }
 405 
 406   return map;
 407 }
 408 
 409 #define __ this->
 410 
 411 void C1_MacroAssembler::save_live_registers_no_oop_map(int num_rt_args, bool save_fpu_registers) {
 412   __ block_comment("save_live_registers");
 413 
 414   __ pusha();         // integer registers
 415 
 416   // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
 417   // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset");
 418 
 419   __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
 420 
 421 #ifdef ASSERT
 422   __ movptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef);
 423 #endif
 424 
 425   if (save_fpu_registers) {
 426     if (UseSSE < 2) {
 427       // save FPU stack
 428       __ fnsave(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size));
 429       __ fwait();
 430 
 431 #ifdef ASSERT


 465       }
 466 #endif
 467       for (int n = 0; n < xmm_bypass_limit; n++) {
 468         XMMRegister xmm_name = as_XMMRegister(n);
 469         __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
 470         offset += 8;
 471       }
 472     } else if (UseSSE == 1) {
 473       // save XMM registers as float because double not supported without SSE2(num MMX == num fpu)
 474       int offset = 0;
 475       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 476         XMMRegister xmm_name = as_XMMRegister(n);
 477         __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
 478         offset += 8;
 479       }
 480     }
 481   }
 482 
 483   // FPU stack must be empty now
 484   __ verify_FPU(0, "save_live_registers");


 485 }
 486 
 487 #undef __
 488 #define __ sasm->
 489 
 490 static void restore_fpu(C1_MacroAssembler* sasm, bool restore_fpu_registers) {
 491   if (restore_fpu_registers) {
 492     if (UseSSE >= 2) {
 493       // restore XMM registers
 494       int xmm_bypass_limit = FrameMap::nof_xmm_regs;
 495 #ifdef _LP64
 496       if (UseAVX < 3) {
 497         xmm_bypass_limit = xmm_bypass_limit / 2;
 498       }
 499 #endif
 500       int offset = 0;
 501       for (int n = 0; n < xmm_bypass_limit; n++) {
 502         XMMRegister xmm_name = as_XMMRegister(n);
 503         __ movdbl(xmm_name, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
 504         offset += 8;
 505       }
 506     } else if (UseSSE == 1) {
 507       // restore XMM registers(num MMX == num fpu)
 508       int offset = 0;
 509       for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
 510         XMMRegister xmm_name = as_XMMRegister(n);


 521     }
 522 
 523   } else {
 524     // check that FPU stack is really empty
 525     __ verify_FPU(0, "restore_live_registers");
 526   }
 527 
 528 #ifdef ASSERT
 529   {
 530     Label ok;
 531     __ cmpptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef);
 532     __ jcc(Assembler::equal, ok);
 533     __ stop("bad offsets in frame");
 534     __ bind(ok);
 535   }
 536 #endif // ASSERT
 537 
 538   __ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
 539 }
 540 
 541 #undef __
 542 #define __ this->
 543 
 544 void C1_MacroAssembler::restore_live_registers(bool restore_fpu_registers) {
 545   __ block_comment("restore_live_registers");
 546 
 547   restore_fpu(this, restore_fpu_registers);
 548   __ popa();
 549 }
 550 
 551 #undef __
 552 #define __ sasm->
 553 
 554 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
 555                                    bool save_fpu_registers = true) {
 556   sasm->save_live_registers_no_oop_map(num_rt_args, save_fpu_registers);
 557   return generate_oop_map(sasm, num_rt_args, save_fpu_registers);
 558 }
 559 
 560 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
 561   sasm->restore_live_registers(restore_fpu_registers);
 562 }
 563 
 564 static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
 565   __ block_comment("restore_live_registers_except_rax");
 566 
 567   restore_fpu(sasm, restore_fpu_registers);
 568 
 569 #ifdef _LP64
 570   __ movptr(r15, Address(rsp, 0));
 571   __ movptr(r14, Address(rsp, wordSize));
 572   __ movptr(r13, Address(rsp, 2 * wordSize));
 573   __ movptr(r12, Address(rsp, 3 * wordSize));
 574   __ movptr(r11, Address(rsp, 4 * wordSize));
 575   __ movptr(r10, Address(rsp, 5 * wordSize));
 576   __ movptr(r9,  Address(rsp, 6 * wordSize));
 577   __ movptr(r8,  Address(rsp, 7 * wordSize));
 578   __ movptr(rdi, Address(rsp, 8 * wordSize));
 579   __ movptr(rsi, Address(rsp, 9 * wordSize));
 580   __ movptr(rbp, Address(rsp, 10 * wordSize));
 581   // skip rsp
 582   __ movptr(rbx, Address(rsp, 12 * wordSize));


1591 #endif // _LP64
1592         __ jmp(do_return);
1593 
1594         __ bind(return0);
1595         __ fpop();
1596 #ifndef _LP64
1597         __ xorptr(rdx,rdx);
1598         __ xorptr(rax,rax);
1599 #else
1600         __ xorptr(rax, rax);
1601 #endif // _LP64
1602 
1603         __ bind(do_return);
1604         __ addptr(rsp, 32);
1605         LP64_ONLY(__ pop(rdx);)
1606         __ pop(rcx);
1607         __ pop(rsi);
1608         __ ret(0);
1609       }
1610       break;



























































































































































1611 
1612     case predicate_failed_trap_id:
1613       {
1614         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1615 
1616         OopMap* map = save_live_registers(sasm, 1);
1617 
1618         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1619         oop_maps = new OopMapSet();
1620         oop_maps->add_gc_map(call_offset, map);
1621         restore_live_registers(sasm);
1622         __ leave();
1623         DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1624         assert(deopt_blob != NULL, "deoptimization blob must have been created");
1625 
1626         __ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1627       }
1628       break;
1629 
1630     default:
< prev index next >