--- old/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2016-11-16 17:45:43.587799896 +0000 +++ new/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp 2016-11-16 17:45:43.357794866 +0000 @@ -2197,46 +2197,50 @@ } } -void MacroAssembler::cmpxchg_oop_shenandoah(Register res, Register addr, Register expected, +void MacroAssembler::cmpxchg_oop_shenandoah(Register addr, Register expected, Register new_val, - bool narrow, + enum operand_size size, bool acquire, bool release, - Register tmp1, Register tmp2) { + bool weak, + Register result, Register tmp2) { assert(UseShenandoahGC, "only for shenandoah"); - assert_different_registers(res, addr, expected, new_val, tmp1, tmp2); + assert_different_registers(addr, expected, new_val, result, 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); + 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, narrow ? word : xword, true); - cbnzw(tmp2, retry); - mov(res, 1); + 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(tmp1) + // Check if rb(expected)==rb(result) // 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); + mov(expected, result); + if (size == word) { + decode_heap_oop(result, result); decode_heap_oop(tmp2, tmp2); } - oopDesc::bs()->interpreter_read_barrier(this, tmp1); + oopDesc::bs()->interpreter_read_barrier(this, result); oopDesc::bs()->interpreter_read_barrier(this, tmp2); - cmp(tmp1, tmp2); + cmp(result, 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) {