# HG changeset patch # User Roland Schatz # Date 1395770014 -3600 # Node ID 6ae9af961b7c32141688f7a9a01ecd274cefb5ac # Parent b10e42998d01b9a97c7c975e02c2b940ae41be4f Introduce separate interfaces for deoptimizing nodes that deopt to a state before, during or after their execution. diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Mar 25 18:53:34 2014 +0100 @@ -368,18 +368,29 @@ return false; } + private static FrameState getFrameState(DeoptimizingNode deopt) { + if (deopt instanceof DeoptimizingNode.DeoptBefore) { + return ((DeoptimizingNode.DeoptBefore) deopt).stateBefore(); + } else if (deopt instanceof DeoptimizingNode.DeoptDuring) { + return ((DeoptimizingNode.DeoptDuring) deopt).stateDuring(); + } else { + assert deopt instanceof DeoptimizingNode.DeoptAfter; + return ((DeoptimizingNode.DeoptAfter) deopt).stateAfter(); + } + } + public LIRFrameState state(DeoptimizingNode deopt) { if (!deopt.canDeoptimize()) { return null; } - return stateFor(deopt.getDeoptimizationState()); + return stateFor(getFrameState(deopt)); } public LIRFrameState stateWithExceptionEdge(DeoptimizingNode deopt, LabelRef exceptionEdge) { if (!deopt.canDeoptimize()) { return null; } - return stateForWithExceptionEdge(deopt.getDeoptimizationState(), exceptionEdge); + return stateForWithExceptionEdge(getFrameState(deopt), exceptionEdge); } public LIRFrameState stateFor(FrameState state) { @@ -910,7 +921,7 @@ LIRFrameState state = null; if (linkage.canDeoptimize()) { if (info != null) { - state = stateFor(info.getDeoptimizationState()); + state = stateFor(getFrameState(info)); } else { assert needOnlyOopMaps(); state = new LIRFrameState(null, null, null); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Tue Mar 25 18:53:34 2014 +0100 @@ -250,7 +250,7 @@ ValueNode[] launchArgsArray = args.values().toArray(new ValueNode[args.size()]); ForeignCallNode result = append(new ForeignCallNode(providers.getForeignCalls(), CALL_KERNEL, launchArgsArray)); - result.setDeoptimizationState(fs); + result.setStateAfter(fs); InvokeNode getObjectResult = null; ValueNode returnValue; diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Tue Mar 25 18:53:34 2014 +0100 @@ -25,7 +25,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -public class G1PreWriteBarrier extends WriteBarrier implements DeoptimizingNode { +public class G1PreWriteBarrier extends WriteBarrier implements DeoptimizingNode.DeoptBefore { @Input private FrameState deoptimizationState; private final boolean nullCheck; @@ -55,17 +55,13 @@ } @Override - public FrameState getDeoptimizationState() { + public FrameState stateBefore() { return deoptimizationState; } @Override - public void setDeoptimizationState(FrameState state) { + public void setStateBefore(FrameState state) { updateUsages(deoptimizationState, state); deoptimizationState = state; } - - public FrameState getState() { - return deoptimizationState; - } } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -52,10 +52,10 @@ @Override public void generate(LIRGenerator gen) { String whereString; - if (getState() != null) { + if (stateBefore() != null) { String nl = CodeUtil.NEW_LINE; StringBuilder sb = new StringBuilder("in compiled code associated with frame state:"); - FrameState fs = getState(); + FrameState fs = stateBefore(); while (fs != null) { MetaUtil.appendLocation(sb.append(nl).append("\t"), fs.method(), fs.bci); fs = fs.outerFrameState(); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Tue Mar 25 18:53:34 2014 +0100 @@ -68,9 +68,9 @@ protected static void addG1PreWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean doLoad, boolean nullCheck, StructuredGraph graph) { G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(object, value, location, doLoad, nullCheck)); - preBarrier.setDeoptimizationState(node.getDeoptimizationState()); + preBarrier.setStateBefore(node.stateBefore()); node.setNullCheck(false); - node.setDeoptimizationState(null); + node.setStateBefore(null); graph.addBeforeFixed(node, preBarrier); } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -30,11 +30,9 @@ * This node represents an unconditional explicit request for immediate deoptimization. * * After this node, execution will continue using a fallback execution engine (such as an - * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization - * state}. - * + * interpreter) at the position described by the {@link #stateBefore() deoptimization state}. */ -public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode { +public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode.DeoptBefore { @Input private FrameState deoptState; @@ -48,20 +46,16 @@ } @Override - public FrameState getDeoptimizationState() { + public FrameState stateBefore() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { + public void setStateBefore(FrameState f) { updateUsages(deoptState, f); deoptState = f; } - public FrameState getState() { - return deoptState; - } - public abstract ValueNode getActionAndReason(MetaAccessProvider metaAccess); public abstract ValueNode getSpeculation(MetaAccessProvider metaAccess); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -86,7 +86,7 @@ FixedNode next = next(); setNext(null); DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason)); - deopt.setDeoptimizationState(getDeoptimizationState()); + deopt.setStateBefore(stateBefore()); IfNode ifNode; AbstractBeginNode noDeoptSuccessor; if (negated) { diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Tue Mar 25 18:53:34 2014 +0100 @@ -41,10 +41,6 @@ stateAfter = x; } - public FrameState getState() { - return stateAfter(); - } - public boolean hasSideEffect() { return true; } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -24,7 +24,7 @@ import com.oracle.graal.nodes.type.*; -public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode { +public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode.DeoptBefore { @Input(notDataflow = true) private FrameState deoptState; @@ -33,17 +33,13 @@ } @Override - public FrameState getDeoptimizationState() { + public FrameState stateBefore() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { + public void setStateBefore(FrameState f) { updateUsages(deoptState, f); deoptState = f; } - - public FrameState getState() { - return deoptState; - } } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -35,14 +35,46 @@ boolean canDeoptimize(); /** - * Gets the deoptimization information associated with this node if any. + * Interface for nodes that need a {@link FrameState} for deoptimizing to a point before their + * execution. */ - FrameState getDeoptimizationState(); + public interface DeoptBefore extends DeoptimizingNode { + + /** + * Sets the {@link FrameState} describing the program state before the execution of this + * node. + */ + void setStateBefore(FrameState state); + + FrameState stateBefore(); + } + + /** + * Interface for nodes that need a {@link FrameState} for deoptimizing to a point after their + * execution. + */ + public interface DeoptAfter extends DeoptimizingNode, StateSplit { + } /** - * Sets the deoptimization information associated with this node. - * - * @param state the {@link FrameState} which represents the deoptimization information + * Interface for nodes that need a special {@link FrameState} for deoptimizing during their + * execution (e.g. {@link Invoke}). */ - void setDeoptimizationState(FrameState state); + public interface DeoptDuring extends DeoptimizingNode, StateSplit { + + FrameState stateDuring(); + + /** + * Sets the {@link FrameState} describing the program state during the execution of this + * node. + */ + void setStateDuring(FrameState state); + + /** + * Compute the {@link FrameState} describing the program state during the execution of this + * node from an input {@link FrameState} describing the program state after finishing the + * execution of this node. + */ + void computeStateDuring(FrameState stateAfter); + } } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -66,7 +66,7 @@ DeoptimizeNode newDeopt = graph().add( new DeoptimizeNode(tool.getMetaAccess().decodeDeoptAction(constant), tool.getMetaAccess().decodeDeoptReason(constant), tool.getMetaAccess().decodeDebugId(constant), speculationConstant)); - newDeopt.setDeoptimizationState(getDeoptimizationState()); + newDeopt.setStateBefore(stateBefore()); return newDeopt; } return this; diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -52,7 +52,7 @@ } DeoptimizeNode deopt = graph().add(new DeoptimizeNode(getAction(), getReason())); - deopt.setDeoptimizationState(getDeoptimizationState()); + deopt.setStateBefore(stateBefore()); setNext(deopt); } this.replaceAtUsages(null); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -51,7 +51,7 @@ @Override public boolean verify() { - return getState() != null && super.verify(); + return state != null && super.verify(); } } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Tue Mar 25 18:53:34 2014 +0100 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -public interface Invoke extends StateSplit, Lowerable, DeoptimizingNode, GuardedNode { +public interface Invoke extends StateSplit, Lowerable, DeoptimizingNode.DeoptDuring, GuardedNode { FixedNode next(); @@ -38,10 +38,6 @@ FixedNode asNode(); - FrameState stateDuring(); - - FrameState stateAfter(); - Node predecessor(); void intrinsify(Node node); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -133,17 +133,6 @@ } @Override - public FrameState stateDuring() { - FrameState stateAfter = stateAfter(); - if (stateAfter == null) { - return null; - } - FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), getKind()); - stateDuring.setDuringCall(true); - return stateDuring; - } - - @Override public void intrinsify(Node node) { assert !(node instanceof ValueNode) || (((ValueNode) node).getKind() == Kind.Void) == (getKind() == Kind.Void); CallTargetNode call = callTarget; @@ -174,18 +163,21 @@ } @Override - public FrameState getDeoptimizationState() { - if (deoptState == null) { - FrameState stateDuring = stateDuring(); - updateUsages(deoptState, stateDuring); - deoptState = stateDuring; - } + public FrameState stateDuring() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { - throw new IllegalStateException("Cannot set deoptimization state " + f + " for invoke " + this); + public void setStateDuring(FrameState stateDuring) { + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; + } + + @Override + public void computeStateDuring(FrameState stateAfter) { + FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), getKind()); + stateDuring.setDuringCall(true); + setStateDuring(stateDuring); } @Override @@ -198,14 +190,4 @@ updateUsages(this.guard == null ? null : this.guard.asNode(), guard == null ? null : guard.asNode()); this.guard = guard; } - - @Override - public FrameState getState() { - if (deoptState != null) { - assert stateAfter() == null; - return deoptState; - } else { - return super.getState(); - } - } } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -155,13 +155,6 @@ return LocationIdentity.ANY_LOCATION; } - public FrameState stateDuring() { - FrameState tempStateAfter = stateAfter(); - FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), getKind()); - stateDuring.setDuringCall(true); - return stateDuring; - } - @Override public Map getDebugProperties(Map map) { Map debugProperties = super.getDebugProperties(map); @@ -219,18 +212,21 @@ } @Override - public FrameState getDeoptimizationState() { - if (deoptState == null) { - FrameState stateDuring = stateDuring(); - updateUsages(deoptState, stateDuring); - deoptState = stateDuring; - } + public FrameState stateDuring() { return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { - throw new IllegalStateException(); + public void setStateDuring(FrameState stateDuring) { + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; + } + + @Override + public void computeStateDuring(FrameState tempStateAfter) { + FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), getKind()); + stateDuring.setDuringCall(true); + setStateDuring(stateDuring); } @Override @@ -244,16 +240,6 @@ this.guard = guard; } - @Override - public FrameState getState() { - if (deoptState != null) { - assert stateAfter() == null; - return deoptState; - } else { - return stateAfter(); - } - } - public MemoryCheckpoint asMemoryCheckpoint() { return this; } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -35,7 +35,7 @@ * Node for a {@linkplain ForeignCallDescriptor foreign} call. */ @NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}") -public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint.Multi { +public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode.DeoptDuring, MemoryCheckpoint.Multi { @Input private final NodeInputList arguments; private final ForeignCallsProvider foreignCalls; @@ -101,32 +101,25 @@ } @Override - public FrameState getDeoptimizationState() { - if (deoptState != null) { - return deoptState; - } else if (stateAfter() != null && canDeoptimize()) { - FrameState stateDuring = stateAfter(); - if ((stateDuring.stackSize() > 0 && stateDuring.stackAt(stateDuring.stackSize() - 1) == this) || (stateDuring.stackSize() > 1 && stateDuring.stackAt(stateDuring.stackSize() - 2) == this)) { - stateDuring = stateDuring.duplicateModified(stateDuring.bci, stateDuring.rethrowException(), this.getKind()); - } - setDeoptimizationState(stateDuring); - return stateDuring; - } - return null; + public FrameState stateDuring() { + return deoptState; } @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - assert deoptState == null && canDeoptimize() : "shouldn't assign deoptState to " + this; - deoptState = f; + public void setStateDuring(FrameState stateDuring) { + updateUsages(deoptState, stateDuring); + deoptState = stateDuring; } @Override - public void setStateAfter(FrameState x) { - if (hasSideEffect()) { - super.setStateAfter(x); + public void computeStateDuring(FrameState stateAfter) { + FrameState stateDuring; + if ((stateAfter.stackSize() > 0 && stateAfter.stackAt(stateAfter.stackSize() - 1) == this) || (stateAfter.stackSize() > 1 && stateAfter.stackAt(stateAfter.stackSize() - 2) == this)) { + stateDuring = stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), this.getKind()); + } else { + stateDuring = stateAfter; } + setStateDuring(stateDuring); } @Override @@ -141,14 +134,4 @@ public boolean canDeoptimize() { return foreignCalls.canDeoptimize(descriptor); } - - @Override - public FrameState getState() { - if (deoptState != null) { - assert stateAfter() == null; - return deoptState; - } else { - return super.getState(); - } - } } diff -r b10e42998d01 -r 6ae9af961b7c 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 Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -46,16 +46,6 @@ return stateAfter; } - @Override - public FrameState getState() { - if (stateAfter != null) { - assert super.getState() == null; - return stateAfter; - } else { - return super.getState(); - } - } - public void setStateAfter(FrameState x) { assert x == null || x.isAlive() : "frame state must be in a graph"; updateUsages(stateAfter, x); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -33,9 +33,9 @@ * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and * throws a {@link BailoutException} instead during graph building. */ -public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode { +public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode.DeoptBefore, DeoptimizingNode.DeoptAfter { - @Input private FrameState deoptState; + @Input private FrameState stateBefore; @Input private ValueNode object; @Input private MonitorIdNode monitorId; @@ -44,21 +44,14 @@ return true; } - @Override - public FrameState getDeoptimizationState() { - return deoptState; + public FrameState stateBefore() { + return stateBefore; } @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - deoptState = f; - } - - @Override - public FrameState getState() { - assert deoptState == null || stateAfter() == null; - return deoptState == null ? stateAfter() : deoptState; + public void setStateBefore(FrameState f) { + updateUsages(stateBefore, f); + stateBefore = f; } public ValueNode object() { diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Tue Mar 25 18:53:34 2014 +0100 @@ -34,7 +34,7 @@ * This node is used to perform the finalizer registration at the end of the java.lang.Object * constructor. */ -public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable, LIRLowerable, Virtualizable, DeoptimizingNode { +public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable, LIRLowerable, Virtualizable, DeoptimizingNode.DeoptAfter { public static final ForeignCallDescriptor REGISTER_FINALIZER = new ForeignCallDescriptor("registerFinalizer", void.class, Object.class); @@ -96,17 +96,6 @@ return true; } - @Override - public FrameState getDeoptimizationState() { - return deoptState; - } - - @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - deoptState = f; - } - @SuppressWarnings("unused") @NodeIntrinsic public static void register(Object thisObj) { diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java Tue Mar 25 18:53:34 2014 +0100 @@ -24,25 +24,11 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import static com.oracle.graal.nodes.StructuredGraph.GuardsStage.*; /** * Interface for nodes which have {@link FrameState} nodes as input. - *

