# HG changeset patch # User Thomas Wuerthinger # Date 1397822548 -7200 # Node ID babe13eb6118bc806657996fe49719a160aef23b # Parent df724f63f77634e8c25df08fd8b7321b146483ab Truffle: Speculate on the exact length of the arguments array. diff -r df724f63f776 -r babe13eb6118 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Apr 18 14:01:59 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Fri Apr 18 14:02:28 2014 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; /** * The {@code ArrayLength} instruction gets the length of an array. @@ -57,18 +58,25 @@ /** * Gets the length of an array if possible. * - * @param graph TODO - * @param array an array - * * @return a node representing the length of {@code array} or null if it is not available */ - public static ValueNode readArrayLength(StructuredGraph graph, ValueNode array, ConstantReflectionProvider constantReflection) { - if (array instanceof ArrayLengthProvider) { - ValueNode length = ((ArrayLengthProvider) array).length(); + public static ValueNode readArrayLength(StructuredGraph graph, ValueNode originalArray, ConstantReflectionProvider constantReflection) { + ArrayLengthProvider foundArrayLengthProvider = null; + ValueNode result = originalArray; + while (result instanceof ValueProxy) { + if (result instanceof ArrayLengthProvider) { + foundArrayLengthProvider = (ArrayLengthProvider) result; + } + result = ((ValueProxy) result).getOriginalNode(); + } + + if (foundArrayLengthProvider != null) { + ValueNode length = foundArrayLengthProvider.length(); if (length != null) { return length; } } + ValueNode array = GraphUtil.unproxify(originalArray); if (constantReflection != null && array.isConstant() && !array.isNullConstant()) { Constant constantValue = array.asConstant(); if (constantValue != null && constantValue.isNonNull()) { diff -r df724f63f776 -r babe13eb6118 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Fri Apr 18 14:01:59 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Fri Apr 18 14:02:28 2014 +0200 @@ -51,6 +51,8 @@ protected final CompilationPolicy compilationPolicy; private OptimizedCallTarget splitSource; private final AtomicInteger callSitesKnown = new AtomicInteger(0); + @CompilationFinal private Class[] profiledArgumentTypes; + @CompilationFinal private Assumption profiledArgumentTypesAssumption; @CompilationFinal private Class profiledReturnType; @CompilationFinal private Assumption profiledReturnTypeAssumption; @@ -83,9 +85,21 @@ } public Object callDirect(Object... args) { + if (profiledArgumentTypesAssumption == null) { + CompilerDirectives.transferToInterpreter(); + profiledArgumentTypesAssumption = Truffle.getRuntime().createAssumption("Profiled Argument Types"); + profiledArgumentTypes = new Class[args.length]; + } else if (profiledArgumentTypes != null) { + if (profiledArgumentTypes.length != args.length) { + CompilerDirectives.transferToInterpreter(); + profiledArgumentTypesAssumption.invalidate(); + profiledArgumentTypes = null; + } + } + Object result = callBoundary(args); Class klass = profiledReturnType; - if (klass != null && profiledReturnTypeAssumption.isValid()) { + if (klass != null && CompilerDirectives.inCompiledCode() && profiledReturnTypeAssumption.isValid()) { result = CompilerDirectives.unsafeCast(result, klass, true, true); } return result; @@ -247,7 +261,13 @@ } } - public final Object callRoot(Object[] args) { + public final Object callRoot(Object[] originalArguments) { + + Object[] args = originalArguments; + if (this.profiledArgumentTypesAssumption != null && CompilerDirectives.inCompiledCode() && profiledArgumentTypesAssumption.isValid()) { + args = CompilerDirectives.unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true); + } + VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args); Object result = callProxy(frame); @@ -269,6 +289,10 @@ return result; } + private static Object castArrayFixedLength(Object[] args, @SuppressWarnings("unused") int length) { + return args; + } + public static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, Object[] args) { return new FrameWithoutBoxing(descriptor, args); } diff -r df724f63f776 -r babe13eb6118 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Fri Apr 18 14:01:59 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Fri Apr 18 14:02:28 2014 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.substitutions; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.truffle.api.frame.*; @@ -34,4 +36,9 @@ private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, Object[] args) { return NewFrameNode.allocate(FrameWithoutBoxing.class, descriptor, args); } + + @MethodSubstitution + private static Object castArrayFixedLength(Object[] args, int length) { + return PiArrayNode.piArrayCast(args, length, StampFactory.forNodeIntrinsic()); + } }