Mercurial > hg > graal-jvmci-8
changeset 8892:2c0c708a0ad6
Introduce DeoptimizingNode interface
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Apr 08 09:26:06 2013 +0200 @@ -212,17 +212,17 @@ } @Override - public Variable emitLoad(Kind kind, Value base, int displacement, Value index, int scale, boolean canTrap) { + public Variable emitLoad(Kind kind, Value base, int displacement, Value index, int scale, DeoptimizingNode deopting) { AMD64AddressValue loadAddress = prepareAddress(kind, base, displacement, index, scale); Variable result = newVariable(loadAddress.getKind()); - append(new LoadOp(result, loadAddress, canTrap ? state() : null)); + append(new LoadOp(result, loadAddress, deopting != null ? state(deopting) : null)); return result; } @Override - public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, boolean canTrap) { + public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, DeoptimizingNode deopting) { AMD64AddressValue storeAddress = prepareAddress(kind, base, displacement, index, scale); - LIRFrameState state = canTrap ? state() : null; + LIRFrameState state = deopting != null ? state(deopting) : null; if (isConstant(inputVal)) { Constant c = asConstant(inputVal); @@ -369,11 +369,11 @@ } @Override - public void emitNullCheck(ValueNode v) { + public void emitNullCheck(ValueNode v, DeoptimizingNode deoping) { assert v.kind() == Kind.Object; Variable obj = newVariable(Kind.Object); emitMove(obj, operand(v)); - append(new AMD64Move.NullCheckOp(obj, state())); + append(new AMD64Move.NullCheckOp(obj, state(deoping))); } @Override @@ -509,7 +509,7 @@ if (((fixedWithNextNode instanceof IntegerDivNode) || (fixedWithNextNode instanceof IntegerRemNode)) && fixedWithNextNode.getClass() != divRem.getClass()) { FixedBinaryNode otherDivRem = (FixedBinaryNode) fixedWithNextNode; if (otherDivRem.x() == divRem.x() && otherDivRem.y() == divRem.y() && operand(otherDivRem) == null) { - Value[] results = emitIntegerDivRem(operand(divRem.x()), operand(divRem.y())); + Value[] results = emitIntegerDivRem(operand(divRem.x()), operand(divRem.y()), (DeoptimizingNode) valueNode); if (divRem instanceof IntegerDivNode) { setResult(divRem, results[0]); setResult(otherDivRem, results[1]); @@ -526,19 +526,20 @@ return false; } - private void emitDivRem(AMD64Arithmetic op, Value a, Value b) { + private void emitDivRem(AMD64Arithmetic op, Value a, Value b, LIRFrameState state) { AllocatableValue rax = AMD64.rax.asValue(a.getKind()); emitMove(rax, a); - append(new DivRemOp(op, rax, asAllocatable(b), state())); + append(new DivRemOp(op, rax, asAllocatable(b), state)); } - public Value[] emitIntegerDivRem(Value a, Value b) { + public Value[] emitIntegerDivRem(Value a, Value b, DeoptimizingNode deopting) { + LIRFrameState state = state(deopting); switch (a.getKind()) { case Int: - emitDivRem(IDIVREM, a, b); + emitDivRem(IDIVREM, a, b, state); return new Value[]{emitMove(RAX_I), emitMove(RDX_I)}; case Long: - emitDivRem(LDIVREM, a, b); + emitDivRem(LDIVREM, a, b, state); return new Value[]{emitMove(RAX_L), emitMove(RDX_L)}; default: throw GraalInternalError.shouldNotReachHere(); @@ -546,13 +547,13 @@ } @Override - public Value emitDiv(Value a, Value b) { + public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { switch (a.getKind()) { case Int: - emitDivRem(IDIV, a, b); + emitDivRem(IDIV, a, b, state(deopting)); return emitMove(RAX_I); case Long: - emitDivRem(LDIV, a, b); + emitDivRem(LDIV, a, b, state(deopting)); return emitMove(RAX_L); case Float: { Variable result = newVariable(a.getKind()); @@ -570,21 +571,21 @@ } @Override - public Value emitRem(Value a, Value b) { + public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { switch (a.getKind()) { case Int: - emitDivRem(IREM, a, b); + emitDivRem(IREM, a, b, state(deopting)); return emitMove(RDX_I); case Long: - emitDivRem(LREM, a, b); + emitDivRem(LREM, a, b, state(deopting)); return emitMove(RDX_L); case Float: { RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_FREM); - return emitCall(stub, stub.getCallingConvention(), false, a, b); + return emitCall(stub, stub.getCallingConvention(), null, a, b); } case Double: { RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_DREM); - return emitCall(stub, stub.getCallingConvention(), false, a, b); + return emitCall(stub, stub.getCallingConvention(), null, a, b); } default: throw GraalInternalError.shouldNotReachHere(); @@ -592,13 +593,14 @@ } @Override - public Variable emitUDiv(Value a, Value b) { + public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { + LIRFrameState state = state(deopting); switch (a.getKind()) { case Int: - emitDivRem(IUDIV, a, b); + emitDivRem(IUDIV, a, b, state); return emitMove(RAX_I); case Long: - emitDivRem(LUDIV, a, b); + emitDivRem(LUDIV, a, b, state); return emitMove(RAX_L); default: throw GraalInternalError.shouldNotReachHere(); @@ -606,13 +608,14 @@ } @Override - public Variable emitURem(Value a, Value b) { + public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { + LIRFrameState state = state(deopting); switch (a.getKind()) { case Int: - emitDivRem(IUREM, a, b); + emitDivRem(IUREM, a, b, state); return emitMove(RDX_I); case Long: - emitDivRem(LUREM, a, b); + emitDivRem(LUREM, a, b, state); return emitMove(RDX_L); default: throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Mon Apr 08 09:26:06 2013 +0200 @@ -154,18 +154,18 @@ } @Override - public Variable emitLoad(Kind kind, Value base, int displacement, Value index, int scale, boolean canTrap) { + public Variable emitLoad(Kind kind, Value base, int displacement, Value index, int scale, DeoptimizingNode deopting) { PTXAddressValue loadAddress = prepareAddress(kind, base, displacement, index, scale); Variable result = newVariable(loadAddress.getKind()); - append(new LoadOp(result, loadAddress, canTrap ? state() : null)); + append(new LoadOp(result, loadAddress, deopting != null ? state(deopting) : null)); return result; } @Override - public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, boolean canTrap) { + public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, DeoptimizingNode deopting) { PTXAddressValue storeAddress = prepareAddress(kind, base, displacement, index, scale); Variable input = load(inputVal); - append(new StoreOp(storeAddress, input, canTrap ? state() : null)); + append(new StoreOp(storeAddress, input, deopting != null ? state(deopting) : null)); } @Override @@ -278,22 +278,22 @@ } @Override - public Value emitDiv(Value a, Value b) { + public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { throw new InternalError("NYI"); } @Override - public Value emitRem(Value a, Value b) { + public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { throw new InternalError("NYI"); } @Override - public Variable emitUDiv(Value a, Value b) { + public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { throw new InternalError("NYI"); } @Override - public Variable emitURem(Value a, Value b) { + public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { throw new InternalError("NYI"); } @@ -349,7 +349,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { + public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { append(new ReturnOp(Value.ILLEGAL)); } @@ -469,7 +469,7 @@ } @Override - public void emitNullCheck(ValueNode v) { + public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { throw new InternalError("NYI"); } }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Apr 08 09:26:06 2013 +0200 @@ -214,13 +214,13 @@ } @Override - public Value emitLoad(Kind kind, Value base, int displacement, Value index, int scale, boolean canTrap) { + public Value emitLoad(Kind kind, Value base, int displacement, Value index, int scale, DeoptimizingNode canTrap) { // SPARC: Auto-generated method stub return null; } @Override - public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value input, boolean canTrap) { + public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value input, DeoptimizingNode canTrap) { // SPARC: Auto-generated method stub } @@ -262,25 +262,25 @@ } @Override - public Value emitDiv(Value a, Value b) { + public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { // SPARC: Auto-generated method stub return null; } @Override - public Value emitRem(Value a, Value b) { + public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { // SPARC: Auto-generated method stub return null; } @Override - public Value emitUDiv(Value a, Value b) { + public Value emitUDiv(Value a, Value b, DeoptimizingNode deopting) { // SPARC: Auto-generated method stub return null; } @Override - public Value emitURem(Value a, Value b) { + public Value emitURem(Value a, Value b, DeoptimizingNode deopting) { // SPARC: Auto-generated method stub return null; } @@ -334,7 +334,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { + public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { // SPARC: Auto-generated method stub } @@ -364,7 +364,7 @@ } @Override - public void emitNullCheck(ValueNode v) { + public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { // SPARC: Auto-generated method stub }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Apr 08 09:26:06 2013 +0200 @@ -220,11 +220,11 @@ plan.runPhases(PhasePosition.LOW_LEVEL, graph); - new GuardLoweringPhase(target).apply(graph); - // Add safepoints to loops new SafepointInsertionPhase().apply(graph); + new GuardLoweringPhase(target).apply(graph); + final SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph); Debug.dump(schedule, "final schedule");
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Mon Apr 08 09:26:06 2013 +0200 @@ -218,13 +218,11 @@ return false; } - public LIRFrameState state() { - return state(null); - } - - public LIRFrameState state(DeoptimizationReason reason) { - assert lastState != null || needOnlyOopMaps() : "must have state before instruction"; - return stateFor(lastState, reason); + public LIRFrameState state(DeoptimizingNode deopt) { + if (!deopt.canDeoptimize()) { + return null; + } + return stateFor(deopt.getDeoptimizationState(), deopt.getDeoptimizationReason()); } public LIRFrameState stateFor(FrameState state, DeoptimizationReason reason) { @@ -332,6 +330,12 @@ if (instr instanceof StateSplit) { stateAfter = ((StateSplit) instr).stateAfter(); } + if (instr instanceof DeoptimizingNode) { + DeoptimizingNode deopt = (DeoptimizingNode) instr; + if (deopt.canDeoptimize() && deopt.getDeoptimizationState() == null) { + deopt.setDeoptimizationState(lastState); + } + } if (instr instanceof ValueNode) { ValueNode valueNode = (ValueNode) instr; @@ -658,8 +662,8 @@ } @Override - public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args) { - LIRFrameState info = canTrap ? state() : null; + public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args) { + LIRFrameState state = info != null ? state(info) : null; // move the arguments into the correct location frameMap.callsMethod(cc); @@ -671,7 +675,7 @@ emitMove(loc, arg); argLocations[i] = loc; } - emitCall(callTarget, cc.getReturn(), argLocations, cc.getTemporaries(), info); + emitCall(callTarget, cc.getReturn(), argLocations, cc.getTemporaries(), state); if (isLegal(cc.getReturn())) { return emitMove(cc.getReturn()); @@ -688,25 +692,7 @@ Value resultOperand = cc.getReturn(); Value[] args = visitInvokeArguments(cc, x.arguments()); - LIRFrameState info = null; - FrameState stateAfter = x.stateAfter(); - if (stateAfter != null) { - // (cwimmer) I made the code that modifies the operand stack conditional. My scenario: - // runtime calls to, e.g., - // CreateNullPointerException have no equivalent in the bytecodes, so there is no invoke - // bytecode. - // Therefore, the result of the runtime call was never pushed to the stack, and we - // cannot pop it here. - FrameState stateBeforeReturn = stateAfter; - if ((stateAfter.stackSize() > 0 && stateAfter.stackAt(stateAfter.stackSize() - 1) == x) || (stateAfter.stackSize() > 1 && stateAfter.stackAt(stateAfter.stackSize() - 2) == x)) { - stateBeforeReturn = stateAfter.duplicateModified(stateAfter.bci, stateAfter.rethrowException(), x.kind()); - } - info = stateFor(stateBeforeReturn, null); - } else { - info = state(); - } - - emitCall(call, resultOperand, args, cc.getTemporaries(), info); + emitCall(call, resultOperand, args, cc.getTemporaries(), state(x)); if (isLegal(resultOperand)) { setResult(x, emitMove(resultOperand));
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Apr 08 09:26:06 2013 +0200 @@ -161,7 +161,7 @@ @Override public void visitSafepointNode(SafepointNode i) { - LIRFrameState info = state(); + LIRFrameState info = state(i); append(new AMD64SafepointOp(info, runtime().config, this)); } @@ -232,8 +232,8 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { - append(new AMD64DeoptimizeOp(action, reason, state())); + public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { + append(new AMD64DeoptimizeOp(action, deopting.getDeoptimizationReason(), state(deopting))); } @Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, 2013, 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.hotspot.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +public class DeoptimizingStubCall extends DeoptimizingFixedWithNextNode { + + public DeoptimizingStubCall(Stamp stamp) { + super(stamp); + } + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return null; + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/IdentityHashCodeStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/IdentityHashCodeStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -34,7 +34,7 @@ /** * Node implementing a call to HotSpot's {@code graal_identityhashcode} stub. */ -public class IdentityHashCodeStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class IdentityHashCodeStubCall extends DeoptimizingStubCall implements LIRGenLowerable { @Input private final ValueNode object; public static final Descriptor IDENTITY_HASHCODE = new Descriptor("identity_hashcode", false, int.class, Object.class); @@ -47,7 +47,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(IdentityHashCodeStubCall.IDENTITY_HASHCODE); - Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object)); + Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(object)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -33,7 +33,7 @@ /** * Node implementing a call to HotSpot's {@code graal_monitorenter} stub. */ -public class MonitorEnterStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class MonitorEnterStubCall extends DeoptimizingStubCall implements LIRGenLowerable { @Input private final ValueNode object; @Input private final ValueNode lock; @@ -48,7 +48,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(MonitorEnterStubCall.MONITORENTER); - gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object), gen.operand(lock)); + gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(object), gen.operand(lock)); } @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -35,7 +35,7 @@ /** * Node implementing a call to HotSpot's {@code graal_monitorexit} stub. */ -public class MonitorExitStubCall extends FixedWithNextNode implements LIRGenLowerable, MonitorReference { +public class MonitorExitStubCall extends DeoptimizingStubCall implements LIRGenLowerable, MonitorReference { @Input private final ValueNode object; private int lockDepth; @@ -60,7 +60,7 @@ HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen; StackSlot slot = hsGen.getLockSlot(lockDepth); RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(MonitorExitStubCall.MONITOREXIT); - gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object), gen.emitLea(slot)); + gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(object), gen.emitLea(slot)); } @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArraySlowStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArraySlowStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -35,7 +35,7 @@ /** * Node implementing a call to the {@code new_array} stub. */ -public class NewArraySlowStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class NewArraySlowStubCall extends DeoptimizingStubCall implements LIRGenLowerable { private static final Stamp defaultStamp = StampFactory.objectNonNull(); @@ -62,7 +62,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_ARRAY_SLOW); - Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub), gen.operand(length)); + Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(hub), gen.operand(length)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -36,7 +36,7 @@ /** * A call to the {@link NewArrayStub}. */ -public class NewArrayStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class NewArrayStubCall extends DeoptimizingStubCall implements LIRGenLowerable { private static final Stamp defaultStamp = StampFactory.objectNonNull(); @@ -63,7 +63,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_ARRAY); - Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub), gen.operand(length)); + Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(hub), gen.operand(length)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceSlowStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -35,7 +35,7 @@ /** * Node implementing a call to HotSpot's {@code new_instance} stub. */ -public class NewInstanceSlowStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class NewInstanceSlowStubCall extends DeoptimizingStubCall implements LIRGenLowerable { private static final Stamp defaultStamp = StampFactory.objectNonNull(); @@ -60,7 +60,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_INSTANCE_SLOW); - Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub)); + Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(hub)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -36,7 +36,7 @@ /** * A call to the {@link NewInstanceStub}. */ -public class NewInstanceStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class NewInstanceStubCall extends DeoptimizingStubCall implements LIRGenLowerable { private static final Stamp defaultStamp = StampFactory.objectNonNull(); @@ -61,7 +61,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NEW_INSTANCE); - Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub)); + Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(hub)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -36,7 +36,7 @@ /** * Node implementing a call to HotSpot's {@code new_multi_array} stub. */ -public class NewMultiArrayStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class NewMultiArrayStubCall extends DeoptimizingStubCall implements LIRGenLowerable { private static final Stamp defaultStamp = StampFactory.objectNonNull(); @@ -65,7 +65,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(NewMultiArrayStubCall.NEW_MULTI_ARRAY); - Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(hub), Constant.forInt(rank), gen.operand(dims)); + Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(hub), Constant.forInt(rank), gen.operand(dims)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -69,7 +69,7 @@ parameters.add(frameState.localAt(slot)); } Value[] args = gen.visitInvokeArguments(cc, parameters); - Value entry = gen.emitLoad(Kind.Long, gen.operand(target), config.nmethodEntryOffset, Value.ILLEGAL, 0, false); + Value entry = gen.emitLoad(Kind.Long, gen.operand(target), config.nmethodEntryOffset, Value.ILLEGAL, 0, null); HotSpotLIRGenerator hsgen = (HotSpotLIRGenerator) gen; hsgen.emitTailcall(args, entry); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ThreadIsInterruptedStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ThreadIsInterruptedStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -37,7 +37,7 @@ /** * Node implementing a call to HotSpot's ThreadIsInterrupted stub. */ -public class ThreadIsInterruptedStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class ThreadIsInterruptedStubCall extends DeoptimizingStubCall implements LIRGenLowerable { @Input private final ValueNode thread; @Input private final ValueNode clearIsInterrupted; @@ -52,7 +52,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(ThreadIsInterruptedStubCall.THREAD_IS_INTERRUPTED); - Variable result = gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(thread), gen.operand(clearIsInterrupted)); + Variable result = gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(thread), gen.operand(clearIsInterrupted)); gen.setResult(this, result); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -28,7 +28,6 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; @@ -51,15 +50,7 @@ @Override public void generate(LIRGenerator gen) { - String where; - try { - LIRFrameState state = gen.state(); - BytecodePosition pos = state.topFrame; - where = "near or " + CodeUtil.append(new StringBuilder(100), pos).toString().replace(CodeUtil.NEW_LINE, CodeUtil.NEW_LINE + "\t"); - } catch (Throwable t) { - // Report a less accurate location when debug info cannot be obtained - where = "in compiled code for " + MetaUtil.format("%H.%n(%p)", gen.method()); - } + String where = "in compiled code for " + MetaUtil.format("%H.%n(%p)", gen.method()); HotSpotRuntime runtime = (HotSpotRuntime) gen.getRuntime(); Constant whereArg = Constant.forObject(runtime.registerGCRoot(where)); @@ -71,7 +62,7 @@ } RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(VMErrorNode.VM_ERROR); - gen.emitCall(stub, stub.getCallingConvention(), false, whereArg, formatArg, gen.operand(value)); + gen.emitCall(stub, stub.getCallingConvention(), null, whereArg, formatArg, gen.operand(value)); } @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -32,7 +32,7 @@ /** * Node implementing a call to HotSpot's object pointer verification stub. */ -public class VerifyOopStubCall extends FixedWithNextNode implements LIRGenLowerable { +public class VerifyOopStubCall extends DeoptimizingStubCall implements LIRGenLowerable { @Input private final ValueNode object; public static final Descriptor VERIFY_OOP = new Descriptor("verify_oop", false, void.class, Object.class); @@ -45,7 +45,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(VerifyOopStubCall.VERIFY_OOP); - gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(object)); + gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(object)); } @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPostStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -48,7 +48,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(WriteBarrierPostStubCall.WBPOSTCALL); - gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(object), gen.operand(card)); + gen.emitCall(stub, stub.getCallingConvention(), null, gen.operand(object), gen.operand(card)); } @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrierPreStubCall.java Mon Apr 08 09:26:06 2013 +0200 @@ -45,7 +45,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(WriteBarrierPreStubCall.WBPRECALL); - gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(object)); + gen.emitCall(stub, stub.getCallingConvention(), null, gen.operand(object)); } @NodeIntrinsic
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Mon Apr 08 09:26:06 2013 +0200 @@ -98,7 +98,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(descriptor); - gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key)); + gen.emitCall(stub, stub.getCallingConvention(), null, gen.operand(in), gen.operand(out), gen.operand(key)); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Mon Apr 08 09:26:06 2013 +0200 @@ -119,7 +119,7 @@ @Override public void generate(LIRGenerator gen) { RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(descriptor); - gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key), gen.operand(r), gen.operand(inLength)); + gen.emitCall(stub, stub.getCallingConvention(), null, gen.operand(in), gen.operand(out), gen.operand(key), gen.operand(r), gen.operand(inLength)); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -29,7 +29,9 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") -public class DeoptimizeNode extends ControlSinkNode implements Node.IterableNodeType, LIRLowerable { +public class DeoptimizeNode extends ControlSinkNode implements Node.IterableNodeType, LIRLowerable, DeoptimizingNode { + + @Input private FrameState deoptState; private final DeoptimizationAction action; private final DeoptimizationReason reason; @@ -50,9 +52,34 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.emitDeoptimize(action, reason); + gen.emitDeoptimize(action, this); } @NodeIntrinsic public static native void deopt(@ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter DeoptimizationReason reason); + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public FrameState getDeoptimizationState() { + return deoptState; + } + + @Override + public void setDeoptimizationState(FrameState f) { + deoptState = f; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return reason; + } + + @Override + public boolean isCallSiteDeoptimization() { + return false; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingFixedWithNextNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, 2013, 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.nodes; + +import java.util.*; + +import com.oracle.graal.nodes.type.*; + +public abstract class DeoptimizingFixedWithNextNode extends FixedWithNextNode implements DeoptimizingNode { + + @Input private FrameState deoptState; + + public DeoptimizingFixedWithNextNode(Stamp stamp) { + super(stamp); + } + + public DeoptimizingFixedWithNextNode(Stamp stamp, List<ValueNode> dependencies) { + super(stamp, dependencies); + } + + public DeoptimizingFixedWithNextNode(Stamp stamp, ValueNode... dependencies) { + super(stamp, dependencies); + } + + @Override + public FrameState getDeoptimizationState() { + return deoptState; + } + + @Override + public void setDeoptimizationState(FrameState f) { + deoptState = f; + } + + @Override + public boolean isCallSiteDeoptimization() { + return false; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013, 2013, 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.nodes; + +import com.oracle.graal.api.meta.*; + +/** + * Interface that needs to be implemented by nodes which need deoptimization information. + * + */ +public interface DeoptimizingNode { + + /** + * Returns true if this particular instance needs deoptimization information. + * + * @return true if this particular instance needs deoptimization information + */ + boolean canDeoptimize(); + + /** + * Returns the deoptimization information associated with this node if any. + * + * @return the deoptimization information associated with this node if any. + */ + FrameState getDeoptimizationState(); + + /** + * Set the deoptimization information associated with this node. + * + * @param state the FrameState which represents the deoptimization information. + */ + void setDeoptimizationState(FrameState state); + + /** + * Returns the reason for deoptimization triggered by this node. If deoptimization at this point + * can happen for external reasons (i.e. not explicitely triggered by this node) this method can + * return null. + * + * @return the reason for deoptimization triggered by this node. + */ + DeoptimizationReason getDeoptimizationReason(); + + /** + * Returns true if this node needs deoptimization information for stack-walking purposes because + * it is a call-site. While most other nodes use deoptimization information representing a state + * that happened before them, these nodes use a state that is valid during the call itself. + * + * @return true if this node needs deoptimization information for stack-walking purposes. + */ + boolean isCallSiteDeoptimization(); +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Mon Apr 08 09:26:06 2013 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -public interface Invoke extends StateSplit, Lowerable { +public interface Invoke extends StateSplit, Lowerable, DeoptimizingNode { FixedNode next();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -175,4 +175,29 @@ stateAfter.safeDelete(); } } + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return null; + } + + @Override + public FrameState getDeoptimizationState() { + return stateDuring(); + } + + @Override + public void setDeoptimizationState(FrameState f) { + throw new IllegalStateException(); + } + + @Override + public boolean isCallSiteDeoptimization() { + return true; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -221,4 +221,29 @@ public double probability(BeginNode successor) { return successor == next ? 1 - EXCEPTION_PROBA : EXCEPTION_PROBA; } + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return null; + } + + @Override + public FrameState getDeoptimizationState() { + return stateDuring(); + } + + @Override + public void setDeoptimizationState(FrameState f) { + throw new IllegalStateException(); + } + + @Override + public boolean isCallSiteDeoptimization() { + return true; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -29,7 +30,7 @@ /** * Marks a position in the graph where a safepoint should be emitted. */ -public class SafepointNode extends FixedWithNextNode implements LIRLowerable, Node.IterableNodeType { +public class SafepointNode extends DeoptimizingFixedWithNextNode implements LIRLowerable, Node.IterableNodeType { public SafepointNode() { this(StampFactory.forVoid()); @@ -43,4 +44,14 @@ public void generate(LIRGeneratorTool gen) { gen.visitSafepointNode(this); } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return null; + } + + @Override + public boolean canDeoptimize() { + return true; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -23,12 +23,10 @@ package com.oracle.graal.nodes.calc; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; -@NodeInfo(shortName = "/") -public class FixedBinaryNode extends FixedWithNextNode { +public abstract class FixedBinaryNode extends DeoptimizingFixedWithNextNode { @Input private ValueNode x; @Input private ValueNode y; @@ -46,4 +44,9 @@ this.x = x; this.y = y; } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return DeoptimizationReason.ArithmeticException; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -53,6 +53,6 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitDiv(gen.operand(x()), gen.operand(y()))); + gen.setResult(this, gen.emitDiv(gen.operand(x()), gen.operand(y()), null)); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -49,6 +49,6 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y()))); + gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y()), null)); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -109,6 +109,11 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitDiv(gen.operand(x()), gen.operand(y()))); + gen.setResult(this, gen.emitDiv(gen.operand(x()), gen.operand(y()), this)); + } + + @Override + public boolean canDeoptimize() { + return y().integerStamp().contains(0); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -66,6 +66,11 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y()))); + gen.setResult(this, gen.emitRem(gen.operand(x()), gen.operand(y()), this)); + } + + @Override + public boolean canDeoptimize() { + return y().integerStamp().contains(0); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -67,6 +67,11 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitUDiv(gen.operand(x()), gen.operand(y()))); + gen.setResult(this, gen.emitUDiv(gen.operand(x()), gen.operand(y()), this)); + } + + @Override + public boolean canDeoptimize() { + return y().integerStamp().contains(0); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -66,6 +66,11 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitURem(gen.operand(x()), gen.operand(y()))); + gen.setResult(this, gen.emitURem(gen.operand(x()), gen.operand(y()), this)); + } + + @Override + public boolean canDeoptimize() { + return y().integerStamp().contains(0); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/Access.java Mon Apr 08 09:26:06 2013 +0200 @@ -25,7 +25,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -public interface Access { +public interface Access extends DeoptimizingNode { ValueNode object();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -33,7 +34,7 @@ * {@linkplain #nullCheckLocation() location}. The access does not include a null check on the * object. */ -public abstract class AccessNode extends FixedWithNextNode implements Access { +public abstract class AccessNode extends DeoptimizingFixedWithNextNode implements Access { @Input private ValueNode object; @Input private ValueNode location; @@ -81,4 +82,14 @@ public Node node() { return this; } + + @Override + public boolean canDeoptimize() { + return nullCheck; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return DeoptimizationReason.NullCheckException; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -33,6 +34,7 @@ @Input private ValueNode object; @Input private LocationNode location; + @Input private FrameState deoptState; private boolean nullCheck; public ValueNode object() { @@ -78,5 +80,30 @@ return this; } + @Override + public boolean canDeoptimize() { + return nullCheck; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return DeoptimizationReason.NullCheckException; + } + + @Override + public FrameState getDeoptimizationState() { + return deoptState; + } + + @Override + public void setDeoptimizationState(FrameState f) { + deoptState = f; + } + + @Override + public boolean isCallSiteDeoptimization() { + return false; + } + public abstract Access asFixedNode(); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -53,7 +53,7 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, location().generateLoad(gen, object(), getNullCheck())); + gen.setResult(this, location().generateLoad(gen, object(), this)); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -86,12 +86,12 @@ } @Override - public Value generateLoad(LIRGeneratorTool gen, ValueNode base, boolean canTrap) { - return gen.emitLoad(getValueKind(), gen.operand(base), displacement(), gen.operand(index()), indexScaling(), canTrap); + public Value generateLoad(LIRGeneratorTool gen, ValueNode base, DeoptimizingNode deopting) { + return gen.emitLoad(getValueKind(), gen.operand(base), displacement(), gen.operand(index()), indexScaling(), deopting); } @Override - public void generateStore(LIRGeneratorTool gen, ValueNode base, ValueNode value, boolean canTrap) { - gen.emitStore(getValueKind(), gen.operand(base), displacement(), gen.operand(index()), indexScaling(), gen.operand(value), canTrap); + public void generateStore(LIRGeneratorTool gen, ValueNode base, ValueNode value, DeoptimizingNode deopting) { + gen.emitStore(getValueKind(), gen.operand(base), displacement(), gen.operand(index()), indexScaling(), gen.operand(value), deopting); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -107,11 +107,11 @@ return gen.emitLea(gen.operand(base), displacement(), Value.ILLEGAL, 0); } - public Value generateLoad(LIRGeneratorTool gen, ValueNode base, boolean canTrap) { - return gen.emitLoad(getValueKind(), gen.operand(base), displacement(), Value.ILLEGAL, 0, canTrap); + public Value generateLoad(LIRGeneratorTool gen, ValueNode base, DeoptimizingNode deopting) { + return gen.emitLoad(getValueKind(), gen.operand(base), displacement(), Value.ILLEGAL, 0, deopting); } - public void generateStore(LIRGeneratorTool gen, ValueNode base, ValueNode value, boolean canTrap) { - gen.emitStore(getValueKind(), gen.operand(base), displacement(), Value.ILLEGAL, 0, gen.operand(value), canTrap); + public void generateStore(LIRGeneratorTool gen, ValueNode base, ValueNode value, DeoptimizingNode deopting) { + gen.emitStore(getValueKind(), gen.operand(base), displacement(), Value.ILLEGAL, 0, gen.operand(value), deopting); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -22,11 +22,12 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public class NullCheckNode extends FixedWithNextNode implements LIRLowerable { +public class NullCheckNode extends DeoptimizingFixedWithNextNode implements LIRLowerable { @Input public ValueNode object; @@ -41,6 +42,16 @@ @Override public void generate(LIRGeneratorTool generator) { - generator.emitNullCheck(object); + generator.emitNullCheck(object, this); + } + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return DeoptimizationReason.NullCheckException; } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -57,7 +57,7 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, location().generateLoad(gen, object(), getNullCheck())); + gen.setResult(this, location().generateLoad(gen, object(), this)); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -30,9 +30,10 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(nameTemplate = "RuntimeCall#{p#descriptor/s}") -public final class RuntimeCallNode extends AbstractCallNode implements LIRLowerable { +public final class RuntimeCallNode extends AbstractCallNode implements LIRLowerable, DeoptimizingNode { private final Descriptor descriptor; + @Input private FrameState deoptState; public RuntimeCallNode(Descriptor descriptor, ValueNode... arguments) { super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())), arguments); @@ -65,4 +66,41 @@ } return super.toString(verbosity); } + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public FrameState getDeoptimizationState() { + if (deoptState != null) { + return deoptState; + } else if (stateAfter() != null) { + 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.kind()); + } + return stateDuring; + } + return null; + } + + @Override + public void setDeoptimizationState(FrameState f) { + if (deoptState != null) { + throw new IllegalStateException(); + } + deoptState = f; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return null; + } + + @Override + public boolean isCallSiteDeoptimization() { + return stateAfter() != null; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -59,7 +59,7 @@ @Override public void generate(LIRGeneratorTool gen) { - location().generateStore(gen, object(), value(), getNullCheck()); + location().generateStore(gen, object(), value(), this); } @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -32,10 +33,11 @@ * 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 StateSplit, Canonicalizable, LIRLowerable, Virtualizable { +public final class RegisterFinalizerNode extends AbstractStateSplit implements StateSplit, Canonicalizable, LIRLowerable, Virtualizable, DeoptimizingNode { public static final Descriptor REGISTER_FINALIZER = new Descriptor("registerFinalizer", true, void.class, Object.class); + @Input private FrameState deoptState; @Input private ValueNode object; public ValueNode object() { @@ -50,7 +52,7 @@ @Override public void generate(LIRGeneratorTool gen) { RuntimeCallTarget call = gen.getRuntime().lookupRuntimeCall(REGISTER_FINALIZER); - gen.emitCall(call, call.getCallingConvention(), true, gen.operand(object())); + gen.emitCall(call, call.getCallingConvention(), this, gen.operand(object())); } @Override @@ -83,6 +85,31 @@ } } + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public FrameState getDeoptimizationState() { + return deoptState; + } + + @Override + public void setDeoptimizationState(FrameState f) { + deoptState = f; + } + + @Override + public DeoptimizationReason getDeoptimizationReason() { + return null; + } + + @Override + public boolean isCallSiteDeoptimization() { + return false; + } + @SuppressWarnings("unused") @NodeIntrinsic public static void register(Object thisObj) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Mon Apr 08 09:26:06 2013 +0200 @@ -57,9 +57,9 @@ public abstract void emitMove(Value dst, Value src); - public abstract Value emitLoad(Kind kind, Value base, int displacement, Value index, int scale, boolean canTrap); + public abstract Value emitLoad(Kind kind, Value base, int displacement, Value index, int scale, DeoptimizingNode deopting); - public abstract void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value input, boolean canTrap); + public abstract void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value input, DeoptimizingNode deopting); public abstract Value emitLea(Value base, int displacement, Value index, int scale); @@ -73,13 +73,13 @@ public abstract Value emitMul(Value a, Value b); - public abstract Value emitDiv(Value a, Value b); + public abstract Value emitDiv(Value a, Value b, DeoptimizingNode deopting); - public abstract Value emitRem(Value a, Value b); + public abstract Value emitRem(Value a, Value b, DeoptimizingNode deopting); - public abstract Value emitUDiv(Value a, Value b); + public abstract Value emitUDiv(Value a, Value b, DeoptimizingNode deopting); - public abstract Value emitURem(Value a, Value b); + public abstract Value emitURem(Value a, Value b, DeoptimizingNode deopting); public abstract Value emitAnd(Value a, Value b); @@ -97,11 +97,11 @@ public abstract void emitMembar(int barriers); - public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason); + public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting); - public abstract void emitNullCheck(ValueNode v); + public abstract void emitNullCheck(ValueNode v, DeoptimizingNode deopting); - public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args); + public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args); public abstract void emitIf(IfNode i);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -47,7 +47,7 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitLoad(readKind, gen.operand(address), 0, Value.ILLEGAL, 0, false)); + gen.setResult(this, gen.emitLoad(readKind, gen.operand(address), 0, Value.ILLEGAL, 0, null)); } @SuppressWarnings("unchecked")
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Wed Mar 27 15:31:23 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Mon Apr 08 09:26:06 2013 +0200 @@ -50,7 +50,7 @@ @Override public void generate(LIRGeneratorTool gen) { Value v = gen.operand(value); - gen.emitStore(kind, gen.operand(address), 0, Value.ILLEGAL, 0, v, false); + gen.emitStore(kind, gen.operand(address), 0, Value.ILLEGAL, 0, v, null); } /*