# HG changeset patch # User Doug Simon # Date 1427730555 -7200 # Node ID 5ea03a00828af2b49f5d2a6dd4b010b04099a7eb # Parent 8529bfcef6f5c8c72dd04650b4307d0196d8a8b4 allow direct call derived from constant MethodHandle if JDK version >= 1.8.0_60 diff -r 8529bfcef6f5 -r 5ea03a00828a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java Mon Mar 30 16:51:26 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java Mon Mar 30 17:49:15 2015 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.nodes; +import static sun.misc.Version.*; + import java.lang.invoke.*; import com.oracle.graal.api.meta.*; @@ -35,24 +37,39 @@ /** * A call target that replaces itself in the graph when being lowered by restoring the original - * {@link MethodHandle} invocation target. This is required for when a {@link MethodHandle} call was - * resolved to a constant target but the target was not inlined. In that case, the original - * invocation must be restored with all of its original arguments. Why? HotSpot linkage for - * {@link MethodHandle} intrinsics (see {@code MethodHandles::generate_method_handle_dispatch}) - * expects certain implicit arguments to be on the stack such as the MemberName suffix argument for - * a call to one of the MethodHandle.linkTo* methods. An - * {@linkplain MethodHandleNode#tryResolveTargetInvoke resolved} {@link MethodHandle} invocation - * drops these arguments which means the interpreter won't find them. + * {@link MethodHandle} invocation target. Prior to + * https://bugs.openjdk.java.net/browse/JDK-8072008, this is required for when a + * {@link MethodHandle} call is resolved to a constant target but the target was not inlined. In + * that case, the original invocation must be restored with all of its original arguments. Why? + * HotSpot linkage for {@link MethodHandle} intrinsics (see + * {@code MethodHandles::generate_method_handle_dispatch}) expects certain implicit arguments to be + * on the stack such as the MemberName suffix argument for a call to one of the MethodHandle.linkTo* + * methods. An {@linkplain MethodHandleNode#tryResolveTargetInvoke resolved} {@link MethodHandle} + * invocation drops these arguments which means the interpreter won't find them. */ @NodeInfo public final class ResolvedMethodHandleCallTargetNode extends MethodCallTargetNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(ResolvedMethodHandleCallTargetNode.class); + + /** + * Creates a call target for an invocation on a direct target derived by resolving a constant + * {@link MethodHandle}. + */ + public static MethodCallTargetNode create(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod, + ValueNode[] originalArguments, JavaType originalReturnType) { + if (jdkMajorVersion() >= 1 && jdkMinorVersion() >= 8 && jdkMicroVersion() >= 0 && jdkUpdateVersion() >= 60) { + // https://bugs.openjdk.java.net/browse/JDK-8072008 is targeted for 8u60 + return new MethodCallTargetNode(invokeKind, targetMethod, arguments, returnType); + } + return new ResolvedMethodHandleCallTargetNode(invokeKind, targetMethod, arguments, returnType, originalTargetMethod, originalArguments, originalReturnType); + } + protected final ResolvedJavaMethod originalTargetMethod; protected final JavaType originalReturnType; @Input NodeInputList originalArguments; - public ResolvedMethodHandleCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod, + protected ResolvedMethodHandleCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod, ValueNode[] originalArguments, JavaType originalReturnType) { super(TYPE, invokeKind, targetMethod, arguments, returnType); this.originalTargetMethod = originalTargetMethod; diff -r 8529bfcef6f5 -r 5ea03a00828a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Mon Mar 30 16:51:26 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Mon Mar 30 17:49:15 2015 +0200 @@ -256,7 +256,7 @@ throw GraalInternalError.shouldNotReachHere(); } - MethodCallTargetNode callTarget = new ResolvedMethodHandleCallTargetNode(targetInvokeKind, target, targetArguments, targetReturnType, original, arguments, returnType); + MethodCallTargetNode callTarget = ResolvedMethodHandleCallTargetNode.create(targetInvokeKind, target, targetArguments, targetReturnType, original, arguments, returnType); // The call target can have a different return type than the invoker, // e.g. the target returns an Object but the invoker void. In this case