# HG changeset patch # User Doug Simon # Date 1380228325 -7200 # Node ID 43bc62c78f776bb4dd7e1123a53c66eea4ca7c5d # Parent 22d47c2c74e99e1b7d80bf958aa3f306f6c58cdd attempt to canonicalize array length access when lowering array load|store operations diff -r 22d47c2c74e9 -r 43bc62c78f77 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Thu Sep 26 16:46:27 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Thu Sep 26 22:45:25 2013 +0200 @@ -447,7 +447,7 @@ @Test public void testLoop4() { SchedulePhase schedule = getFinalSchedule("testLoop4Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL); - assertReadWithinStartBlock(schedule, true); + assertReadWithinStartBlock(schedule, false); assertReadWithinReturnBlock(schedule, false); } diff -r 22d47c2c74e9 -r 43bc62c78f77 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Sep 26 16:46:27 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Sep 26 22:45:25 2013 +0200 @@ -49,6 +49,7 @@ import static com.oracle.graal.hotspot.stubs.StubUtil.*; import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; +import static com.oracle.graal.nodes.java.ArrayLengthNode.*; import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; import static com.oracle.graal.phases.GraalOptions.*; import static com.oracle.graal.replacements.Log.*; @@ -994,10 +995,15 @@ private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { StructuredGraph g = n.graph(); ValueNode array = n.array(); - Stamp stamp = StampFactory.positiveInt(); - ReadNode arrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, g), stamp, BarrierType.NONE, false)); - g.addBeforeFixed(n, arrayLength); - tool.createNullCheckGuard(arrayLength, array); + ValueNode arrayLength = readArrayLength(array, tool.getRuntime()); + if (arrayLength == null) { + Stamp stamp = StampFactory.positiveInt(); + ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, g), stamp, BarrierType.NONE, false)); + g.addBeforeFixed(n, readArrayLength); + tool.createNullCheckGuard(readArrayLength, array); + arrayLength = readArrayLength; + } + return tool.createGuard(g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile); } diff -r 22d47c2c74e9 -r 43bc62c78f77 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 Thu Sep 26 16:46:27 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Thu Sep 26 22:45:25 2013 +0200 @@ -45,23 +45,36 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - if (array() instanceof ArrayLengthProvider) { - ValueNode length = ((ArrayLengthProvider) array()).length(); + ValueNode length = readArrayLength(array(), tool.runtime()); + if (length != null) { + return length; + } + return this; + } + + /** + * Gets the length of an array if possible. + * + * @param array an array + * @return a node representing the length of {@code array} or null if it is not available + */ + public static ValueNode readArrayLength(ValueNode array, MetaAccessProvider runtime) { + if (array instanceof ArrayLengthProvider) { + ValueNode length = ((ArrayLengthProvider) array).length(); if (length != null) { return length; } } - MetaAccessProvider runtime = tool.runtime(); - if (runtime != null && array().isConstant() && !array().isNullConstant()) { - Constant constantValue = array().asConstant(); + if (runtime != null && array.isConstant() && !array.isNullConstant()) { + Constant constantValue = array.asConstant(); if (constantValue != null && constantValue.isNonNull()) { Integer constantLength = runtime.lookupArrayLength(constantValue); if (constantLength != null) { - return ConstantNode.forInt(constantLength, graph()); + return ConstantNode.forInt(constantLength, array.graph()); } } } - return this; + return null; } @Override