Skip to content

Commit 8e87d46

Browse files
committed
8252857: AArch64: Shenandoah C1 CAS is not sequentially consistent
Reviewed-by: rkennke, shade
1 parent c2692f8 commit 8e87d46

File tree

2 files changed

+21
-42
lines changed

2 files changed

+21
-42
lines changed

src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
2+
* Copyright (c) 2018, 2020, Red Hat, Inc. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,16 @@ void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) {
4848
newval = tmp2;
4949
}
5050

51-
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*is_cae*/ false, result);
51+
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), addr, cmpval, newval, /*acquire*/ true, /*release*/ true, /*is_cae*/ false, result);
52+
53+
if (is_c1_or_interpreter_only()) {
54+
// The membar here is necessary to prevent reordering between the
55+
// release store in the CAS above and a subsequent volatile load.
56+
// However for tiered compilation C1 inserts a full barrier before
57+
// volatile loads which means we don't need an additional barrier
58+
// here (see LIRGenerator::volatile_field_load()).
59+
__ membar(__ AnyAny);
60+
}
5261
}
5362

5463
#undef __

src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -459,39 +459,10 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
459459
// from-space, or it refers to the to-space version of an object that
460460
// is being evacuated out of from-space.
461461
//
462-
// By default, this operation implements sequential consistency and the
463-
// value held in the result register following execution of the
464-
// generated code sequence is 0 to indicate failure of CAS, non-zero
465-
// to indicate success. Arguments support variations on this theme:
466-
//
467-
// acquire: Allow relaxation of the memory ordering on CAS from
468-
// sequential consistency. This can be useful when
469-
// sequential consistency is not required, such as when
470-
// another sequentially consistent operation is already
471-
// present in the execution stream. If acquire, successful
472-
// execution has the side effect of assuring that memory
473-
// values updated by other threads and "released" will be
474-
// visible to any read operations perfomed by this thread
475-
// which follow this operation in program order. This is a
476-
// special optimization that should not be enabled by default.
477-
// release: Allow relaxation of the memory ordering on CAS from
478-
// sequential consistency. This can be useful when
479-
// sequential consistency is not required, such as when
480-
// another sequentially consistent operation is already
481-
// present in the execution stream. If release, successful
482-
// completion of this operation has the side effect of
483-
// assuring that all writes to memory performed by this
484-
// thread that precede this operation in program order are
485-
// visible to all other threads that subsequently "acquire"
486-
// before reading the respective memory values. This is a
487-
// special optimization that should not be enabled by default.
488-
// is_cae: This turns CAS (compare and swap) into CAE (compare and
489-
// exchange). This HotSpot convention is that CAE makes
490-
// available to the caller the "failure witness", which is
491-
// the value that was stored in memory which did not match
492-
// the expected value. If is_cae, the result is the value
493-
// most recently fetched from addr rather than a boolean
494-
// success indicator.
462+
// By default the value held in the result register following execution
463+
// of the generated code sequence is 0 to indicate failure of CAS,
464+
// non-zero to indicate success. If is_cae, the result is the value most
465+
// recently fetched from addr rather than a boolean success indicator.
495466
//
496467
// Clobbers rscratch1, rscratch2
497468
void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
@@ -526,11 +497,10 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
526497
__ bind (step4);
527498

528499
// Step 4. CAS has failed because the value most recently fetched
529-
// from addr (which is now held in tmp1) is no longer the from-space
530-
// pointer held in tmp2. If a different thread replaced the
531-
// in-memory value with its equivalent to-space pointer, then CAS
532-
// may still be able to succeed. The value held in the expected
533-
// register has not changed.
500+
// from addr is no longer the from-space pointer held in tmp2. If a
501+
// different thread replaced the in-memory value with its equivalent
502+
// to-space pointer, then CAS may still be able to succeed. The
503+
// value held in the expected register has not changed.
534504
//
535505
// It is extremely rare we reach this point. For this reason, the
536506
// implementation opts for smaller rather than potentially faster
@@ -603,8 +573,8 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
603573
// Note that macro implementation of __cmpxchg cannot use same register
604574
// tmp2 for result and expected since it overwrites result before it
605575
// compares result with expected.
606-
__ cmpxchg(addr, tmp2, new_val, size, acquire, release, false, tmp1);
607-
// EQ flag set iff success. tmp2 holds value fetched.
576+
__ cmpxchg(addr, tmp2, new_val, size, acquire, release, false, noreg);
577+
// EQ flag set iff success. tmp2 holds value fetched, tmp1 (rscratch1) clobbered.
608578

609579
// If fetched value did not equal the new expected, this could
610580
// still be a false negative because some other thread may have

0 commit comments

Comments
 (0)