src/cpu/x86/vm/x86_64.ad

changeset 6356
4d4ea046d32a
parent 6288
984401824c5e
child 6375
085b304a1cc5
     1.1 --- a/src/cpu/x86/vm/x86_64.ad	Thu Mar 06 12:45:59 2014 +0400
     1.2 +++ b/src/cpu/x86/vm/x86_64.ad	Mon Feb 24 15:12:26 2014 -0800
     1.3 @@ -2591,231 +2591,6 @@
     1.4    %}
     1.5  
     1.6  
     1.7 -  // obj: object to lock
     1.8 -  // box: box address (header location) -- killed
     1.9 -  // tmp: rax -- killed
    1.10 -  // scr: rbx -- killed
    1.11 -  //
    1.12 -  // What follows is a direct transliteration of fast_lock() and fast_unlock()
    1.13 -  // from i486.ad.  See that file for comments.
    1.14 -  // TODO: where possible switch from movq (r, 0) to movl(r,0) and
    1.15 -  // use the shorter encoding.  (Movl clears the high-order 32-bits).
    1.16 -
    1.17 -
    1.18 -  enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
    1.19 -  %{
    1.20 -    Register objReg = as_Register((int)$obj$$reg);
    1.21 -    Register boxReg = as_Register((int)$box$$reg);
    1.22 -    Register tmpReg = as_Register($tmp$$reg);
    1.23 -    Register scrReg = as_Register($scr$$reg);
    1.24 -    MacroAssembler masm(&cbuf);
    1.25 -
    1.26 -    // Verify uniqueness of register assignments -- necessary but not sufficient
    1.27 -    assert (objReg != boxReg && objReg != tmpReg &&
    1.28 -            objReg != scrReg && tmpReg != scrReg, "invariant") ;
    1.29 -
    1.30 -    if (_counters != NULL) {
    1.31 -      masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
    1.32 -    }
    1.33 -    if (EmitSync & 1) {
    1.34 -        // Without cast to int32_t a movptr will destroy r10 which is typically obj
    1.35 -        masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
    1.36 -        masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
    1.37 -    } else
    1.38 -    if (EmitSync & 2) {
    1.39 -        Label DONE_LABEL;
    1.40 -        if (UseBiasedLocking) {
    1.41 -           // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
    1.42 -          masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
    1.43 -        }
    1.44 -        // QQQ was movl...
    1.45 -        masm.movptr(tmpReg, 0x1);
    1.46 -        masm.orptr(tmpReg, Address(objReg, 0));
    1.47 -        masm.movptr(Address(boxReg, 0), tmpReg);
    1.48 -        if (os::is_MP()) {
    1.49 -          masm.lock();
    1.50 -        }
    1.51 -        masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
    1.52 -        masm.jcc(Assembler::equal, DONE_LABEL);
    1.53 -
    1.54 -        // Recursive locking
    1.55 -        masm.subptr(tmpReg, rsp);
    1.56 -        masm.andptr(tmpReg, 7 - os::vm_page_size());
    1.57 -        masm.movptr(Address(boxReg, 0), tmpReg);
    1.58 -
    1.59 -        masm.bind(DONE_LABEL);
    1.60 -        masm.nop(); // avoid branch to branch
    1.61 -    } else {
    1.62 -        Label DONE_LABEL, IsInflated, Egress;
    1.63 -
    1.64 -        masm.movptr(tmpReg, Address(objReg, 0)) ;
    1.65 -        masm.testl (tmpReg, 0x02) ;         // inflated vs stack-locked|neutral|biased
    1.66 -        masm.jcc   (Assembler::notZero, IsInflated) ;
    1.67 -
    1.68 -        // it's stack-locked, biased or neutral
    1.69 -        // TODO: optimize markword triage order to reduce the number of
    1.70 -        // conditional branches in the most common cases.
    1.71 -        // Beware -- there's a subtle invariant that fetch of the markword
    1.72 -        // at [FETCH], below, will never observe a biased encoding (*101b).
    1.73 -        // If this invariant is not held we'll suffer exclusion (safety) failure.
    1.74 -
    1.75 -        if (UseBiasedLocking && !UseOptoBiasInlining) {
    1.76 -          masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
    1.77 -          masm.movptr(tmpReg, Address(objReg, 0)) ;        // [FETCH]
    1.78 -        }
    1.79 -
    1.80 -        // was q will it destroy high?
    1.81 -        masm.orl   (tmpReg, 1) ;
    1.82 -        masm.movptr(Address(boxReg, 0), tmpReg) ;
    1.83 -        if (os::is_MP()) { masm.lock(); }
    1.84 -        masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
    1.85 -        if (_counters != NULL) {
    1.86 -           masm.cond_inc32(Assembler::equal,
    1.87 -                           ExternalAddress((address) _counters->fast_path_entry_count_addr()));
    1.88 -        }
    1.89 -        masm.jcc   (Assembler::equal, DONE_LABEL);
    1.90 -
    1.91 -        // Recursive locking
    1.92 -        masm.subptr(tmpReg, rsp);
    1.93 -        masm.andptr(tmpReg, 7 - os::vm_page_size());
    1.94 -        masm.movptr(Address(boxReg, 0), tmpReg);
    1.95 -        if (_counters != NULL) {
    1.96 -           masm.cond_inc32(Assembler::equal,
    1.97 -                           ExternalAddress((address) _counters->fast_path_entry_count_addr()));
    1.98 -        }
    1.99 -        masm.jmp   (DONE_LABEL) ;
   1.100 -
   1.101 -        masm.bind  (IsInflated) ;
   1.102 -        // It's inflated
   1.103 -
   1.104 -        // TODO: someday avoid the ST-before-CAS penalty by
   1.105 -        // relocating (deferring) the following ST.
   1.106 -        // We should also think about trying a CAS without having
   1.107 -        // fetched _owner.  If the CAS is successful we may
   1.108 -        // avoid an RTO->RTS upgrade on the $line.
   1.109 -        // Without cast to int32_t a movptr will destroy r10 which is typically obj
   1.110 -        masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
   1.111 -
   1.112 -        masm.mov    (boxReg, tmpReg) ;
   1.113 -        masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
   1.114 -        masm.testptr(tmpReg, tmpReg) ;
   1.115 -        masm.jcc    (Assembler::notZero, DONE_LABEL) ;
   1.116 -
   1.117 -        // It's inflated and appears unlocked
   1.118 -        if (os::is_MP()) { masm.lock(); }
   1.119 -        masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
   1.120 -        // Intentional fall-through into DONE_LABEL ...
   1.121 -
   1.122 -        masm.bind  (DONE_LABEL) ;
   1.123 -        masm.nop   () ;                 // avoid jmp to jmp
   1.124 -    }
   1.125 -  %}
   1.126 -
   1.127 -  // obj: object to unlock
   1.128 -  // box: box address (displaced header location), killed
   1.129 -  // RBX: killed tmp; cannot be obj nor box
   1.130 -  enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp)
   1.131 -  %{
   1.132 -
   1.133 -    Register objReg = as_Register($obj$$reg);
   1.134 -    Register boxReg = as_Register($box$$reg);
   1.135 -    Register tmpReg = as_Register($tmp$$reg);
   1.136 -    MacroAssembler masm(&cbuf);
   1.137 -
   1.138 -    if (EmitSync & 4) {
   1.139 -       masm.cmpptr(rsp, 0) ;
   1.140 -    } else
   1.141 -    if (EmitSync & 8) {
   1.142 -       Label DONE_LABEL;
   1.143 -       if (UseBiasedLocking) {
   1.144 -         masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
   1.145 -       }
   1.146 -
   1.147 -       // Check whether the displaced header is 0
   1.148 -       //(=> recursive unlock)
   1.149 -       masm.movptr(tmpReg, Address(boxReg, 0));
   1.150 -       masm.testptr(tmpReg, tmpReg);
   1.151 -       masm.jcc(Assembler::zero, DONE_LABEL);
   1.152 -
   1.153 -       // If not recursive lock, reset the header to displaced header
   1.154 -       if (os::is_MP()) {
   1.155 -         masm.lock();
   1.156 -       }
   1.157 -       masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
   1.158 -       masm.bind(DONE_LABEL);
   1.159 -       masm.nop(); // avoid branch to branch
   1.160 -    } else {
   1.161 -       Label DONE_LABEL, Stacked, CheckSucc ;
   1.162 -
   1.163 -       if (UseBiasedLocking && !UseOptoBiasInlining) {
   1.164 -         masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
   1.165 -       }
   1.166 -
   1.167 -       masm.movptr(tmpReg, Address(objReg, 0)) ;
   1.168 -       masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
   1.169 -       masm.jcc   (Assembler::zero, DONE_LABEL) ;
   1.170 -       masm.testl (tmpReg, 0x02) ;
   1.171 -       masm.jcc   (Assembler::zero, Stacked) ;
   1.172 -
   1.173 -       // It's inflated
   1.174 -       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
   1.175 -       masm.xorptr(boxReg, r15_thread) ;
   1.176 -       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
   1.177 -       masm.jcc   (Assembler::notZero, DONE_LABEL) ;
   1.178 -       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
   1.179 -       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
   1.180 -       masm.jcc   (Assembler::notZero, CheckSucc) ;
   1.181 -       masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
   1.182 -       masm.jmp   (DONE_LABEL) ;
   1.183 -
   1.184 -       if ((EmitSync & 65536) == 0) {
   1.185 -         Label LSuccess, LGoSlowPath ;
   1.186 -         masm.bind  (CheckSucc) ;
   1.187 -         masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
   1.188 -         masm.jcc   (Assembler::zero, LGoSlowPath) ;
   1.189 -
   1.190 -         // I'd much rather use lock:andl m->_owner, 0 as it's faster than the
   1.191 -         // the explicit ST;MEMBAR combination, but masm doesn't currently support
   1.192 -         // "ANDQ M,IMM".  Don't use MFENCE here.  lock:add to TOS, xchg, etc
   1.193 -         // are all faster when the write buffer is populated.
   1.194 -         masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
   1.195 -         if (os::is_MP()) {
   1.196 -            masm.lock () ; masm.addl (Address(rsp, 0), 0) ;
   1.197 -         }
   1.198 -         masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
   1.199 -         masm.jcc   (Assembler::notZero, LSuccess) ;
   1.200 -
   1.201 -         masm.movptr (boxReg, (int32_t)NULL_WORD) ;                   // box is really EAX
   1.202 -         if (os::is_MP()) { masm.lock(); }
   1.203 -         masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
   1.204 -         masm.jcc   (Assembler::notEqual, LSuccess) ;
   1.205 -         // Intentional fall-through into slow-path
   1.206 -
   1.207 -         masm.bind  (LGoSlowPath) ;
   1.208 -         masm.orl   (boxReg, 1) ;                      // set ICC.ZF=0 to indicate failure
   1.209 -         masm.jmp   (DONE_LABEL) ;
   1.210 -
   1.211 -         masm.bind  (LSuccess) ;
   1.212 -         masm.testl (boxReg, 0) ;                      // set ICC.ZF=1 to indicate success
   1.213 -         masm.jmp   (DONE_LABEL) ;
   1.214 -       }
   1.215 -
   1.216 -       masm.bind  (Stacked) ;
   1.217 -       masm.movptr(tmpReg, Address (boxReg, 0)) ;      // re-fetch
   1.218 -       if (os::is_MP()) { masm.lock(); }
   1.219 -       masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
   1.220 -
   1.221 -       if (EmitSync & 65536) {
   1.222 -          masm.bind (CheckSucc) ;
   1.223 -       }
   1.224 -       masm.bind(DONE_LABEL);
   1.225 -       if (EmitSync & 32768) {
   1.226 -          masm.nop();                      // avoid branch to branch
   1.227 -       }
   1.228 -    }
   1.229 -  %}
   1.230 -
   1.231 -
   1.232    enc_class enc_rethrow()
   1.233    %{
   1.234      cbuf.set_insts_mark();
   1.235 @@ -11443,27 +11218,25 @@
   1.236  // ============================================================================
   1.237  // inlined locking and unlocking
   1.238  
   1.239 -instruct cmpFastLock(rFlagsReg cr,
   1.240 -                     rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr)
   1.241 -%{
   1.242 +instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{
   1.243    match(Set cr (FastLock object box));
   1.244    effect(TEMP tmp, TEMP scr, USE_KILL box);
   1.245 -
   1.246    ins_cost(300);
   1.247    format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
   1.248 -  ins_encode(Fast_Lock(object, box, tmp, scr));
   1.249 +  ins_encode %{
   1.250 +    __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register, _counters);
   1.251 +  %}
   1.252    ins_pipe(pipe_slow);
   1.253  %}
   1.254  
   1.255 -instruct cmpFastUnlock(rFlagsReg cr,
   1.256 -                       rRegP object, rax_RegP box, rRegP tmp)
   1.257 -%{
   1.258 +instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{
   1.259    match(Set cr (FastUnlock object box));
   1.260    effect(TEMP tmp, USE_KILL box);
   1.261 -
   1.262    ins_cost(300);
   1.263    format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
   1.264 -  ins_encode(Fast_Unlock(object, box, tmp));
   1.265 +  ins_encode %{
   1.266 +    __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
   1.267 +  %}
   1.268    ins_pipe(pipe_slow);
   1.269  %}
   1.270  

mercurial