changeset 20089:5ea03a00828a

allow direct call derived from constant MethodHandle if JDK version >= 1.8.0_60
author Doug Simon <doug.simon@oracle.com>
date Mon, 30 Mar 2015 17:49:15 +0200
parents 8529bfcef6f5
children 1048511c6bcc
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java
diffstat 2 files changed, 27 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- 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<ResolvedMethodHandleCallTargetNode> 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<ValueNode> 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;
--- 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