src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
changeset 49906 4bb58f644e4e
parent 49754 ee93c1087584
child 50023 bdb627563075
child 56508 f67f588ebf15
equal deleted inserted replaced
49905:a09af8ef8e5c 49906:4bb58f644e4e
    39 #include "runtime/sharedRuntime.hpp"
    39 #include "runtime/sharedRuntime.hpp"
    40 #include "runtime/signature.hpp"
    40 #include "runtime/signature.hpp"
    41 #include "runtime/vframeArray.hpp"
    41 #include "runtime/vframeArray.hpp"
    42 #include "utilities/macros.hpp"
    42 #include "utilities/macros.hpp"
    43 #include "vmreg_x86.inline.hpp"
    43 #include "vmreg_x86.inline.hpp"
    44 #if INCLUDE_ALL_GCS
       
    45 #include "gc/g1/g1BarrierSet.hpp"
       
    46 #include "gc/g1/g1CardTable.hpp"
       
    47 #include "gc/g1/g1ThreadLocalData.hpp"
       
    48 #endif
       
    49 
       
    50 
    44 
    51 // Implementation of StubAssembler
    45 // Implementation of StubAssembler
    52 
    46 
    53 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
    47 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
    54   // setup registers
    48   // setup registers
   210   void load_argument(int offset_in_words, Register reg);
   204   void load_argument(int offset_in_words, Register reg);
   211 
   205 
   212   ~StubFrame();
   206   ~StubFrame();
   213 };
   207 };
   214 
   208 
       
   209 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
       
   210   set_info(name, must_gc_arguments);
       
   211   enter();
       
   212 }
       
   213 
       
   214 void StubAssembler::epilogue() {
       
   215   leave();
       
   216   ret(0);
       
   217 }
   215 
   218 
   216 #define __ _sasm->
   219 #define __ _sasm->
   217 
   220 
   218 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
   221 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
   219   _sasm = sasm;
   222   _sasm = sasm;
   220   __ set_info(name, must_gc_arguments);
   223   __ prologue(name, must_gc_arguments);
   221   __ enter();
       
   222 }
   224 }
   223 
   225 
   224 // load parameters that were stored with LIR_Assembler::store_parameter
   226 // load parameters that were stored with LIR_Assembler::store_parameter
   225 // Note: offsets for store_parameter and load_argument must match
   227 // Note: offsets for store_parameter and load_argument must match
   226 void StubFrame::load_argument(int offset_in_words, Register reg) {
   228 void StubFrame::load_argument(int offset_in_words, Register reg) {
   227   // rbp, + 0: link
   229   __ load_parameter(offset_in_words, reg);
   228   //     + 1: return address
       
   229   //     + 2: argument with offset 0
       
   230   //     + 3: argument with offset 1
       
   231   //     + 4: ...
       
   232 
       
   233   __ movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
       
   234 }
   230 }
   235 
   231 
   236 
   232 
   237 StubFrame::~StubFrame() {
   233 StubFrame::~StubFrame() {
   238   __ leave();
   234   __ epilogue();
   239   __ ret(0);
       
   240 }
   235 }
   241 
   236 
   242 #undef __
   237 #undef __
   243 
   238 
   244 
   239 
   245 // Implementation of Runtime1
   240 // Implementation of Runtime1
   246 
       
   247 #define __ sasm->
       
   248 
   241 
   249 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
   242 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
   250 const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2;
   243 const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2;
   251 
   244 
   252 // Stack layout for saving/restoring  all the registers needed during a runtime
   245 // Stack layout for saving/restoring  all the registers needed during a runtime
   308   saved_rbp_off, SLOT2(saved_rbpH_off)                                                      // 488, 492
   301   saved_rbp_off, SLOT2(saved_rbpH_off)                                                      // 488, 492
   309   return_off, SLOT2(returnH_off)                                                            // 496, 500
   302   return_off, SLOT2(returnH_off)                                                            // 496, 500
   310   reg_save_frame_size   // As noted: neglects any parameters to runtime                     // 504
   303   reg_save_frame_size   // As noted: neglects any parameters to runtime                     // 504
   311 };
   304 };
   312 
   305 
   313 
       
   314 
       
   315 // Save off registers which might be killed by calls into the runtime.
   306 // Save off registers which might be killed by calls into the runtime.
   316 // Tries to smart of about FP registers.  In particular we separate
   307 // Tries to smart of about FP registers.  In particular we separate
   317 // saving and describing the FPU registers for deoptimization since we
   308 // saving and describing the FPU registers for deoptimization since we
   318 // have to save the FPU registers twice if we describe them and on P4
   309 // have to save the FPU registers twice if we describe them and on P4
   319 // saving FPU registers which don't contain anything appears
   310 // saving FPU registers which don't contain anything appears
   416   }
   407   }
   417 
   408 
   418   return map;
   409   return map;
   419 }
   410 }
   420 
   411 
   421 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
   412 #define __ this->
   422                                    bool save_fpu_registers = true) {
   413 
       
   414 void C1_MacroAssembler::save_live_registers_no_oop_map(int num_rt_args, bool save_fpu_registers) {
   423   __ block_comment("save_live_registers");
   415   __ block_comment("save_live_registers");
   424 
   416 
   425   __ pusha();         // integer registers
   417   __ pusha();         // integer registers
   426 
   418 
   427   // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
   419   // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
   491     }
   483     }
   492   }
   484   }
   493 
   485 
   494   // FPU stack must be empty now
   486   // FPU stack must be empty now
   495   __ verify_FPU(0, "save_live_registers");
   487   __ verify_FPU(0, "save_live_registers");
   496 
   488 }
   497   return generate_oop_map(sasm, num_rt_args, save_fpu_registers);
   489 
   498 }
   490 #undef __
   499 
   491 #define __ sasm->
   500 
   492 
   501 static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true) {
   493 static void restore_fpu(C1_MacroAssembler* sasm, bool restore_fpu_registers) {
   502   if (restore_fpu_registers) {
   494   if (restore_fpu_registers) {
   503     if (UseSSE >= 2) {
   495     if (UseSSE >= 2) {
   504       // restore XMM registers
   496       // restore XMM registers
   505       int xmm_bypass_limit = FrameMap::nof_xmm_regs;
   497       int xmm_bypass_limit = FrameMap::nof_xmm_regs;
   506 #ifdef _LP64
   498 #ifdef _LP64
   547 #endif // ASSERT
   539 #endif // ASSERT
   548 
   540 
   549   __ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
   541   __ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
   550 }
   542 }
   551 
   543 
       
   544 #undef __
       
   545 #define __ this->
       
   546 
       
   547 void C1_MacroAssembler::restore_live_registers(bool restore_fpu_registers) {
       
   548   __ block_comment("restore_live_registers");
       
   549 
       
   550   restore_fpu(this, restore_fpu_registers);
       
   551   __ popa();
       
   552 }
       
   553 
       
   554 #undef __
       
   555 #define __ sasm->
       
   556 
       
   557 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
       
   558                                    bool save_fpu_registers = true) {
       
   559   sasm->save_live_registers_no_oop_map(num_rt_args, save_fpu_registers);
       
   560   return generate_oop_map(sasm, num_rt_args, save_fpu_registers);
       
   561 }
   552 
   562 
   553 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
   563 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
   554   __ block_comment("restore_live_registers");
   564   sasm->restore_live_registers(restore_fpu_registers);
   555 
   565 }
   556   restore_fpu(sasm, restore_fpu_registers);
       
   557   __ popa();
       
   558 }
       
   559 
       
   560 
   566 
   561 static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
   567 static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
   562   __ block_comment("restore_live_registers_except_rax");
   568   __ block_comment("restore_live_registers_except_rax");
   563 
   569 
   564   restore_fpu(sasm, restore_fpu_registers);
   570   restore_fpu(sasm, restore_fpu_registers);
  1555         __ pop(rsi);
  1561         __ pop(rsi);
  1556         __ ret(0);
  1562         __ ret(0);
  1557       }
  1563       }
  1558       break;
  1564       break;
  1559 
  1565 
  1560 #if INCLUDE_ALL_GCS
       
  1561     case g1_pre_barrier_slow_id:
       
  1562       {
       
  1563         StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments);
       
  1564         // arg0 : previous value of memory
       
  1565 
       
  1566         BarrierSet* bs = BarrierSet::barrier_set();
       
  1567         if (bs->kind() != BarrierSet::G1BarrierSet) {
       
  1568           __ movptr(rax, (int)id);
       
  1569           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax);
       
  1570           __ should_not_reach_here();
       
  1571           break;
       
  1572         }
       
  1573         __ push(rax);
       
  1574         __ push(rdx);
       
  1575 
       
  1576         const Register pre_val = rax;
       
  1577         const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
       
  1578         const Register tmp = rdx;
       
  1579 
       
  1580         NOT_LP64(__ get_thread(thread);)
       
  1581 
       
  1582         Address queue_active(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
       
  1583         Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
       
  1584         Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
       
  1585 
       
  1586         Label done;
       
  1587         Label runtime;
       
  1588 
       
  1589         // Is marking still active?
       
  1590         if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
       
  1591           __ cmpl(queue_active, 0);
       
  1592         } else {
       
  1593           assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
       
  1594           __ cmpb(queue_active, 0);
       
  1595         }
       
  1596         __ jcc(Assembler::equal, done);
       
  1597 
       
  1598         // Can we store original value in the thread's buffer?
       
  1599 
       
  1600         __ movptr(tmp, queue_index);
       
  1601         __ testptr(tmp, tmp);
       
  1602         __ jcc(Assembler::zero, runtime);
       
  1603         __ subptr(tmp, wordSize);
       
  1604         __ movptr(queue_index, tmp);
       
  1605         __ addptr(tmp, buffer);
       
  1606 
       
  1607         // prev_val (rax)
       
  1608         f.load_argument(0, pre_val);
       
  1609         __ movptr(Address(tmp, 0), pre_val);
       
  1610         __ jmp(done);
       
  1611 
       
  1612         __ bind(runtime);
       
  1613 
       
  1614         save_live_registers(sasm, 3);
       
  1615 
       
  1616         // load the pre-value
       
  1617         f.load_argument(0, rcx);
       
  1618         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread);
       
  1619 
       
  1620         restore_live_registers(sasm);
       
  1621 
       
  1622         __ bind(done);
       
  1623 
       
  1624         __ pop(rdx);
       
  1625         __ pop(rax);
       
  1626       }
       
  1627       break;
       
  1628 
       
  1629     case g1_post_barrier_slow_id:
       
  1630       {
       
  1631         StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments);
       
  1632 
       
  1633         BarrierSet* bs = BarrierSet::barrier_set();
       
  1634         if (bs->kind() != BarrierSet::G1BarrierSet) {
       
  1635           __ movptr(rax, (int)id);
       
  1636           __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax);
       
  1637           __ should_not_reach_here();
       
  1638           break;
       
  1639         }
       
  1640 
       
  1641         // arg0: store_address
       
  1642         Address store_addr(rbp, 2*BytesPerWord);
       
  1643 
       
  1644         Label done;
       
  1645         Label enqueued;
       
  1646         Label runtime;
       
  1647 
       
  1648         // At this point we know new_value is non-NULL and the new_value crosses regions.
       
  1649         // Must check to see if card is already dirty
       
  1650 
       
  1651         const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
       
  1652 
       
  1653         Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
       
  1654         Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
       
  1655 
       
  1656         __ push(rax);
       
  1657         __ push(rcx);
       
  1658 
       
  1659         const Register cardtable = rax;
       
  1660         const Register card_addr = rcx;
       
  1661 
       
  1662         f.load_argument(0, card_addr);
       
  1663         __ shrptr(card_addr, CardTable::card_shift);
       
  1664         // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
       
  1665         // a valid address and therefore is not properly handled by the relocation code.
       
  1666         __ movptr(cardtable, ci_card_table_address_as<intptr_t>());
       
  1667         __ addptr(card_addr, cardtable);
       
  1668 
       
  1669         NOT_LP64(__ get_thread(thread);)
       
  1670 
       
  1671         __ cmpb(Address(card_addr, 0), (int)G1CardTable::g1_young_card_val());
       
  1672         __ jcc(Assembler::equal, done);
       
  1673 
       
  1674         __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
       
  1675         __ cmpb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
       
  1676         __ jcc(Assembler::equal, done);
       
  1677 
       
  1678         // storing region crossing non-NULL, card is clean.
       
  1679         // dirty card and log.
       
  1680 
       
  1681         __ movb(Address(card_addr, 0), (int)CardTable::dirty_card_val());
       
  1682 
       
  1683         const Register tmp = rdx;
       
  1684         __ push(rdx);
       
  1685 
       
  1686         __ movptr(tmp, queue_index);
       
  1687         __ testptr(tmp, tmp);
       
  1688         __ jcc(Assembler::zero, runtime);
       
  1689         __ subptr(tmp, wordSize);
       
  1690         __ movptr(queue_index, tmp);
       
  1691         __ addptr(tmp, buffer);
       
  1692         __ movptr(Address(tmp, 0), card_addr);
       
  1693         __ jmp(enqueued);
       
  1694 
       
  1695         __ bind(runtime);
       
  1696 
       
  1697         save_live_registers(sasm, 3);
       
  1698 
       
  1699         __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
       
  1700 
       
  1701         restore_live_registers(sasm);
       
  1702 
       
  1703         __ bind(enqueued);
       
  1704         __ pop(rdx);
       
  1705 
       
  1706         __ bind(done);
       
  1707         __ pop(rcx);
       
  1708         __ pop(rax);
       
  1709       }
       
  1710       break;
       
  1711 #endif // INCLUDE_ALL_GCS
       
  1712 
       
  1713     case predicate_failed_trap_id:
  1566     case predicate_failed_trap_id:
  1714       {
  1567       {
  1715         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
  1568         StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
  1716 
  1569 
  1717         OopMap* map = save_live_registers(sasm, 1);
  1570         OopMap* map = save_live_registers(sasm, 1);