- * Some node can implement more than one interface which requires a {@link FrameState} input (e.g. - * {@link DeoptimizingNode} and {@link StateSplit}). Since this interface can only report one - * FrameState, such nodes must ensure they only maintain a link to at most one FrameState at all - * times. Usually this is not a problem because FrameStates are associated only with StateSplit - * nodes before the {@link #AFTER_FSA} stage and only with DeoptimizingNodes after. - * */ public interface NodeWithState { - /** - * Gets the {@link FrameState} associated with this node. - * - * @return the {@link FrameState} associated with this node - */ - FrameState getState(); Node asNode(); } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Tue Mar 25 18:53:34 2014 +0100 @@ -82,7 +82,7 @@ } } if (obsoletes != null) { - ((DynamicDeoptimizeNode) ((MergeNode) target).next()).setDeoptimizationState(fs); + ((DynamicDeoptimizeNode) ((MergeNode) target).next()).setStateBefore(fs); for (AbstractDeoptimizeNode obsolete : obsoletes) { obsolete.safeDelete(); } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Tue Mar 25 18:53:34 2014 +0100 @@ -49,24 +49,41 @@ @Override protected FrameState processNode(FixedNode node, FrameState currentState) { - if (node instanceof DeoptimizingNode) { - DeoptimizingNode deopt = (DeoptimizingNode) node; - if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) { + if (node instanceof DeoptimizingNode.DeoptBefore) { + DeoptimizingNode.DeoptBefore deopt = (DeoptimizingNode.DeoptBefore) node; + if (deopt.canDeoptimize() && deopt.stateBefore() == null) { GraalInternalError.guarantee(currentState != null, "no FrameState at DeoptimizingNode %s", deopt); - deopt.setDeoptimizationState(currentState); + deopt.setStateBefore(currentState); } } + FrameState newState = currentState; if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; FrameState stateAfter = stateSplit.stateAfter(); if (stateAfter != null) { - FrameState newState = stateAfter; + newState = stateAfter; stateSplit.setStateAfter(null); - return newState; } } - return currentState; + + if (node instanceof DeoptimizingNode.DeoptDuring) { + DeoptimizingNode.DeoptDuring deopt = (DeoptimizingNode.DeoptDuring) node; + if (deopt.canDeoptimize()) { + GraalInternalError.guarantee(newState != null, "no FrameState at DeoptimizingNode %s", deopt); + deopt.computeStateDuring(newState); + } + } + + if (node instanceof DeoptimizingNode.DeoptAfter) { + DeoptimizingNode.DeoptAfter deopt = (DeoptimizingNode.DeoptAfter) node; + if (deopt.canDeoptimize() && deopt.stateAfter() == null) { + GraalInternalError.guarantee(newState != null, "no FrameState at DeoptimizingNode %s", deopt); + deopt.setStateAfter(newState); + } + } + + return newState; } @Override diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Tue Mar 25 18:53:34 2014 +0100 @@ -76,7 +76,7 @@ AbstractBeginNode nonTrappingContinuation = ifNode.falseSuccessor(); AbstractBeginNode trappingContinuation = ifNode.trueSuccessor(); NullCheckNode trappingNullCheck = deopt.graph().add(new NullCheckNode(isNullNode.object())); - trappingNullCheck.setDeoptimizationState(deopt.getDeoptimizationState()); + trappingNullCheck.setStateBefore(deopt.stateBefore()); deopt.graph().replaceSplit(ifNode, trappingNullCheck, nonTrappingContinuation); GraphUtil.killCFG(trappingContinuation); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 25 18:53:34 2014 +0100 @@ -966,14 +966,18 @@ return; } - FrameState state = null; + FrameState stateAfter = null; + if (i instanceof StateSplit) { + stateAfter = ((StateSplit) i).stateAfter(); + } + for (Node input : i.inputs()) { if (input instanceof FrameState) { - assert state == null; - state = (FrameState) input; + if (input != stateAfter) { + addUnscheduledToLatestSorting(b, (FrameState) input, sortedInstructions, visited, reads, beforeLastLocation); + } } else { addToLatestSorting(b, (ScheduledNode) input, sortedInstructions, visited, reads, beforeLastLocation); - } } @@ -991,7 +995,7 @@ addToLatestSorting(b, (ScheduledNode) i.predecessor(), sortedInstructions, visited, reads, beforeLastLocation); visited.mark(i); - addUnscheduledToLatestSorting(b, state, sortedInstructions, visited, reads, beforeLastLocation); + addUnscheduledToLatestSorting(b, stateAfter, sortedInstructions, visited, reads, beforeLastLocation); // Now predecessors and inputs are scheduled => we can add this node. if (!sortedInstructions.contains(i)) { diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java Tue Mar 25 18:53:34 2014 +0100 @@ -175,7 +175,7 @@ for (Node returnSideEffect : returnSideEffects) { if (!unwindSideEffects.contains(returnSideEffect) && !maskedSideEffects.contains(returnSideEffect)) { StateSplit split = (StateSplit) returnSideEffect; - if (split.getState() != null) { + if (split.stateAfter() != null) { split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_BCI))); } } @@ -184,7 +184,7 @@ for (Node unwindSideEffect : unwindSideEffects) { if (!returnSideEffects.contains(unwindSideEffect) && !maskedSideEffects.contains(unwindSideEffect)) { StateSplit split = (StateSplit) unwindSideEffect; - if (split.getState() != null) { + if (split.stateAfter() != null) { split.setStateAfter(graph.add(new FrameState(FrameState.AFTER_EXCEPTION_BCI))); } } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 25 18:53:34 2014 +0100 @@ -728,8 +728,8 @@ private final ArrayList sideEffectNodes; /** - * Nodes that inherit the {@link DeoptimizingNode#getDeoptimizationState()} from the replacee - * during instantiation. + * Nodes that inherit a deoptimization {@link FrameState} from the replacee during + * instantiation. */ private final ArrayList deoptNodes; @@ -1024,11 +1024,50 @@ if (replacee instanceof DeoptimizingNode) { DeoptimizingNode replaceeDeopt = (DeoptimizingNode) replacee; - FrameState state = replaceeDeopt.getDeoptimizationState(); + + FrameState stateBefore = null; + FrameState stateDuring = null; + FrameState stateAfter = null; + if (replaceeDeopt.canDeoptimize()) { + if (replaceeDeopt instanceof DeoptimizingNode.DeoptBefore) { + stateBefore = ((DeoptimizingNode.DeoptBefore) replaceeDeopt).stateBefore(); + } + if (replaceeDeopt instanceof DeoptimizingNode.DeoptDuring) { + stateDuring = ((DeoptimizingNode.DeoptDuring) replaceeDeopt).stateDuring(); + } + if (replaceeDeopt instanceof DeoptimizingNode.DeoptAfter) { + stateAfter = ((DeoptimizingNode.DeoptAfter) replaceeDeopt).stateAfter(); + } + } + for (DeoptimizingNode deoptNode : deoptNodes) { DeoptimizingNode deoptDup = (DeoptimizingNode) duplicates.get(deoptNode); - assert replaceeDeopt.canDeoptimize() || !deoptDup.canDeoptimize(); - deoptDup.setDeoptimizationState(state); + if (deoptDup.canDeoptimize()) { + if (deoptDup instanceof DeoptimizingNode.DeoptBefore) { + ((DeoptimizingNode.DeoptBefore) deoptDup).setStateBefore(stateBefore); + } + if (deoptDup instanceof DeoptimizingNode.DeoptDuring) { + DeoptimizingNode.DeoptDuring deoptDupDuring = (DeoptimizingNode.DeoptDuring) deoptDup; + if (stateDuring != null) { + deoptDupDuring.setStateDuring(stateDuring); + } else if (stateAfter != null) { + deoptDupDuring.computeStateDuring(stateAfter); + } else if (stateBefore != null) { + assert !deoptDupDuring.hasSideEffect() : "can't use stateBefore as stateDuring for state split " + deoptDupDuring; + deoptDupDuring.setStateDuring(stateBefore); + } + } + if (deoptDup instanceof DeoptimizingNode.DeoptAfter) { + DeoptimizingNode.DeoptAfter deoptDupAfter = (DeoptimizingNode.DeoptAfter) deoptDup; + if (stateAfter != null) { + deoptDupAfter.setStateAfter(stateAfter); + } else { + assert !deoptDupAfter.hasSideEffect() : "can't use stateBefore as stateAfter for state split " + deoptDupAfter; + deoptDupAfter.setStateAfter(stateBefore); + } + + } + } } } diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Tue Mar 25 18:53:34 2014 +0100 @@ -43,7 +43,7 @@ } public void preExpand(MethodCallTargetNode callTarget, StructuredGraph inliningGraph) { - ResolvedJavaMethod sourceMethod = callTarget.invoke().getState().method(); + ResolvedJavaMethod sourceMethod = callTarget.invoke().stateAfter().method(); int sourceMethodBci = callTarget.invoke().bci(); ResolvedJavaMethod targetMethod = callTarget.targetMethod(); diff -r b10e42998d01 -r 6ae9af961b7c graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Mar 25 16:38:01 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Mar 25 18:53:34 2014 +0100 @@ -132,75 +132,78 @@ } private void processNodeWithState(NodeWithState nodeWithState, final BlockT state, final GraphEffectList effects) { - FrameState frameState = nodeWithState.getState(); - if (frameState != null) { - if (frameState.usages().count() > 1) { - nodeWithState.asNode().replaceFirstInput(frameState, frameState.copyWithInputs()); - frameState = nodeWithState.getState(); - } - final Set virtual = new ArraySet<>(); - frameState.applyToNonVirtual(new NodeClosure() { + for (Node input : nodeWithState.asNode().inputs()) { + if (input instanceof FrameState) { + FrameState frameState = (FrameState) input; + if (frameState.usages().count() > 1) { + FrameState copy = (FrameState) frameState.copyWithInputs(); + nodeWithState.asNode().replaceFirstInput(frameState, copy); + frameState = copy; + } + final Set virtual = new ArraySet<>(); + frameState.applyToNonVirtual(new NodeClosure() { - @Override - public void apply(Node usage, ValueNode value) { - ObjectState valueObj = getObjectState(state, value); - if (valueObj != null) { - virtual.add(valueObj); - effects.replaceFirstInput(usage, value, valueObj.virtual); - } else if (value instanceof VirtualObjectNode) { - ObjectState virtualObj = null; - for (ObjectState obj : state.getStates()) { - if (value == obj.virtual) { - virtualObj = obj; - break; + @Override + public void apply(Node usage, ValueNode value) { + ObjectState valueObj = getObjectState(state, value); + if (valueObj != null) { + virtual.add(valueObj); + effects.replaceFirstInput(usage, value, valueObj.virtual); + } else if (value instanceof VirtualObjectNode) { + ObjectState virtualObj = null; + for (ObjectState obj : state.getStates()) { + if (value == obj.virtual) { + virtualObj = obj; + break; + } + } + if (virtualObj != null) { + virtual.add(virtualObj); } } - if (virtualObj != null) { - virtual.add(virtualObj); - } + } + }); + for (ObjectState obj : state.getStates()) { + if (obj.isVirtual() && obj.hasLocks()) { + virtual.add(obj); } } - }); - for (ObjectState obj : state.getStates()) { - if (obj.isVirtual() && obj.hasLocks()) { - virtual.add(obj); - } - } - ArrayDeque queue = new ArrayDeque<>(virtual); - while (!queue.isEmpty()) { - ObjectState obj = queue.removeLast(); - if (obj.isVirtual()) { - for (ValueNode field : obj.getEntries()) { - if (field instanceof VirtualObjectNode) { - ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field); - if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { - virtual.add(fieldObj); - queue.addLast(fieldObj); + ArrayDeque queue = new ArrayDeque<>(virtual); + while (!queue.isEmpty()) { + ObjectState obj = queue.removeLast(); + if (obj.isVirtual()) { + for (ValueNode field : obj.getEntries()) { + if (field instanceof VirtualObjectNode) { + ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field); + if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { + virtual.add(fieldObj); + queue.addLast(fieldObj); + } } } } } - } - for (ObjectState obj : virtual) { - EscapeObjectState v; - if (obj.isVirtual()) { - ValueNode[] fieldState = obj.getEntries().clone(); - for (int i = 0; i < fieldState.length; i++) { - ObjectState valueObj = getObjectState(state, fieldState[i]); - if (valueObj != null) { - if (valueObj.isVirtual()) { - fieldState[i] = valueObj.virtual; - } else { - fieldState[i] = valueObj.getMaterializedValue(); + for (ObjectState obj : virtual) { + EscapeObjectState v; + if (obj.isVirtual()) { + ValueNode[] fieldState = obj.getEntries().clone(); + for (int i = 0; i < fieldState.length; i++) { + ObjectState valueObj = getObjectState(state, fieldState[i]); + if (valueObj != null) { + if (valueObj.isVirtual()) { + fieldState[i] = valueObj.virtual; + } else { + fieldState[i] = valueObj.getMaterializedValue(); + } } } + v = new VirtualObjectState(obj.virtual, fieldState); + } else { + v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue()); } - v = new VirtualObjectState(obj.virtual, fieldState); - } else { - v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue()); + effects.addVirtualMapping(frameState, v); } - effects.addVirtualMapping(frameState, v); } } }