< prev index next >

src/cpu/aarch64/vm/macroAssembler_aarch64.cpp

Print this page
rev 12202 : AArch64: Add remaining (weak / exchange) CAS-obj intrinsics for Shenandoah.

*** 2195,2244 **** bind(done); BLOCK_COMMENT("} cmpxchg"); } } ! void MacroAssembler::cmpxchg_oop_shenandoah(Register res, Register addr, Register expected, Register new_val, ! bool narrow, bool acquire, bool release, ! Register tmp1, Register tmp2) { assert(UseShenandoahGC, "only for shenandoah"); ! assert_different_registers(res, addr, expected, new_val, tmp1, tmp2); ! Label retry, done, fail; ! mov(res, 0); // CAS, using LL/SC pair. bind(retry); ! load_exclusive(tmp1, addr, narrow ? word : xword, true); ! if (narrow) cmpw(tmp1, expected); ! else cmp(tmp1, expected); br(Assembler::NE, fail); ! store_exclusive(tmp2, new_val, addr, narrow ? word : xword, true); cbnzw(tmp2, retry); ! mov(res, 1); b(done); bind(fail); ! // Check if rb(expected)==rb(tmp1) // Shuffle registers so that we have memory value ready for next expected. mov(tmp2, expected); ! mov(expected, tmp1); ! if (narrow) { ! decode_heap_oop(tmp1, tmp1); decode_heap_oop(tmp2, tmp2); } ! oopDesc::bs()->interpreter_read_barrier(this, tmp1); oopDesc::bs()->interpreter_read_barrier(this, tmp2); ! cmp(tmp1, tmp2); // Retry with expected now being the value we just loaded from addr. br(Assembler::EQ, retry); ! bind(done); - membar(AnyAny); } static bool different(Register a, RegisterOrConstant b, Register c) { if (b.is_constant()) return a != c; --- 2195,2255 ---- bind(done); BLOCK_COMMENT("} cmpxchg"); } } ! void MacroAssembler::cmpxchg_oop_shenandoah(Register addr, Register expected, Register new_val, ! enum operand_size size, bool acquire, bool release, ! bool weak, ! Register res, Register tmp2) { assert(UseShenandoahGC, "only for shenandoah"); ! Register result = res; ! if (result == noreg) result = rscratch1; ! assert_different_registers(addr, expected, new_val, result, tmp2); ! Label retry, done, fail; // CAS, using LL/SC pair. bind(retry); ! load_exclusive(result, addr, size, acquire); ! if (size == xword) { ! cmp(result, expected); ! } else { ! cmpw(result, expected); ! } br(Assembler::NE, fail); ! store_exclusive(tmp2, new_val, addr, size, release); ! if (weak) { ! cmpw(tmp2, 0u); // If the store fails, return NE to our caller ! } else { cbnzw(tmp2, retry); ! } b(done); bind(fail); ! // Check if rb(expected)==rb(result) // Shuffle registers so that we have memory value ready for next expected. mov(tmp2, expected); ! mov(expected, result); ! if (size == word) { ! decode_heap_oop(result, result); decode_heap_oop(tmp2, tmp2); } ! oopDesc::bs()->interpreter_read_barrier(this, result); oopDesc::bs()->interpreter_read_barrier(this, tmp2); ! cmp(result, tmp2); // Retry with expected now being the value we just loaded from addr. br(Assembler::EQ, retry); ! if (size == word && res != noreg) { ! // For cmp-and-exchange and narrow oops, we need to restore ! // the compressed old-value. ! mov(result, expected); ! } bind(done); } static bool different(Register a, RegisterOrConstant b, Register c) { if (b.is_constant()) return a != c;
< prev index next >