590 // Special Shenandoah CAS implementation that handles false negatives |
590 // Special Shenandoah CAS implementation that handles false negatives |
591 // due to concurrent evacuation. |
591 // due to concurrent evacuation. |
592 #ifndef _LP64 |
592 #ifndef _LP64 |
593 void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, |
593 void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, |
594 Register res, Address addr, Register oldval, Register newval, |
594 Register res, Address addr, Register oldval, Register newval, |
595 bool exchange, bool encode, Register tmp1, Register tmp2) { |
595 bool exchange, Register tmp1, Register tmp2) { |
596 // Shenandoah has no 32-bit version for this. |
596 // Shenandoah has no 32-bit version for this. |
597 Unimplemented(); |
597 Unimplemented(); |
598 } |
598 } |
599 #else |
599 #else |
600 void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, |
600 void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, |
601 Register res, Address addr, Register oldval, Register newval, |
601 Register res, Address addr, Register oldval, Register newval, |
602 bool exchange, bool encode, Register tmp1, Register tmp2) { |
602 bool exchange, Register tmp1, Register tmp2) { |
603 if (!ShenandoahCASBarrier) { |
|
604 #ifdef _LP64 |
|
605 if (UseCompressedOops) { |
|
606 if (encode) { |
|
607 __ encode_heap_oop(oldval); |
|
608 __ mov(rscratch1, newval); |
|
609 __ encode_heap_oop(rscratch1); |
|
610 newval = rscratch1; |
|
611 } |
|
612 if (os::is_MP()) { |
|
613 __ lock(); |
|
614 } |
|
615 // oldval (rax) is implicitly used by this instruction |
|
616 __ cmpxchgl(newval, addr); |
|
617 } else |
|
618 #endif |
|
619 { |
|
620 if (os::is_MP()) { |
|
621 __ lock(); |
|
622 } |
|
623 __ cmpxchgptr(newval, addr); |
|
624 } |
|
625 |
|
626 if (!exchange) { |
|
627 assert(res != NULL, "need result register"); |
|
628 __ setb(Assembler::equal, res); |
|
629 __ movzbl(res, res); |
|
630 } |
|
631 return; |
|
632 } |
|
633 |
|
634 assert(ShenandoahCASBarrier, "Should only be used when CAS barrier is enabled"); |
603 assert(ShenandoahCASBarrier, "Should only be used when CAS barrier is enabled"); |
635 assert(oldval == rax, "must be in rax for implicit use in cmpxchg"); |
604 assert(oldval == rax, "must be in rax for implicit use in cmpxchg"); |
636 |
605 |
637 Label retry, done; |
606 Label retry, done; |
638 |
|
639 // Apply storeval barrier to newval. |
|
640 if (encode) { |
|
641 storeval_barrier(masm, newval, tmp1); |
|
642 } |
|
643 |
|
644 if (UseCompressedOops) { |
|
645 if (encode) { |
|
646 __ encode_heap_oop(oldval); |
|
647 __ mov(rscratch1, newval); |
|
648 __ encode_heap_oop(rscratch1); |
|
649 newval = rscratch1; |
|
650 } |
|
651 } |
|
652 |
607 |
653 // Remember oldval for retry logic below |
608 // Remember oldval for retry logic below |
654 if (UseCompressedOops) { |
609 if (UseCompressedOops) { |
655 __ movl(tmp1, oldval); |
610 __ movl(tmp1, oldval); |
656 } else { |
611 } else { |