§1. JMM and C2

Volatile writes have release semantics; volatile reads have acquire semantics. Volatile accesses also participate in a total synchronization order consistent with program order. Release/acquire alone is therefore insufficient: a volatile write followed by a volatile read needs StoreLoad ordering.

BarrierSetC2::load_at() and BarrierSetC2::store_at() use C2AccessFence in barrierSetC2.cpp to insert these Ideal nodes for multi-copy-atomic targets (x64, AArch64, and RISC-V):

Access C2 Ideal sequence
Volatile read Load
MemBarAcquire
Volatile write MemBarRelease
Store
MemBarVolatile
Seq-cst CAS MemBarRelease
CAS (LoadStore)
MemBarAcquire

On PPC64, C2 instead uses a leading MemBarVolatile for volatile reads and seq-cst CAS, and omits the trailing one after volatile stores.

These nodes express ordering requirements. Instruction selection can satisfy them with fences, instruction ordering bits, or the target memory model.

§2. RISC-V code generation

Representative 32-bit accesses. Operands and CAS comparison/retry branches are omitted; + separates instructions.

Access RVWMO RVWMO + Zalasr Ztso Ztso + Zalasr
Plain load lw lw lw lw
Plain store sw sw sw sw
Volatile load lw + fence r, rw lw.aq lw lw.aq
Volatile store fence rw, w + sw + fence w, r sw.rl sw + fence w, r sw.rl
Seq-cst CAS (LR/SC) lr.w.aq + sc.w.aqrl lr.w.aq + sc.w.rl lr.w.aq + sc.w.aqrl lr.w.aq + sc.w.rl
Seq-cst CAS (Zacas) amocas.w.aqrl amocas.w.aqrl amocas.w.aqrl amocas.w.aqrl
  • RVWMO needs explicit acquire, release, and StoreLoad fences for ordinary loads/stores used as volatile accesses.
  • Zalasr carries ordering in lw.aq / sw.rl, allowing HotSpot to omit those fences.
  • Ztso makes acquire/release fences unnecessary, but still permits StoreLoad reordering, so fence w, r remains after a volatile store.