Summary

Add three memory-ordering intrinsics to the sun.misc.Unsafe class.

Motivation

JVMs don't have advertised mechanisms providing memory orderings that
were not envisioned originally or in the JSR 133 memory model specs.
(But are present for example in the recent C11/C++11 specs.) These
include several constructions used in java.util.concurrent and other
low-level libraries that currently rely on undocumented (and possibly
transient) properties of existing intrinsics.

Adding these methods at the VM level permits use by JDK libraries in
support of JDK 8 features, while also opening up the possibility of
later exporting the base functionality via new java.util.concurrent
APIs. This may become essential to allow people developing non-JDK
low-level libraries if upcoming modularity support makes these methods
impossible for others to access.

Description

The three methods provide the three different kinds of memory fences
that some compilers and processors need to ensure that particular
accesses (loads and stores) do not become reordered. In practice, they
are identical in effect to existing getXXXVolatile, putXXXVolatile, and
putOrderedXXX methods, except that they do not actually perform an
access; they just ensure the ordering. However, they conceptually
differ in one way: According to the current JMM, some language-level
uses of volatile may be reordered with some uses of non-volatile
variables. But this would not be allowed here. (It is not allowed in
the current intrinsics either, but this is an undocumented difference
between intrinsics-based vs language-based volatile access.)

The three methods are:

/**
* Ensures lack of reordering of loads before the fence
* with loads or stores after the fence.
*/
void loadFence();
/**
* Ensures lack of reordering of stores before the fence
* with loads or stores after the fence.
*/
void storeFence();
/**
* Ensures lack of reordering of loads or stores before the fence
* with loads or stores after the fence.
*/
void fullFence();

While there is nothing at all "unsafe" about the three methods, by
convention, Unsafe currently houses related methods for per-use
volatile and atomic operations, so seems to be the best home for these
methods.

The javadoc could be made more rigorous, although cannot be specified
in terms of the JMM because it doesn't cover "per-use volatileness".
So, leaving them in this simple form probably best conveys intent to
target users. Also, it is probably impossible (because of likely
existing usage dependencies) to at the same time make explicit and
slightly weaken the minimally required reordering properties of
existing volatile access intrinsics. However, the presence of fence
intrinsics allows users to unambiguously obtain these effects when
needed.

Hotspot Implementation

The three methods can be implemented in terms of the existing acquire,
release, and volatile fence methods available across c1, c2, and the
interpreter/runtime, plus, when applicable, suppressing internal compiler
reorderings and value reuse. This requires no new underlying
capabailities, but still requires adding to and adapting the code strewn
across Hotspot necessary for new intrinsics. Omitting these, here is an
implementation sketch:

For c2, implementation amounts to methods that omit all the access code
in methods like inline_unsafe_access, leaving only generation of the
memory-based fences, plus an internal CPUOrder fence that disables
reorderings during optimization. (In the case of fullFence, also
cautiously including an acquire fence along with the full volatile
fence, to cover the possibility that existing c2 code relies on the
presence of MemBarAcquire to detect volatile-ness with respect to
loads.)