The JSR133 cookbook says that:
StoreStore Barriers The sequence: Store1; StoreStore; Store2 ensures that Store1's data are visible to other processors (i.e., flushed to memory) before the data associated with Store2 and all subsequent store instructions. In general, StoreStore barriers are needed on processors that do not otherwise guarantee strict ordering of flushes from write buffers and/or caches to other processors or main memory.
And, from the cookbook we know that, for a synchronized block, the Java compiler will insert some barriers to prevent possible reordering:
MonitorEnter
[LoadLoad] <==inserted barrier
[LoadStore]<==inserted barrier
...
[LoadStore]<==inserted barrier
[StoreStore]<==inserted barrier
MonitorExit
However, since x86 does not allow reordering of Read-Read,Read-Write and Write-Write. So all the above barriers will be mapped to no-ops.That is equivalent to say that no barriers will be inserted between MonitorEnter and MonitorExit for x86 processors. My confuse is that if we map StoreStore to no-op under x86, then how visibility is guaranteed? To be more detailed, x86 DOES employ store buffer, so to make writes performed in the critical section be visible to other processor(s), we need to flush the store buffer, hence a Write barrier is needed. From the perspective of visibility a should be mapped to sfence/mfence/Lock#? But the cookbook says it should be mapped to no-op from the perspective of reordering prevention. Or, the key point is that visibility guarantee is done by MonitorEnter and MonitorExit itself? If it is the case, I think they might use so-called Read barrier and Write barrier to guarantee visibility, right?