< prev index next >

src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp

Print this page
rev 56437 : 8231583: Shenandoah: Fix register clash in SBSA::resolve_forwarding_pointer() borrowing

@@ -245,36 +245,39 @@
   if(tosca_live) __ pop(rax);
 
   __ bind(done);
 }
 
-void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp) {
+void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst) {
   assert(ShenandoahCASBarrier, "should be enabled");
   Label is_null;
   __ testptr(dst, dst);
   __ jcc(Assembler::zero, is_null);
-  resolve_forward_pointer_not_null(masm, dst, tmp);
+  resolve_forward_pointer_not_null(masm, dst);
   __ bind(is_null);
 }
 
-void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) {
+void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst) {
   assert(ShenandoahCASBarrier || ShenandoahLoadRefBarrier, "should be enabled");
   // The below loads the mark word, checks if the lowest two bits are
   // set, and if so, clear the lowest two bits and copy the result
   // to dst. Otherwise it leaves dst alone.
   // Implementing this is surprisingly awkward. I do it here by:
   // - Inverting the mark word
   // - Test lowest two bits == 0
   // - If so, set the lowest two bits
   // - Invert the result back, and copy to dst
 
-  bool borrow_reg = (tmp == noreg);
-  if (borrow_reg) {
     // No free registers available. Make one useful.
+  Register tmp = rscratch1;
     tmp = LP64_ONLY(rscratch1) NOT_LP64(rdx);
-    __ push(tmp);
+  if (tmp == dst) {
+    tmp = LP64_ONLY(rscratch2) NOT_LP64(rcx);
   }
+  __ push(tmp);
+
+  assert_different_registers(dst, tmp);
 
   Label done;
   __ movptr(tmp, Address(dst, oopDesc::mark_offset_in_bytes()));
   __ notptr(tmp);
   __ testb(tmp, markWord::marked_value);

@@ -282,13 +285,11 @@
   __ orptr(tmp, markWord::marked_value);
   __ notptr(tmp);
   __ mov(dst, tmp);
   __ bind(done);
 
-  if (borrow_reg) {
     __ pop(tmp);
-  }
 }
 
 
 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst) {
   assert(ShenandoahLoadRefBarrier, "Should be enabled");
< prev index next >