public class IntrinsifyMethodHandlesInvocationPlugin extends Object implements org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin
Design decisions for this phase: So support static analysis, the method handle invocation needs to be replaced with a regular invocation before static analysis runs. This requires inlining of all method that are involved in the method handle dispatch. We introduce the restriction that one method handle invocation can be reduced by exactly one regular invocation, so that we can inherit the bci of that invocation, and there are no nested frame states created for the inlining. The static analysis results are therefore registered using this bci, and the bci is still unique and belongs to the original method.
Implementation: The starting point is an invoke that has a Constant
MethodHandle
as an argument. The method handle is the appendix of the invokedynamic bytecode generated by
javac for lambda expressions. We inline recursively all methods that get the method handle
parameter, with special treatment of the invocation methods of the method handle chain provided
by MethodHandleAccessProvider
. After all inlining (which is done during parsing,
configured by the MethodHandlesInlineInvokePlugin
), we require to have just a single
invocation left. This invocation replaces the original invoke that was our starting point. If we
have more than a single invocation left, we fail and report it as an unsupported feature of
Substrate VM.
The parsing is done using the original universe and providers of the HotSpot VM. This has a
couple of advantages: Our analysis universe is not polluted with types and methods just used for
method handles; we can use the constant folding and graph builder plugins of the HotSpot VM; and
we can use the MethodHandlePlugin
of the HotSpot VM without the need for any wrappers.
The downside is that we have to convert types, methods, and constants between our world and the
HotSpot world.
Constructor and Description |
---|
IntrinsifyMethodHandlesInvocationPlugin(org.graalvm.compiler.phases.util.Providers providers,
com.oracle.graal.pointsto.meta.AnalysisUniverse aUniverse,
HostedUniverse hUniverse) |
Modifier and Type | Method and Description |
---|---|
boolean |
handleInvoke(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext b,
jdk.vm.ci.meta.ResolvedJavaMethod method,
org.graalvm.compiler.nodes.ValueNode[] args) |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
canChangeStackKind, handleCheckCast, handleInstanceOf, handleLoadField, handleLoadIndexed, handleLoadStaticField, handleNewArray, handleNewInstance, handleNewMultiArray, handleStoreField, handleStoreIndexed, handleStoreStaticField, instrumentExceptionDispatch
public IntrinsifyMethodHandlesInvocationPlugin(org.graalvm.compiler.phases.util.Providers providers, com.oracle.graal.pointsto.meta.AnalysisUniverse aUniverse, HostedUniverse hUniverse)
public boolean handleInvoke(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext b, jdk.vm.ci.meta.ResolvedJavaMethod method, org.graalvm.compiler.nodes.ValueNode[] args)
handleInvoke
in interface org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin