changeset 21459:f5c2bc68205e

support later folding of constant array reads
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 18 May 2015 14:46:23 -0700
parents 5e84db779bfe
children 877d718f3ab2
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java
diffstat 4 files changed, 54 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Mon May 18 14:44:59 2015 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Mon May 18 14:46:23 2015 -0700
@@ -63,6 +63,14 @@
     JavaConstant readConstantArrayElement(JavaConstant array, int index);
 
     /**
+     * Reads a value from the given array at the given offset if it is a stable array. The offset
+     * will decoded relative to the platform addressing into an index into the array. Returns
+     * {@code null} if the constant is not a stable array, if it is a default value, if the offset
+     * is out of bounds, or if the value is not available at this point.
+     */
+    JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset);
+
+    /**
      * Gets the constant value of this field. Note that a {@code static final} field may not be
      * considered constant if its declaring class is not yet initialized or if it is a well known
      * field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}).
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon May 18 14:44:59 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon May 18 14:46:23 2015 -0700
@@ -96,6 +96,40 @@
         return null;
     }
 
+    /**
+     * Try to convert {@code offset} into an an index into {@code array}.
+     *
+     * @return -1 if the offset isn't within the array or the computed index
+     */
+    private int indexForOffset(JavaConstant array, long offset) {
+        if (array.getKind() != Kind.Object || array.isNull()) {
+            return -1;
+        }
+        Class<?> componentType = ((HotSpotObjectConstantImpl) array).object().getClass().getComponentType();
+        Kind kind = runtime.getHostProviders().getMetaAccess().lookupJavaType(componentType).getKind();
+        int arraybase = runtime.getArrayBaseOffset(kind);
+        int scale = runtime.getArrayIndexScale(kind);
+        if (offset < arraybase) {
+            return -1;
+        }
+        long index = offset - arraybase;
+        if (index % scale != 0) {
+            return -1;
+        }
+        long result = index / scale;
+        if (result >= Integer.MAX_VALUE) {
+            return -1;
+        }
+        return (int) result;
+    }
+
+    public JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset) {
+        if (array instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) array).getStableDimension() > 0) {
+            return readConstantArrayElement(array, indexForOffset(array, offset));
+        }
+        return null;
+    }
+
     @Override
     public JavaConstant readArrayElement(JavaConstant array, int index) {
         if (array.getKind() != Kind.Object || array.isNull()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon May 18 14:44:59 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon May 18 14:46:23 2015 -0700
@@ -105,14 +105,19 @@
     public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) {
         MetaAccessProvider metaAccess = tool.getMetaAccess();
         if (tool.canonicalizeReads()) {
-            if (metaAccess != null && object != null && object.isConstant() && !object.isNullConstant()) {
-                if ((location.getLocationIdentity().isImmutable()) && location instanceof ConstantLocationNode) {
-                    long displacement = ((ConstantLocationNode) location).getDisplacement();
+            if (metaAccess != null && object != null && object.isConstant() && !object.isNullConstant() && location instanceof ConstantLocationNode) {
+                long displacement = ((ConstantLocationNode) location).getDisplacement();
+                if ((location.getLocationIdentity().isImmutable())) {
                     Constant constant = read.stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), object.asConstant(), displacement);
                     if (constant != null) {
                         return ConstantNode.forConstant(read.stamp(), constant, metaAccess);
                     }
                 }
+
+                Constant constant = tool.getConstantReflection().readConstantArrayElementForOffset(object.asJavaConstant(), displacement);
+                if (constant != null) {
+                    return ConstantNode.forConstant(read.stamp(), constant, metaAccess);
+                }
             }
             if (location.getLocationIdentity().equals(LocationIdentity.ARRAY_LENGTH_LOCATION)) {
                 ValueNode length = GraphUtil.arrayLength(object);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java	Mon May 18 14:44:59 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java	Mon May 18 14:46:23 2015 -0700
@@ -52,6 +52,10 @@
         return graalConstantReflection.readConstantArrayElement(array, index);
     }
 
+    public JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset) {
+        return graalConstantReflection.readConstantArrayElementForOffset(array, offset);
+    }
+
     public JavaConstant readConstantFieldValue(JavaField field0, JavaConstant receiver) {
         ResolvedJavaField field = (ResolvedJavaField) field0;
         if (!field.isStatic() && receiver.isNonNull()) {