changeset 15231:babe13eb6118

Truffle: Speculate on the exact length of the arguments array.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 18 Apr 2014 14:02:28 +0200
parents df724f63f776
children 7aa0ef5348e5
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java
diffstat 3 files changed, 47 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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()) {
--- 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);
     }
--- 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());
+    }
 }