# HG changeset patch # User aph # Date 1441717738 -3600 # Node ID 3b837e8988b595c80407dcf580b4932804139c39 # Parent 2115e6f0cbee935f1a36db94c49a1f360f45f97f 8135157: DMB elimination in AArch64 C2 synchronization implementation Summary: Reduce memory barrier usage in C2 fast lock and unlock. Reviewed-by: kvn Contributed-by: wei.tang@linaro.org, aph@redhat.com diff -r 2115e6f0cbee -r 3b837e8988b5 src/cpu/aarch64/vm/aarch64.ad --- a/src/cpu/aarch64/vm/aarch64.ad Tue Nov 03 10:39:54 2015 +0000 +++ b/src/cpu/aarch64/vm/aarch64.ad Tue Sep 08 14:08:58 2015 +0100 @@ -4845,13 +4845,10 @@ // Compare object markOop with mark and if equal exchange scratch1 // with object markOop. - // Note that this is simply a CAS: it does not generate any - // barriers. These are separately generated by - // membar_acquire_lock(). { Label retry_load; __ bind(retry_load); - __ ldxr(tmp, oop); + __ ldaxr(tmp, oop); __ cmp(tmp, disp_hdr); __ br(Assembler::NE, cas_failed); // use stlxr to ensure update is immediately visible @@ -4901,7 +4898,7 @@ { Label retry_load, fail; __ bind(retry_load); - __ ldxr(rscratch1, tmp); + __ ldaxr(rscratch1, tmp); __ cmp(disp_hdr, rscratch1); __ br(Assembler::NE, fail); // use stlxr to ensure update is immediately visible @@ -8533,10 +8530,10 @@ match(MemBarAcquireLock); ins_cost(VOLATILE_REF_COST); - format %{ "membar_acquire_lock" %} - - ins_encode %{ - __ membar(Assembler::LoadLoad|Assembler::LoadStore); + format %{ "membar_acquire_lock (elided)" %} + + ins_encode %{ + __ block_comment("membar_acquire_lock (elided)"); %} ins_pipe(pipe_serial); @@ -8596,10 +8593,10 @@ match(MemBarReleaseLock); ins_cost(VOLATILE_REF_COST); - format %{ "membar_release_lock" %} - - ins_encode %{ - __ membar(Assembler::LoadStore|Assembler::StoreStore); + format %{ "membar_release_lock (elided)" %} + + ins_encode %{ + __ block_comment("membar_release_lock (elided)"); %} ins_pipe(pipe_serial); @@ -8885,7 +8882,11 @@ ins_pipe(pipe_serial); %} -// this has to be implemented as a CAS + +// storeLConditional is used by PhaseMacroExpand::expand_lock_node +// when attempting to rebias a lock towards the current thread. We +// must use the acquire form of cmpxchg in order to guarantee acquire +// semantics in this case. instruct storeLConditional(indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{ match(Set cr (StoreLConditional mem (Binary oldval newval))); @@ -8897,12 +8898,14 @@ "cmpw rscratch1, zr\t# EQ on successful write" %} - ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval)); + ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval)); ins_pipe(pipe_slow); %} -// this has to be implemented as a CAS +// storeIConditional also has acquire semantics, for no better reason +// than matching storeLConditional. At the time of writing this +// comment storeIConditional was not used anywhere by AArch64. instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{ match(Set cr (StoreIConditional mem (Binary oldval newval))); @@ -8914,7 +8917,7 @@ "cmpw rscratch1, zr\t# EQ on successful write" %} - ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval)); + ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval)); ins_pipe(pipe_slow); %}