JEP 193: Enhanced Volatiles
Brian Goetz
brian.goetz at oracle.com
Mon Mar 3 22:25:34 UTC 2014
> Posted: http://openjdk.java.net/jeps/193
Some follow-up thoughts on teasing apart the issues covered by this JEP.
There are three main layers of questions to answer:
1. How do we surface the various pieces of this into the programming
model? This includes language syntax (e.g.,
x.volatile.compareAndSet()), library surface (e.g., the fictitious and
not-terribly-satisfying VolatileInt interface), and relevant
restrictions (e.g., can we do volatile operations on non-volatile fields
or array elements?)
Embedded in this proposal is the desire to not provide a full-blown
"lvalue" form for variables; supporting any form of pass-by-reference at
the language level is a super-non-goal here. But, we have to watch out
for unintended consequences: the VolatileXxx interfaces may end up as a
de facto lvalue construct, and not the ideal one. Along these lines,
the right level at which to exposes these might (or might not) be
FieldHandle, which would be the constrained sibling of MethodHandle.
Relatedly, we need to decide whether to expose fences directly in the
libraries, such as with (intrinsifiable) static methods on a Fences
class; based on discussions in the JMM list, that's probably where we're
heading (and that's fine.)
2. Translation to bytecodes. What bytecode should javac emit when it
encounters an volatile accessor or atomic update? We've identified a
handful of candidates:
2a: new bytecodes. This is the most direct and pure, but most intrusive
(and least extensible), means of delivering on the promise of "it's time
to move this stuff into the programming model proper." The "wide"
bytecode offers a means to express fenced variants of
{get,put}{field,static} with only a single new bytecode, but this
doesn't scale well to CAS (explosion of data types and data locations
(static field, instance field, array element)), which is really the
important case.
2b: new MH types. Just as we have field getter/setter method handles,
we can have fenced getter/setter handles as well as CAS-er handles. Paul
has prototyped something here and demonstrated that its probably viable,
but we have to do some measurement to verify that this is at least
asymptotically competitive with Unsafe. The spec footprint of this
might be broader than we like; a number of new forms of
DirectMethodHandle and corresponding constant pool forms.
One variant of 2b would be to separate fenced access from CAS, and only
require MH support for CAS; translating fenced access would be with a
combination of {put,get}field and calls to Fence methods. This reduces
the VM footprint.
2c: Field handles. This is formalizing the notion of lvalue at the VM
level; define a type FieldHandle which is analogous to MethodHandle,
with signature-polymorphic / intrinsifiable methods for fenced get/put
and CAS. Smaller footprint than 2b; at worst three flavors (static,
instance, and array element). A logical extension of MethodHandle.
2d: Indy+intrinsification. Define a number of indy forms (with
intrinsifiable bootstraps) to describe the various fenced and atomic
operations. Known combinations of (bootstrap, static args) would
effectively be recognized as new bytecodes, since the semantics of the
bootstrap can be known to the VM. Again, can be combined with the
variant above using fence methods, so this might only be needed for CAS,
in which case we need only three forms again: instance field, static
field, array element. Fields could be identified nominally (interpreted
at link time) or by existing CP-able direct method handles for field
accessors (which encapsulates accessibility checking.)
There may be others; this is not an exhaustive list.
3. VM intrusion (including java.lang.invoke footprint). Depending on
the strategy chosen in (2), there are new VM or JSR-292 artifacts needed
to support these forms.
More information about the core-libs-dev
mailing list