-----Original Message-----
From: core-libs-dev [mailto:core-libs-dev-boun...@openjdk.java.net] On
Behalf Of Paul Sandoz
Sent: Thursday, June 23, 2016 9:18 AM
Cc: Java Core Libs <core-libs-dev@openjdk.java.net>
Subject: Re: Question about signature polymorphic, the VM spec of Java 7+,
and VarHandles
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 <uschind...@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
uschind...@apache.org
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/