< 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,280 **** if(tosca_live) __ pop(rax); __ bind(done); } ! void ShenandoahBarrierSetAssembler::resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp) { assert(ShenandoahCASBarrier, "should be enabled"); Label is_null; __ testptr(dst, dst); __ jcc(Assembler::zero, is_null); ! resolve_forward_pointer_not_null(masm, dst, tmp); __ bind(is_null); } ! void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp) { 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. tmp = LP64_ONLY(rscratch1) NOT_LP64(rdx); ! __ push(tmp); } Label done; __ movptr(tmp, Address(dst, oopDesc::mark_offset_in_bytes())); __ notptr(tmp); __ testb(tmp, markWord::marked_value); --- 245,283 ---- if(tosca_live) __ pop(rax); __ bind(done); } ! 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); __ bind(is_null); } ! 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 // No free registers available. Make one useful. + Register tmp = rscratch1; tmp = LP64_ONLY(rscratch1) NOT_LP64(rdx); ! 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,294 **** __ 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"); --- 285,295 ----
< prev index next >