# HG changeset patch # User Lukas Stadler # Date 1346148910 -7200 # Node ID 01d27450356214b4000cfed6a114688a0b127de7 # Parent 72eb3a1a20c4a422fab9a09abaf5031735d25632 canonicalize reads and writes on null objects to deopts diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Aug 28 12:15:10 2012 +0200 @@ -152,7 +152,7 @@ if (state instanceof MaterializedObjectState) { return toValue(((MaterializedObjectState) state).materializedValue()); } else { - assert state instanceof VirtualObjectState; + assert obj.fieldsCount() == 0 || state instanceof VirtualObjectState; VirtualObject ciObj = virtualObjects.get(value); if (ciObj == null) { ciObj = VirtualObject.get(obj.type(), null, virtualObjects.size()); diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Tue Aug 28 12:15:10 2012 +0200 @@ -180,6 +180,7 @@ public static boolean tryCanonicalize(final Node node, final StructuredGraph graph, final SimplifierTool tool) { if (node instanceof Canonicalizable) { + assert !(node instanceof Simplifiable); METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); return Debug.scope("CanonicalizeNode", node, new Callable(){ public Boolean call() { diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Tue Aug 28 12:15:10 2012 +0200 @@ -53,6 +53,11 @@ @Override public boolean inferStamp() { + if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) { + // a null value flowing into a nonNull PiNode can happen should be guarded by a type/isNull guard, but the + // compiler might see this situation before the branch is deleted + return false; + } return updateStamp(stamp().join(object().stamp())); } } diff -r 72eb3a1a20c4 -r 01d274503562 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 Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Aug 28 12:15:10 2012 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -31,7 +32,7 @@ /** * Reads an {@linkplain AccessNode accessed} value. */ -public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable/*, Canonicalizable*/ { +public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Simplifiable/*, Canonicalizable*/ { public ReadNode(ValueNode object, LocationNode location, Stamp stamp) { super(object, location, stamp); @@ -42,7 +43,7 @@ gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck())); } - // Canonicalization disabled untill we have a solution for non-Object oops in Hotspot + // Canonicalization disabled until we have a solution for non-Object oops in Hotspot /*@Override public ValueNode canonical(CanonicalizerTool tool) { return canonicalizeRead(this, tool); @@ -64,4 +65,16 @@ } return (ValueNode) read; } + + @Override + public void simplify(SimplifierTool tool) { + if (object().isConstant() && object().asConstant().isNull()) { + FixedNode successor = next(); + tool.deleteBranch(successor); + if (isAlive()) { + replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException))); + safeDelete(); + } + } + } } diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Aug 28 12:15:10 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -30,7 +32,7 @@ /** * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}. */ -public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable { +public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, Simplifiable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; @@ -61,4 +63,16 @@ public void generate(LIRGeneratorTool gen) { gen.emitStore(gen.makeAddress(location(), object()), gen.operand(value()), getNullCheck()); } + + @Override + public void simplify(SimplifierTool tool) { + if (object().isConstant() && object().asConstant().isNull()) { + FixedNode successor = next(); + tool.deleteBranch(successor); + if (isAlive()) { + replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException))); + safeDelete(); + } + } + } } diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Tue Aug 28 12:15:10 2012 +0200 @@ -24,13 +24,14 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** * The {@code AccessIndexedNode} class is the base class of instructions that read or write * elements of an array. */ -public abstract class AccessIndexedNode extends AccessArrayNode { +public abstract class AccessIndexedNode extends AccessArrayNode implements Lowerable { @Input private ValueNode index; private final Kind elementType; @@ -65,4 +66,9 @@ public long leafGraphId() { return leafGraphId; } + + @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } } diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Tue Aug 28 12:15:10 2012 +0200 @@ -33,7 +33,7 @@ /** * The {@code LoadIndexedNode} represents a read from an element of an array. */ -public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Lowerable, Node.IterableNodeType { +public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Node.IterableNodeType { /** * Creates a new LoadIndexedNode. @@ -54,11 +54,6 @@ } @Override - public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); - } - - @Override public ValueNode canonical(CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); if (runtime != null && index().isConstant() && array().isConstant() && !array().isNullConstant()) { diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MaterializeObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MaterializeObjectNode.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MaterializeObjectNode.java Tue Aug 28 12:15:10 2012 +0200 @@ -25,7 +25,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; diff -r 72eb3a1a20c4 -r 01d274503562 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Aug 28 11:27:39 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Aug 28 12:15:10 2012 +0200 @@ -64,9 +64,4 @@ super(StampFactory.forVoid(), array, index, elementKind, leafGraphId); this.value = value; } - - @Override - public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); - } }