# HG changeset patch # User Tom Rodriguez # Date 1431985583 25200 # Node ID f5c2bc68205e91a2eb1ceb71d4c3f1726cfde703 # Parent 5e84db779bfe82dcd7da9199add031e1c49f5b52 support later folding of constant array reads diff -r 5e84db779bfe -r f5c2bc68205e graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java --- 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)}). diff -r 5e84db779bfe -r f5c2bc68205e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- 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()) { diff -r 5e84db779bfe -r f5c2bc68205e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- 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); diff -r 5e84db779bfe -r f5c2bc68205e graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleConstantReflectionProvider.java --- 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()) {