Question about signature polymorphic, the VM spec of Java 7+, and VarHandles

Paul Sandoz paul.sandoz at oracle.com
Thu Jun 23 07:18:25 UTC 2016


Hi Uwe,

The JL and JVM specifications have yet to be updated to take into account the new sig-poly methods on VarHandle, they will be in due course by Alex.

It’s not clear yet if we can specify this generally or we will have to enumerate on a per-class/method basis. Ideally it should be future proof. The tricky bit is the specification for invokevirtual.

Paul.

> On 16 Jun 2016, at 09:19, Uwe Schindler <uschindler at apache.org> wrote:
> 
> Hi,
> 
> the Java VM spec tells you the following how to "detect" signature polymorphic methods in bytecode:
> 
> ===
> A method is signature polymorphic if and only if all of the following conditions hold :
> - It is declared in the java.lang.invoke.MethodHandle class.
> - It has a single formal parameter of type Object[].
> - It has a return type of Object.
> - It has the ACC_VARARGS and ACC_NATIVE flags set.
> 
> In Java SE 7, the only signature polymorphic methods are the invoke and invokeExact methods of the class java.lang.invoke.MethodHandle.
> 
> The Java Virtual Machine gives special treatment to signature polymorphic methods in the invokevirtual instruction (§invokevirtual), in order to effect invocation of a method handle. A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation (§5.4.3.5), with optional transformations of arguments or return values. These transformations are quite general, and include such patterns as conversion, insertion, deletion, and substitution. See the java.lang.invoke package in the Java SE platform API for more information.
> ===
> 
> Now the question is: In java 9 the MethodHandle class is not the only one, it also added VerHandle to the list of classes that use signature polymorphic!
> 
> Now the problem I have: In the Javadocs it says: "Bytecode generators, including the compiler back end, are required to emit untransformed symbolic type descriptors for these methods. Tools which determine symbolic linkage are required to accept such untransformed descriptors, without reporting linkage errors."
> 
> I am writing a bytecode analysis tool that needs to detect signature polymorphic methods to have a special treatment with them when invoked in bytecode. In my opinion, the above spec is fine for Java 7 and Java 8, but breaks for Java 9, because also VarHandle was added. I think the spec should be a bit more clear how to detect those methods:
> - Add a reflective getter on Method to check if its signature polymorphic
> - Make the annotation in MethodHandle public and document it. Also change the spec to say: All native varargs methods with the *public* annotation on it are signature polymorphic.
> - Change the spec to say: The above described flags and method desriptor are used to detect (no change), but anything below java.lang.invoke is also required. I don't really like that spec, because it may break again in future.
> 
> I don't like the first part of the spec that says: this signature + ACC_VARARGS + ACC_NATIVE. A 3rd party tool could create a method with exactly that signature outside the JDK code, so I have to limit the package name. Or use the annotations! That’s my problem with the spec!
> 
> Whats the plan for the VM spec and "what's" the best way to detect if a method is signature polymorphic - that is also future proof?
> 
> In my code of forbiddenapis, see https://github.com/policeman-tools/forbidden-apis/pull/106, I implemented purely the Java VM 8 spec, just extending the class name matcher to "everything below java.lang.invoke", so it also works for VarHandles. But as said, this does not look like "future-proof".
> 
> Uwe
> 
> -----
> Uwe Schindler
> uschindler at apache.org
> ASF Member, Apache Lucene PMC / Committer
> Bremen, Germany
> http://lucene.apache.org/
> 
> 



More information about the core-libs-dev mailing list