changeset 17073:1d69b5c58bfe

Insert proxies when peeking through proxy for array length
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 09 Sep 2014 11:53:53 +0200
parents e4923262b8c5
children 899dd861f081
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java
diffstat 1 files changed, 29 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Tue Sep 09 11:53:03 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Tue Sep 09 11:53:53 2014 +0200
@@ -64,32 +64,42 @@
     }
 
     /**
+     * Replicate the {@link ValueProxyNode}s from {@code originalValue} onto {@code value}.
+     *
+     * @param originalValue a possibly proxied value
+     * @param value a value needing proxies
+     * @return proxies wrapping {@code value}
+     */
+    private static ValueNode reproxyValue(ValueNode originalValue, ValueNode value) {
+        if (value.isConstant()) {
+            // No proxy needed
+            return value;
+        }
+        if (originalValue instanceof ValueProxyNode) {
+            ValueProxyNode proxy = (ValueProxyNode) originalValue;
+            return ValueProxyNode.create(reproxyValue(proxy.getOriginalNode(), value), proxy.proxyPoint());
+        } else if (originalValue instanceof ValueProxy) {
+            ValueProxy proxy = (ValueProxy) originalValue;
+            return reproxyValue(proxy.getOriginalNode(), value);
+        } else {
+            return value;
+        }
+    }
+
+    /**
      * Gets the length of an array if possible.
      *
      * @return a node representing the length of {@code array} or null if it is not available
      */
     public static ValueNode readArrayLength(ValueNode originalArray, ConstantReflectionProvider constantReflection) {
-        ArrayLengthProvider foundArrayLengthProvider = null;
-        ValueNode result = originalArray;
-        while (true) {
-            if (result instanceof ArrayLengthProvider) {
-                foundArrayLengthProvider = (ArrayLengthProvider) result;
-                break;
-            }
-            if (result instanceof ValueProxy) {
-                result = ((ValueProxy) result).getOriginalNode();
-            } else {
-                break;
+        ValueNode array = GraphUtil.unproxify(originalArray);
+        if (array instanceof ArrayLengthProvider) {
+            ValueNode length = ((ArrayLengthProvider) array).length();
+            if (length != null) {
+                // Ensure that any proxies on the original value end up on the length value
+                return reproxyValue(originalArray, length);
             }
         }
-
-        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()) {