Mercurial > hg > graal-jvmci-8
changeset 20082: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