API review of VarHandles
jeremymanson at google.com
Fri Jan 22 18:03:10 UTC 2016
Couple of thoughts:
> The Java Language Specification permits operations to be executed in
> orders different than are apparent in program source code, subject to
> constraints arising, for example, from the use of locks, volatile fields or
> VarHandles. The static methods, fullFence
> , acquireFence
> , releaseFence
> , loadLoadFence
> can also be used to impose constraints. Their specifications are phrased in
> terms of the lack of "reorderings" -- observable ordering effects that
> might otherwise occur if the fence were not present.
There is no notion of reordering (per se) in the JLS; the fact that
reorderings can occur is just implied by the way programs can be observed
to behave. So, these fence operations don't map to anything
non-implementation dependent. I don't think it would be impossible to fix
the spec to define something that works the way you want (similar to the
final field semantics), but it isn't in there already. You might want to
call that out (either by saying this behavior is best effort
implementation-dependent or by fixing the spec).
If a VarHandle references a read-only variable (for example a final field)
> then write, atomic update and numeric atomic update access modes are not
> supported and corresponding methods throw UnsupportedOperationException.
Are you sure you want to limit it in this way? There are an awful lot of
calls to setAccessible in the world of reflection. And writing to final
fields *does* map to something sensible in the spec. In fact, it would be
great to have something that wasn't quite such a blunt instrument as
> public final Object
> ... args)
> Returns the value of a variable, with memory semantics of reading a
> volatile variable.
Reading *which* volatile variable? You probably mean that all getVolatiles
and setVolatiles provide semantics that behave as if the variable being
written / read was declared volatile in the first place, but it is worth
As is usual with virtual methods, source-level calls to access mode methods
> compile to an invokevirtual instruction. More unusually, the compiler
> must record the actual argument types, and may not perform method
> invocation conversions on the arguments. Instead, it must push them on the
> stack according to their own unconverted types. The VarHandle object itself
> is pushed on the stack before the arguments. The compiler then calls the
> VarHandle with a symbolic type descriptor which describes the argument and
> return types.
This is somewhat oddly worded. The compiler doesn't push arguments on a
stack or call anything - it generates instructions that do that.
The first time a invokevirtual instruction is executed it is linked, by
> symbolically resolving the names in the instruction and verifying that the
> method call is statically legal
I keep trying not to call this out as a nit, but there should be no comma
between "linked" and "by".
On Thu, Jan 21, 2016 at 2:42 PM, Paul Sandoz <paul.sandoz at oracle.com> wrote:
> This is a request to review the VarHandles API. The code reviews and
> pushes will occur separately, and flow through the hs-comp repo, most
> likely from the bottom up first with Unsafe changes.
> The specdiff can be found here:
> (Note that specdiff renders some aspects of JavaDoc incorrectly, so just
> ignore any such quirks.)
> A consensus on the set of access mode methods proposed by Doug was
> previously discussed and reached.
> For the moment please ignore the following methods on MethodHandles:
> byteArrayViewVarHandle; and byteBufferViewVarHandle. It is necessary to
> revisit that functionality w.r.t. alignment and proposed enhancements to
> ByteBuffer (in discussion on valhalla-dev).
More information about the valhalla-dev