# HG changeset patch # User Christian Wimmer # Date 1395780628 25200 # Node ID a836fed0e270285b00bca829bbaa8f1f3f9d561c # Parent 7544068e1a91f38cd9c2cf9d0fe46728ea1a3d88# Parent c5ee41cf9823107438ed507344811c7078ceb529 Merge diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RawDataValue.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RawDataValue.java Tue Mar 25 13:32:32 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.api.code; - -import java.util.*; - -import com.oracle.graal.api.meta.*; - -/** - * Represents some raw data. - */ -public final class RawDataValue extends Value { - - private static final long serialVersionUID = 7947228462156566360L; - - private final byte[] data; - - public RawDataValue(PlatformKind kind, byte[] data) { - super(kind); - this.data = data; - } - - public byte[] getData() { - return data; - } - - @Override - public String toString() { - Formatter ret = new Formatter(); - ret.format("data["); - boolean first = true; - for (byte b : data) { - ret.format(first ? "%02X" : " %02X", b); - first = false; - } - return ret.format("]").toString(); - } - - @Override - public int hashCode() { - return Arrays.hashCode(data); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj instanceof RawDataValue) { - RawDataValue other = (RawDataValue) obj; - return Arrays.equals(data, other.data); - } else { - return false; - } - } -} diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java Tue Mar 25 13:50:28 2014 -0700 @@ -90,16 +90,6 @@ return ((RegisterValue) value).getRegister(); } - public static boolean isRawData(Value value) { - assert value != null; - return value instanceof RawDataValue; - } - - public static RawDataValue asRawData(Value value) { - assert value != null; - return (RawDataValue) value; - } - public static Register asIntReg(Value value) { if (value.getKind() != Kind.Int) { throw new InternalError("needed Int got: " + value.getKind()); diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Mar 25 13:50:28 2014 -0700 @@ -60,6 +60,7 @@ import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.StrategySwitchOp; import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp; +import com.oracle.graal.lir.amd64.AMD64Move.LeaDataOp; import com.oracle.graal.lir.amd64.AMD64Move.LeaOp; import com.oracle.graal.lir.amd64.AMD64Move.ZeroExtendLoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MembarOp; @@ -158,6 +159,10 @@ append(createMove(dst, src)); } + public void emitData(AllocatableValue dst, byte[] data) { + append(new LeaDataOp(dst, data)); + } + @Override public AMD64AddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Tue Mar 25 13:50:28 2014 -0700 @@ -115,6 +115,10 @@ } } + public void emitData(AllocatableValue dst, byte[] data) { + throw GraalInternalError.unimplemented(); + } + protected HSAILAddressValue asAddressValue(Value address) { if (address instanceof HSAILAddressValue) { return (HSAILAddressValue) address; diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Tue Mar 25 13:50:28 2014 -0700 @@ -208,6 +208,11 @@ } @Override + public void emitData(AllocatableValue dst, byte[] data) { + throw GraalInternalError.unimplemented(); + } + + @Override public PTXAddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; long finalDisp = displacement; diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Mar 25 13:50:28 2014 -0700 @@ -132,6 +132,11 @@ } @Override + public void emitData(AllocatableValue dst, byte[] data) { + throw GraalInternalError.unimplemented(); + } + + @Override public SPARCAddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; long finalDisp = displacement; diff -r 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CStringNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -22,12 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; -import java.util.*; - -import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; /** @@ -43,17 +42,28 @@ } public void generate(LIRGenerator gen) { - gen.setResult(this, gen.emitMove(new RawDataValue(gen.target().wordKind, toCString(string)))); + gen.setResult(this, emitCString(gen, string)); + } + + public static AllocatableValue emitCString(LIRGeneratorTool gen, String value) { + AllocatableValue dst = gen.newVariable(gen.target().wordKind); + gen.emitData(dst, toCString(value)); + return dst; } /** - * Converts a String to a null terminated byte array suitable for use as a C string value. + * Converts a string to a null terminated byte array of ASCII characters. + * + * @param s a String that must only contain ASCII characters */ - public static byte[] toCString(String value) { - byte[] bytes = value.getBytes(); - byte[] nulTerminated = Arrays.copyOf(bytes, bytes.length + 1); - nulTerminated[bytes.length] = 0; - return nulTerminated; + public static byte[] toCString(String s) { + byte[] bytes = new byte[s.length() + 1]; + for (int i = 0; i < s.length(); i++) { + assert s.charAt(i) < 128 : "non-ascii string: " + s; + bytes[i] = (byte) s.charAt(i); + } + bytes[s.length()] = 0; + return bytes; } @NodeIntrinsic(setStampFromReturnType = true) diff -r 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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(); @@ -65,8 +65,8 @@ ResolvedJavaMethod method = graph().method(); whereString = "in compiled code for " + (method == null ? graph().toString() : format("%H.%n(%p)", method)); } - Value whereArg = new RawDataValue(gen.target().wordKind, toCString(whereString)); - Value formatArg = new RawDataValue(gen.target().wordKind, toCString(format)); + Value whereArg = emitCString(gen, whereString); + Value formatArg = emitCString(gen, format); ForeignCallLinkage linkage = gen.getForeignCalls().lookupForeignCall(VMErrorNode.VM_ERROR); gen.emitForeignCall(linkage, null, whereArg, formatArg, gen.operand(value)); diff -r 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Mar 25 13:50:28 2014 -0700 @@ -310,6 +310,23 @@ } } + public static class LeaDataOp extends AMD64LIRInstruction { + + @Def({REG}) protected AllocatableValue result; + private final byte[] data; + + public LeaDataOp(AllocatableValue result, byte[] data) { + this.result = result; + this.data = data; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + RawData rawData = new RawData(data, 16); + masm.leaq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(rawData)); + } + } + public static class StackLeaOp extends AMD64LIRInstruction { @Def({REG}) protected AllocatableValue result; @@ -409,13 +426,6 @@ } else { throw GraalInternalError.shouldNotReachHere(); } - } else if (isRawData(input)) { - if (isRegister(result)) { - RawData rawData = new RawData(asRawData(input).getData(), 16); - masm.leaq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(rawData)); - } else { - throw GraalInternalError.shouldNotReachHere(); - } } else { throw GraalInternalError.shouldNotReachHere(); } diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Mar 25 13:50:28 2014 -0700 @@ -26,7 +26,6 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; -import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; @@ -390,13 +389,6 @@ } else { throw GraalInternalError.shouldNotReachHere(); } - } else if (isRawData(input)) { - if (isRegister(result)) { - RawData rawData = new RawData(asRawData(input).getData(), 16); - throw GraalInternalError.unimplemented("Emitting raw data: " + rawData); - } else { - throw GraalInternalError.shouldNotReachHere(); - } } else { throw GraalInternalError.shouldNotReachHere(); } diff -r 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Tue Mar 25 13:50:28 2014 -0700 @@ -237,7 +237,6 @@ if ((isVariable(value) && flags.contains(OperandFlag.REG)) || (isRegister(value) && flags.contains(OperandFlag.REG)) || (isStackSlot(value) && flags.contains(OperandFlag.STACK)) || - (isRawData(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || (isConstant(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || (isIllegal(value) && flags.contains(OperandFlag.ILLEGAL))) { return value; diff -r 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Tue Mar 25 13:50:28 2014 -0700 @@ -41,10 +41,6 @@ stateAfter = x; } - public FrameState getState() { - return stateAfter(); - } - public boolean hasSideEffect() { return true; } diff -r 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InfopointNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -51,7 +51,7 @@ @Override public boolean verify() { - return getState() != null && super.verify(); + return state != null && super.verify(); } } diff -r 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Tue Mar 25 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Tue Mar 25 13:50:28 2014 -0700 @@ -59,6 +59,14 @@ void emitMove(AllocatableValue dst, Value src); + /** + * Emits an op that loads the address of some raw data. + * + * @param dst the variable into which the address is loaded + * @param data the data to be installed with the generated code + */ + void emitData(AllocatableValue dst, byte[] data); + Value emitAddress(Value base, long displacement, Value index, int scale); Value emitAddress(StackSlot slot); diff -r 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CollapseFrameForSingleSideEffectPhase.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleExpansionLogger.java Tue Mar 25 13:50:28 2014 -0700 @@ -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 7544068e1a91 -r a836fed0e270 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 13:32:32 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Mar 25 13:50:28 2014 -0700 @@ -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); } } }