# HG changeset patch # Parent 94a8fbf1b6a391a1d73cd7f0ed4d78882dc8fafa [backport] 8217016: Shenandoah: Streamline generation of CAS barriers Reviewed-by: roland diff -r 94a8fbf1b6a3 src/cpu/aarch64/vm/aarch64.ad --- a/src/cpu/aarch64/vm/aarch64.ad Sun Apr 28 01:42:00 2019 +0200 +++ b/src/cpu/aarch64/vm/aarch64.ad Fri May 10 11:10:04 2019 -0400 @@ -4270,13 +4270,13 @@ %} - enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{ + enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{ MacroAssembler _masm(&cbuf); guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, - Assembler::xword, /*acquire*/ false, /*release*/ true, /*weak*/ false); + /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} // The only difference between aarch64_enc_cmpxchg and @@ -4297,13 +4297,14 @@ Assembler::word, /*acquire*/ true, /*release*/ true); %} - enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{ + enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{ MacroAssembler _masm(&cbuf); guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, - Assembler::xword, /*acquire*/ true, /*release*/ true, /*weak*/ false); + /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, + $res$$Register); %} // auxiliary used for CompareAndSwapX to set result register @@ -9671,11 +9672,9 @@ format %{ "cmpxchg_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" - "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" - %} - - ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp), - aarch64_enc_cset_eq(res)); + %} + + ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res)); ins_pipe(pipe_slow); %} @@ -9709,14 +9708,12 @@ format %{ "cmpxchgw_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" - "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" %} ins_encode %{ Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, Assembler::word, /*acquire*/ false, /*release*/ true, /*weak*/ false); - __ cset($res$$Register, Assembler::EQ); + __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} ins_pipe(pipe_slow); @@ -9791,11 +9788,9 @@ format %{ "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" - "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" - %} - - ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp), - aarch64_enc_cset_eq(res)); + %} + + ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res)); ins_pipe(pipe_slow); %} @@ -9829,14 +9824,12 @@ format %{ "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" - "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" %} ins_encode %{ Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, Assembler::word, /*acquire*/ true, /*release*/ true, /*weak*/ false); - __ cset($res$$Register, Assembler::EQ); + __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} ins_pipe(pipe_slow); diff -r 94a8fbf1b6a3 src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp --- a/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Sun Apr 28 01:42:00 2019 +0200 +++ b/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Fri May 10 11:10:04 2019 -0400 @@ -1662,8 +1662,7 @@ Register t2 = op->tmp2()->as_register(); __ encode_heap_oop(t2, newval); newval = t2; - __ cmpxchg_oop_shenandoah(addr, cmpval, newval, Assembler::word, /*acquire*/ false, /*release*/ true, /*weak*/ false); - __ csetw(res, Assembler::EQ); + __ cmpxchg_oop_shenandoah(addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, res); } else #endif { @@ -1677,8 +1676,7 @@ } else { #if INCLUDE_ALL_GCS if (UseShenandoahGC && ShenandoahCASBarrier) { - __ cmpxchg_oop_shenandoah(addr, cmpval, newval, Assembler::xword, /*acquire*/ false, /*release*/ true, /*weak*/ false); - __ csetw(res, Assembler::EQ); + __ cmpxchg_oop_shenandoah(addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, res); } else #endif { diff -r 94a8fbf1b6a3 src/cpu/aarch64/vm/macroAssembler_aarch64.cpp --- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Sun Apr 28 01:42:00 2019 +0200 +++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Fri May 10 11:10:04 2019 -0400 @@ -2226,19 +2226,15 @@ } } -void MacroAssembler::cmpxchg_oop_shenandoah(Register addr, Register expected, - Register new_val, - enum operand_size size, - bool acquire, bool release, - bool weak, - Register result, Register tmp2) { - assert(UseShenandoahGC, "only for shenandoah"); - bool is_cae = (result != noreg); - bool is_narrow = (size == word); - - if (! is_cae) result = rscratch1; - - assert_different_registers(addr, expected, new_val, result, tmp2); +void MacroAssembler::cmpxchg_oop_shenandoah(Register addr, Register expected, Register new_val, + bool acquire, bool release, bool weak, bool is_cae, + Register result) { + + Register tmp = rscratch2; + bool is_narrow = UseCompressedOops; + Assembler::operand_size size = is_narrow ? Assembler::word : Assembler::xword; + + assert_different_registers(addr, expected, new_val, result, tmp); Label retry, done, fail; @@ -2251,34 +2247,38 @@ cmp(result, expected); } br(Assembler::NE, fail); - store_exclusive(tmp2, new_val, addr, size, release); + store_exclusive(tmp, new_val, addr, size, release); if (weak) { - cmpw(tmp2, 0u); // If the store fails, return NE to our caller + cmpw(tmp, 0u); // If the store fails, return NE to our caller } else { - cbnzw(tmp2, retry); + cbnzw(tmp, retry); } b(done); - bind(fail); + bind(fail); // Check if rb(expected)==rb(result) // Shuffle registers so that we have memory value ready for next expected. - mov(tmp2, expected); + mov(tmp, expected); mov(expected, result); if (is_narrow) { decode_heap_oop(result, result); - decode_heap_oop(tmp2, tmp2); + decode_heap_oop(tmp, tmp); } oopDesc::bs()->interpreter_read_barrier(this, result); - oopDesc::bs()->interpreter_read_barrier(this, tmp2); - cmp(result, tmp2); + oopDesc::bs()->interpreter_read_barrier(this, tmp); + cmp(result, tmp); // Retry with expected now being the value we just loaded from addr. br(Assembler::EQ, retry); - if (is_narrow && is_cae) { + if (is_cae && is_narrow) { // For cmp-and-exchange and narrow oops, we need to restore // the compressed old-value. We moved it to 'expected' a few lines up. mov(result, expected); } bind(done); + + if (!is_cae) { + cset(result, Assembler::EQ); + } } static bool different(Register a, RegisterOrConstant b, Register c) { diff -r 94a8fbf1b6a3 src/cpu/aarch64/vm/macroAssembler_aarch64.hpp --- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Sun Apr 28 01:42:00 2019 +0200 +++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Fri May 10 11:10:04 2019 -0400 @@ -1008,9 +1008,7 @@ Register tmp = rscratch1); void cmpxchg_oop_shenandoah(Register addr, Register expected, Register new_val, - enum operand_size size, - bool acquire, bool release, bool weak, - Register result = noreg, Register tmp2 = rscratch2); + bool acquire, bool release, bool weak, bool is_cae, Register result); // Calls address trampoline_call(Address entry, CodeBuffer *cbuf = NULL);