# HG changeset patch # User Christian Haeubl # Date 1331850694 25200 # Node ID 0ebca2e35ca5a992243f3a0e03c8583e5238f80e # Parent 6766253384bfe22d54d6f9767a9e1325ad497ee8 more preparations for disabling runtime feedback selectively based on deoptimization history diff -r 6766253384bf -r 0ebca2e35ca5 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 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Mar 15 15:31:34 2012 -0700 @@ -744,7 +744,7 @@ } @Override - public void emitGuardCheck(BooleanNode comp, RiDeoptReason deoptReason) { + public void emitGuardCheck(BooleanNode comp, DeoptReason deoptReason) { if (comp instanceof NullCheckNode && !((NullCheckNode) comp).expectedNull) { emitNullCheckGuard((NullCheckNode) comp); } else if (comp instanceof ConstantNode && comp.asConstant().asBoolean()) { @@ -752,7 +752,7 @@ } else { // Fall back to a normal branch. LIRDebugInfo info = state(); - LabelRef stubEntry = createDeoptStub(RiDeoptAction.InvalidateReprofile, deoptReason, info, comp); + LabelRef stubEntry = createDeoptStub(DeoptAction.InvalidateReprofile, deoptReason, info, comp); emitBranch(comp, null, stubEntry, info); } } @@ -985,7 +985,7 @@ } - protected abstract LabelRef createDeoptStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo); + protected abstract LabelRef createDeoptStub(DeoptAction action, DeoptReason reason, LIRDebugInfo info, Object deoptInfo); @Override public Variable emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args) { diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java Thu Mar 15 15:31:34 2012 -0700 @@ -28,7 +28,6 @@ import com.oracle.graal.lir.cfg.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.max.cri.ri.*; public class LoweringPhase extends Phase { @@ -60,8 +59,8 @@ } @Override - public Node createGuard(Node condition, RiDeoptReason deoptReason) { - // TODO (thomaswue): Docuemnt why this must not be called on floating nodes. + public Node createGuard(Node condition, DeoptReason deoptReason) { + // TODO (thomaswue): Document why this must not be called on floating nodes. throw new UnsupportedOperationException(); } }; @@ -118,7 +117,7 @@ } @Override - public Node createGuard(Node condition, RiDeoptReason deoptReason) { + public Node createGuard(Node condition, DeoptReason deoptReason) { FixedNode guardAnchor = (FixedNode) getGuardAnchor(); if (GraalOptions.OptEliminateGuards) { for (Node usage : condition.usages()) { diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java Thu Mar 15 15:31:34 2012 -0700 @@ -25,22 +25,23 @@ import java.util.*; import com.oracle.graal.compiler.*; +import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.*; import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.*; import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; public class AMD64DeoptimizationStub extends AMD64SlowPath { public final Label label = new Label(); public final LIRDebugInfo info; - public final RiDeoptAction action; - public final RiDeoptReason reason; + public final DeoptAction action; + public final DeoptReason reason; public final Object deoptInfo; - public AMD64DeoptimizationStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo) { + public AMD64DeoptimizationStub(DeoptAction action, DeoptReason reason, LIRDebugInfo info, Object deoptInfo) { this.action = action; this.reason = reason; this.info = info; @@ -63,16 +64,51 @@ AMD64Call.directCall(tasm, masm, CiRuntimeCall.SetDeoptInfo, info); } - masm.movq(scratch, encodeDeoptActionAndReason(action, reason)); + masm.movl(scratch, encodeDeoptActionAndReason(action, reason)); // TODO Make this an explicit calling convention instead of using a scratch register AMD64Call.directCall(tasm, masm, CiRuntimeCall.Deoptimize, info); AMD64Call.shouldNotReachHere(tasm, masm); } - public static int encodeDeoptActionAndReason(RiDeoptAction action, RiDeoptReason reason) { - int a = action.value(); - int r = reason.value(); - assert NumUtil.isUShort(a) && NumUtil.isUShort(r) : "both values are encoded in one uint"; - return (a << 16) | r; + // TODO (ch) this is HotSpot specific -> move it somewhere else + public static int encodeDeoptActionAndReason(DeoptAction action, DeoptReason reason) { + final int actionShift = 0; + final int reasonShift = 3; + + int actionValue = getDeoptActionValue(action); + int reasonValue = getDeoptReasonValue(reason); + return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); + } + + // TODO (ch) this is HotSpot specific -> move it somewhere else + private static int getDeoptActionValue(DeoptAction action) { + switch(action) { + case None: return 0; + case RecompileIfTooManyDeopts: return 1; + case InvalidateReprofile: return 2; + case InvalidateRecompile: return 3; + case InvalidateStopCompiling: return 4; + default: throw GraalInternalError.shouldNotReachHere(); + } + } + + // TODO (ch) this is HotSpot specific -> move it somewhere else + private static int getDeoptReasonValue(DeoptReason reason) { + switch(reason) { + case None: return 0; + case NullCheckException: return 1; + case BoundsCheckException: return 2; + case ClassCastException: return 3; + case ArrayStoreException: return 4; + case UnreachedCode: return 5; + case TypeCheckedInliningViolated: return 6; + case OptimizedTypeCheckViolated: return 7; + case NotCompiledExceptionHandler: return 8; + case Unresolved: return 9; + case JavaSubroutineMismatch: return 10; + case ArithmeticException: return 11; + case RuntimeConstraint: return 12; + default: throw GraalInternalError.shouldNotReachHere(); + } } } diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java Thu Mar 15 15:31:34 2012 -0700 @@ -499,7 +499,7 @@ @Override - public void emitDeoptimizeOn(Condition cond, RiDeoptAction action, RiDeoptReason reason, Object deoptInfo) { + public void emitDeoptimizeOn(Condition cond, DeoptAction action, DeoptReason reason, Object deoptInfo) { LIRDebugInfo info = state(); LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo); if (cond != null) { @@ -546,7 +546,7 @@ } @Override - protected LabelRef createDeoptStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo) { + protected LabelRef createDeoptStub(DeoptAction action, DeoptReason reason, LIRDebugInfo info, Object deoptInfo) { assert info.topFrame.bci >= 0 : "invalid bci for deopt framestate"; AMD64DeoptimizationStub stub = new AMD64DeoptimizationStub(action, reason, info, deoptInfo); lir.deoptimizationStubs.add(stub); diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Thu Mar 15 15:31:34 2012 -0700 @@ -175,7 +175,7 @@ ValueNode receiver = invoke.callTarget().receiver(); ReadHubNode objectClass = graph.add(new ReadHubNode(receiver)); IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClass, type)); - FixedGuardNode guard = graph.add(new FixedGuardNode(isTypeNode, RiDeoptReason.TypeCheckedInliningViolated)); + FixedGuardNode guard = graph.add(new FixedGuardNode(isTypeNode, DeoptReason.TypeCheckedInliningViolated)); AnchorNode anchor = graph.add(new AnchorNode()); assert invoke.predecessor() != null; @@ -303,7 +303,7 @@ if (shouldFallbackToInvoke()) { unknownTypeNode = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, 1, notRecordedTypeProbability, false); } else { - unknownTypeNode = graph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.TypeCheckedInliningViolated)); + unknownTypeNode = graph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile, DeoptReason.TypeCheckedInliningViolated)); } // replace the invoke exception edge @@ -368,7 +368,7 @@ ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.callTarget().receiver())); graph.addBeforeFixed(invoke.node(), objectClassNode); - FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.TypeCheckedInliningViolated)); + FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile, DeoptReason.TypeCheckedInliningViolated)); FixedNode dispatchOnType = createDispatchOnType(graph, objectClassNode, new BeginNode[] {calleeEntryNode}, unknownTypeNode); FixedWithNextNode pred = (FixedWithNextNode) invoke.node().predecessor(); @@ -820,7 +820,7 @@ } else { if (unwindNode != null) { UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode); - DeoptimizeNode deoptimizeNode = new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.NotCompiledExceptionHandler); + DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.NotCompiledExceptionHandler); unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode)); // move the deopt upwards if there is a monitor exit that tries to use the "after exception" frame state // (because there is no "after exception" frame state!) @@ -908,7 +908,7 @@ NodeInputList parameters = callTarget.arguments(); ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0); if (!callTarget.isStatic() && firstParam.kind() == CiKind.Object && !firstParam.stamp().nonNull()) { - graph.addBeforeFixed(invoke.node(), graph.add(new FixedGuardNode(graph.unique(new NullCheckNode(firstParam, false)), RiDeoptReason.TypeCheckFailed))); + graph.addBeforeFixed(invoke.node(), graph.add(new FixedGuardNode(graph.unique(new NullCheckNode(firstParam, false)), DeoptReason.ClassCastException))); } } } diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Thu Mar 15 15:31:34 2012 -0700 @@ -229,7 +229,7 @@ int displacement = ((HotSpotField) field.field()).offset(); assert field.kind() != CiKind.Illegal; ReadNode memoryRead = graph.add(new ReadNode(field.field().kind(true).stackKind(), field.object(), LocationNode.create(field.field(), field.field().kind(true), displacement, graph))); - memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(field.object(), false)), RiDeoptReason.NullCheckFailed)); + memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(field.object(), false)), DeoptReason.NullCheckException)); graph.replaceFixedWithFixed(field, memoryRead); } else if (n instanceof StoreFieldNode) { StoreFieldNode storeField = (StoreFieldNode) n; @@ -238,7 +238,7 @@ } HotSpotField field = (HotSpotField) storeField.field(); WriteNode memoryWrite = graph.add(new WriteNode(storeField.object(), storeField.value(), LocationNode.create(storeField.field(), storeField.field().kind(true), field.offset(), graph))); - memoryWrite.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(storeField.object(), false)), RiDeoptReason.NullCheckFailed)); + memoryWrite.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(storeField.object(), false)), DeoptReason.NullCheckException)); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); @@ -277,7 +277,7 @@ } else { AnchorNode anchor = graph.add(new AnchorNode()); graph.addBeforeFixed(storeIndexed, anchor); - GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(array, false)), RiDeoptReason.NullCheckFailed); + GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(array, false)), DeoptReason.NullCheckException); ReadNode arrayClass = graph.add(new ReadNode(CiKind.Object, array, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph))); arrayClass.setGuard(guard); graph.addBeforeFixed(storeIndexed, arrayClass); @@ -300,7 +300,7 @@ IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph); location.setIndexScalingEnabled(false); ReadNode memoryRead = graph.add(new ReadNode(load.kind(), load.object(), location)); - memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(load.object(), false)), RiDeoptReason.NullCheckFailed)); + memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(load.object(), false)), DeoptReason.NullCheckException)); graph.replaceFixedWithFixed(load, memoryRead); } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n; @@ -318,7 +318,7 @@ ReadHubNode objectClassNode = (ReadHubNode) n; LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph); ReadNode memoryRead = graph.add(new ReadNode(CiKind.Object, objectClassNode.object(), location)); - memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(objectClassNode.object(), false)), RiDeoptReason.NullCheckFailed)); + memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(objectClassNode.object(), false)), DeoptReason.NullCheckException)); graph.replaceFixed(objectClassNode, memoryRead); } } @@ -328,7 +328,7 @@ } private static GuardNode createBoundsCheck(AccessIndexedNode n, CiLoweringTool tool) { - return (GuardNode) tool.createGuard(n.graph().unique(new CompareNode(n.index(), Condition.BT, n.length())), RiDeoptReason.BoundsCheckFailed); + return (GuardNode) tool.createGuard(n.graph().unique(new CompareNode(n.index(), Condition.BT, n.length())), DeoptReason.BoundsCheckException); } @Override diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Thu Mar 15 15:31:34 2012 -0700 @@ -42,6 +42,7 @@ import com.oracle.graal.compiler.target.amd64.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.Compiler; +import com.oracle.graal.nodes.*; public class HotSpotXirGenerator implements RiXirGenerator { @@ -712,9 +713,9 @@ } } - RiDeoptReason deoptReason = is(EXACT_HINTS, flags) ? RiDeoptReason.TypeCheckAssumptionViolated : RiDeoptReason.TypeCheckFailed; + DeoptReason deoptReason = is(EXACT_HINTS, flags) ? DeoptReason.OptimizedTypeCheckViolated : DeoptReason.ClassCastException; XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(RiDeoptAction.InvalidateReprofile, deoptReason))); + asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.InvalidateReprofile, deoptReason))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); @@ -892,7 +893,7 @@ if (is(BOUNDS_CHECK, flags)) { asm.bindOutOfLine(failBoundsCheck); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.BoundsCheckFailed))); + asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.BoundsCheckException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); } @@ -1082,7 +1083,7 @@ checkSubtype(asm, temp, valueHub, compHub); asm.jneq(store, temp, wordConst(asm, 0)); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.TypeCheckFailed))); + asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.ClassCastException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.jmp(store); } @@ -1163,7 +1164,7 @@ if (is(BOUNDS_CHECK, flags)) { asm.bindOutOfLine(failBoundsCheck); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.BoundsCheckFailed))); + asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.BoundsCheckException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); } @@ -1173,7 +1174,7 @@ checkSubtype(asm, temp, valueHub, compHub); asm.jneq(store, temp, wordConst(asm, 0)); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.TypeCheckFailed))); + asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.ArrayStoreException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); } diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 15 15:31:34 2012 -0700 @@ -324,7 +324,7 @@ if (riType instanceof RiResolvedType) { frameState.push(CiKind.Object, append(ConstantNode.forCiConstant(((RiResolvedType) riType).getEncoding(Representation.JavaClass), runtime, currentGraph))); } else { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); frameState.push(CiKind.Object, append(ConstantNode.forObject(null, runtime, currentGraph))); } } else if (con instanceof CiConstant) { @@ -583,7 +583,7 @@ private void genThrow(int bci) { ValueNode exception = frameState.apop(); - FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false)), RiDeoptReason.NullCheckFailed)); + FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false)), DeoptReason.NullCheckException)); append(node); append(handleException(exception, bci)); } @@ -675,7 +675,7 @@ frameState.apush(checkCast); } else { ValueNode object = frameState.apop(); - append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(object, Condition.EQ, ConstantNode.forObject(null, runtime, currentGraph))), RiDeoptReason.Unresolved))); + append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(object, Condition.EQ, ConstantNode.forObject(null, runtime, currentGraph))), DeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } } @@ -693,7 +693,7 @@ frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode), currentGraph))); } else { BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode()); - DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved)); + DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved)); IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(object, true)), trueSucc, deopt, 1)); append(ifNode); lastInstr = trueSucc; @@ -707,7 +707,7 @@ NewInstanceNode n = currentGraph.add(new NewInstanceNode((RiResolvedType) type)); frameState.apush(append(n)); } else { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } } @@ -748,7 +748,7 @@ NewArrayNode n = currentGraph.add(new NewObjectArrayNode((RiResolvedType) type, length)); frameState.apush(append(n)); } else { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } @@ -765,7 +765,7 @@ FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((RiResolvedType) type, dims)); frameState.apush(append(n)); } else { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } } @@ -779,7 +779,7 @@ LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (RiResolvedField) field)); appendOptimizedLoadField(kind, load); } else { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph))); } } @@ -880,7 +880,7 @@ StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (RiResolvedField) field, value)); appendOptimizedStoreField(store); } else { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); } } @@ -922,7 +922,7 @@ if (initialized) { return appendConstant(((RiResolvedType) holder).getEncoding(representation)); } else { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); return null; } } @@ -983,7 +983,7 @@ } private void genInvokeDeopt(RiMethod unresolvedTarget, boolean withReceiver) { - append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); frameState.popArguments(unresolvedTarget.signature().argumentSlots(withReceiver), unresolvedTarget.signature().argumentCount(withReceiver)); CiKind kind = unresolvedTarget.signature().returnKind(false); if (kind != CiKind.Void) { @@ -1020,7 +1020,7 @@ private void appendInvoke(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] args) { CiKind resultType = targetMethod.signature().returnKind(false); if (GraalOptions.DeoptALot) { - DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(RiDeoptAction.None, RiDeoptReason.DeoptimizeALot)); + DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptAction.None, DeoptReason.RuntimeConstraint)); deoptimize.setMessage("invoke " + targetMethod.name()); append(deoptimize); frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph)); @@ -1109,7 +1109,7 @@ ValueNode local = frameState.loadLocal(localIndex); JsrScope scope = currentBlock.jsrScope; int retAddress = scope.nextReturnAddress(); - append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(local, Condition.EQ, ConstantNode.forJsr(retAddress, currentGraph))), RiDeoptReason.JavaSubroutineMismatch))); + append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(local, Condition.EQ, ConstantNode.forJsr(retAddress, currentGraph))), DeoptReason.JavaSubroutineMismatch))); if (!successor.jsrScope.equals(scope.pop())) { throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)"); } @@ -1195,7 +1195,7 @@ private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) { assert probability >= 0 && probability <= 1; if (probability == 0 && GraalOptions.RemoveNeverExecutedCode && profilingInfoConfig.useBranchProbability()) { - return currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.UnreachedCode)); + return currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile, DeoptReason.UnreachedCode)); } else { return createTarget(block, stateAfter); } diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java Thu Mar 15 15:31:34 2012 -0700 @@ -23,11 +23,11 @@ package com.oracle.graal.cri; import com.oracle.graal.graph.*; -import com.oracle.max.cri.ri.*; +import com.oracle.graal.nodes.*; public interface CiLoweringTool { GraalRuntime getRuntime(); Node getGuardAnchor(); - Node createGuard(Node condition, RiDeoptReason deoptReason); + Node createGuard(Node condition, DeoptReason deoptReason); } diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptAction.java Thu Mar 15 15:31:34 2012 -0700 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 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.nodes; + + +public enum DeoptAction { + None, // just interpret, do not invalidate nmethod + RecompileIfTooManyDeopts, // recompile the nmethod; need not invalidate + InvalidateReprofile, // invalidate the nmethod, reset IC, maybe recompile + InvalidateRecompile, // invalidate the nmethod, recompile (probably) + InvalidateStopCompiling; // invalidate the nmethod and do not compile +} diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptReason.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptReason.java Thu Mar 15 15:31:34 2012 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 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.nodes; + + +public enum DeoptReason { + None, + NullCheckException, + BoundsCheckException, + ClassCastException, + ArrayStoreException, + UnreachedCode, + TypeCheckedInliningViolated, + OptimizedTypeCheckViolated, + NotCompiledExceptionHandler, + Unresolved, + JavaSubroutineMismatch, + ArithmeticException, + RuntimeConstraint; +} diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Thu Mar 15 15:31:34 2012 -0700 @@ -25,16 +25,15 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.max.cri.ri.*; @NodeInfo(shortName = "Deopt") public class DeoptimizeNode extends FixedNode implements Node.IterableNodeType, LIRLowerable { @Data private String message; - @Data private final RiDeoptAction action; - @Data private final RiDeoptReason reason; + @Data private final DeoptAction action; + @Data private final DeoptReason reason; - public DeoptimizeNode(RiDeoptAction action, RiDeoptReason reason) { + public DeoptimizeNode(DeoptAction action, DeoptReason reason) { super(StampFactory.illegal()); this.action = action; this.reason = reason; @@ -48,11 +47,11 @@ return message; } - public RiDeoptAction action() { + public DeoptAction action() { return action; } - public RiDeoptReason reason() { + public DeoptReason reason() { return reason; } diff -r 6766253384bf -r 0ebca2e35ca5 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 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Thu Mar 15 15:31:34 2012 -0700 @@ -26,14 +26,13 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.max.cri.ri.*; public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, LIRLowerable { @Input private final NodeInputList conditions; - @Data private final RiDeoptReason deoptReason; + @Data private final DeoptReason deoptReason; - public FixedGuardNode(BooleanNode condition, RiDeoptReason deoptReason) { + public FixedGuardNode(BooleanNode condition, DeoptReason deoptReason) { super(StampFactory.illegal()); this.conditions = new NodeInputList<>(this, new BooleanNode[] {condition}); this.deoptReason = deoptReason; @@ -66,7 +65,7 @@ if (next != null) { tool.deleteBranch(next); } - setNext(graph().add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, deoptReason))); + setNext(graph().add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, deoptReason))); return; } } diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Thu Mar 15 15:31:34 2012 -0700 @@ -25,13 +25,12 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.max.cri.ri.*; public final class GuardNode extends FloatingNode implements Canonicalizable, LIRLowerable { @Input private BooleanNode condition; @Input(notDataflow = true) private FixedNode anchor; - @Data private RiDeoptReason reason; + @Data private DeoptReason reason; public FixedNode anchor() { return anchor; @@ -49,11 +48,11 @@ return condition; } - public RiDeoptReason reason() { + public DeoptReason reason() { return reason; } - public GuardNode(BooleanNode condition, FixedNode anchor, RiDeoptReason reason) { + public GuardNode(BooleanNode condition, FixedNode anchor, DeoptReason reason) { super(StampFactory.illegal()); this.condition = condition; this.anchor = anchor; diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java Thu Mar 15 15:31:34 2012 -0700 @@ -22,12 +22,11 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.graal.cri.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.max.cri.ci.*; public class SafeReadNode extends SafeAccessNode implements Lowerable { @@ -40,7 +39,7 @@ @Override public void lower(CiLoweringTool tool) { StructuredGraph graph = (StructuredGraph) graph(); - GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), RiDeoptReason.NullCheckExceptionn); + GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), DeoptReason.NullCheckException); ReadNode read = graph.add(new ReadNode(kind(), object(), location())); read.setGuard(guard); diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java Tue Mar 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java Thu Mar 15 15:31:34 2012 -0700 @@ -22,12 +22,11 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.graal.cri.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.max.cri.ci.*; public class SafeWriteNode extends SafeAccessNode implements Lowerable{ @@ -46,7 +45,7 @@ @Override public void lower(CiLoweringTool tool) { StructuredGraph graph = (StructuredGraph) graph(); - GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), RiDeoptReason.NullCheckFailed); + GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), DeoptReason.NullCheckException); WriteNode write = graph.add(new WriteNode(object(), value(), location())); write.setGuard(guard); graph.replaceFixedWithFixed(this, write); diff -r 6766253384bf -r 0ebca2e35ca5 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 13 18:53:33 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Mar 15 15:31:34 2012 -0700 @@ -22,12 +22,11 @@ */ package com.oracle.graal.nodes.spi; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.max.cri.ci.*; public abstract class LIRGeneratorTool { public abstract CiTarget target(); @@ -79,12 +78,12 @@ public abstract CiValue emitConvert(ConvertNode.Op opcode, CiValue inputVal); public abstract void emitMembar(int barriers); - public abstract void emitDeoptimizeOn(Condition of, RiDeoptAction action, RiDeoptReason reason, Object deoptInfo); + public abstract void emitDeoptimizeOn(Condition of, DeoptAction action, DeoptReason reason, Object deoptInfo); public abstract CiValue emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args); public abstract void emitIf(IfNode i); public abstract void emitConditional(ConditionalNode i); - public abstract void emitGuardCheck(BooleanNode comp, RiDeoptReason deoptReason); + public abstract void emitGuardCheck(BooleanNode comp, DeoptReason deoptReason); public abstract void emitLookupSwitch(LookupSwitchNode i); public abstract void emitTableSwitch(TableSwitchNode i); diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptAction.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptAction.java Tue Mar 13 18:53:33 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 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.max.cri.ri; - - -public enum RiDeoptAction { - None(0), // just interpret, do not invalidate nmethod - RecompileIfTooManyDeopts(1), // recompile the nmethod; need not invalidate - InvalidateReprofile(2), // invalidate the nmethod, reset IC, maybe recompile - InvalidateRecompile(3), // invalidate the nmethod, recompile (probably) - InvalidateStopCompiling(4); // invalidate the nmethod and do not compile - - private final int value; - - private RiDeoptAction(int value) { - this.value = value; - } - - public int value() { - return value; - } -} diff -r 6766253384bf -r 0ebca2e35ca5 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptReason.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptReason.java Tue Mar 13 18:53:33 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 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.max.cri.ri; - - -public enum RiDeoptReason { - IllegalDeoptReason(0), - Unresolved(1), - UnreachedCode(2), - TypeCheckedInliningViolated(3), - TypeCheckAssumptionViolated(4), - NotCompiledExceptionHandler(5), - JavaSubroutineMismatch(6), - TypeCheckFailed(7), - BoundsCheckFailed(8), - NullCheckFailed(9), - DeoptimizeALot(10); - - private int value; - - private RiDeoptReason(int value) { - this.value = value; - } - - public int value() { - return value; - } -} diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/c1/c1_Runtime1.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -169,7 +169,7 @@ RegisterMap reg_map(thread, false); frame runtime_frame = thread->last_frame(); frame caller_frame = runtime_frame.sender(®_map); - Deoptimization::deoptimize_frame(thread, caller_frame.id()); + Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); assert(caller_is_deopted(), "Must be deoptimized"); } } @@ -434,7 +434,7 @@ if (osr_nm != NULL) { RegisterMap map(thread, false); frame fr = thread->last_frame().sender(&map); - Deoptimization::deoptimize_frame(thread, fr.id()); + Deoptimization::deoptimize_frame(thread, fr.id(), Deoptimization::Reason_constraint); } JRT_BLOCK_END return NULL; @@ -505,7 +505,7 @@ // We don't really want to deoptimize the nmethod itself since we // can actually continue in the exception handler ourselves but I // don't see an easy way to have the desired effect. - Deoptimization::deoptimize_frame(thread, caller_frame.id()); + Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); assert(caller_is_deopted(), "Must be deoptimized"); return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); @@ -763,7 +763,7 @@ assert(CodeCache::find_nmethod(caller_frame.pc()) != NULL, "sanity"); // Deoptimize the caller frame. - Deoptimization::deoptimize_frame(thread, caller_frame.id()); + Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); // Return to the now deoptimized frame. JRT_END @@ -975,7 +975,7 @@ nm->make_not_entrant(); } - Deoptimization::deoptimize_frame(thread, caller_frame.id()); + Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); // Return to the now deoptimized frame. } diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/prims/jvmtiEnv.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -1457,7 +1457,7 @@ // If any of the top 2 frames is a compiled one, need to deoptimize it for (int i = 0; i < 2; i++) { if (!is_interpreted[i]) { - Deoptimization::deoptimize_frame(java_thread, frame_sp[i]); + Deoptimization::deoptimize_frame(java_thread, frame_sp[i], Deoptimization::Reason_constraint); } } diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/prims/jvmtiEnvBase.cpp --- a/src/share/vm/prims/jvmtiEnvBase.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -1340,7 +1340,7 @@ if (!vf->fr().can_be_deoptimized()) { return JVMTI_ERROR_OPAQUE_FRAME; } - Deoptimization::deoptimize_frame(java_thread, jvf->fr().id()); + Deoptimization::deoptimize_frame(java_thread, jvf->fr().id(), Deoptimization::Reason_constraint); } // Get information about method return type diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/prims/jvmtiImpl.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -767,7 +767,7 @@ // Schedule deoptimization so that eventually the local // update will be written to an interpreter frame. - Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id()); + Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id(), Deoptimization::Reason_constraint); // Now store a new value for the local which will be applied // once deoptimization occurs. Note however that while this diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/deoptimization.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -1133,17 +1133,17 @@ } -void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr) { +void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) { assert(fr.can_be_deoptimized(), "checking frame type"); - gather_statistics(Reason_constraint, Action_none, Bytecodes::_illegal); + gather_statistics(reason, Action_none, Bytecodes::_illegal); // Patch the nmethod so that when execution returns to it we will // deopt the execution state and return to the interpreter. fr.deoptimize(thread); } -void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) { +void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) { // Deoptimize only if the frame comes from compile code. // Do not deoptimize the frame which is already patched // during the execution of the loops below. @@ -1155,12 +1155,12 @@ if (UseBiasedLocking) { revoke_biases_of_monitors(thread, fr, map); } - deoptimize_single_frame(thread, fr); + deoptimize_single_frame(thread, fr, reason); } -void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id) { +void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason) { assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(), "can only deoptimize other thread at a safepoint"); // Compute frame and register map based on thread and sp. @@ -1169,15 +1169,15 @@ while (fr.id() != id) { fr = fr.sender(®_map); } - deoptimize(thread, fr, ®_map); + deoptimize(thread, fr, ®_map, reason); } -void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { +void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason) { if (thread == Thread::current()) { - Deoptimization::deoptimize_frame_internal(thread, id); + Deoptimization::deoptimize_frame_internal(thread, id, reason); } else { - VM_DeoptimizeFrame deopt(thread, id); + VM_DeoptimizeFrame deopt(thread, id, reason); VMThread::execute(&deopt); } } @@ -1813,6 +1813,21 @@ Deoptimization::DeoptAction Deoptimization::_unloaded_action = Deoptimization::Action_reinterpret; const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { +#ifdef GRAAL + "none", + "null_check", + "range_check", + "class_check", + "array_check", + "unreached", + "type_checked_inlining", + "optimized_type_check", + "not_compiled_exception_handler", + "unresolved", + "jsr_mismatch", + "div0_check", + "constraint" +#else // Note: Keep this in sync. with enum DeoptReason. "none", "null_check", @@ -1831,6 +1846,7 @@ "age", "predicate", "loop_limit_check" +#endif }; const char* Deoptimization::_trap_action_name[Action_LIMIT] = { // Note: Keep this in sync. with enum DeoptAction. diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/deoptimization.hpp Thu Mar 15 15:31:34 2012 -0700 @@ -37,8 +37,29 @@ friend class VMStructs; public: - // What condition caused the deoptimization? + // What condition caused the deoptimization enum DeoptReason { +#ifdef GRAAL + Reason_many = -1, // indicates presence of several reasons + Reason_none = 0, // indicates absence of a relevant deopt. + // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits + Reason_null_check, + Reason_range_check, + Reason_class_check, + Reason_array_check, + Reason_unreached, + Reason_type_checked_inlining, + Reason_optimized_type_check, + + // recorded per method + Reason_not_compiled_exception_handler, + Reason_unresolved, + Reason_jsr_mismatch, + Reason_div0_check, + Reason_constraint, + Reason_LIMIT, + Reason_RECORDED_LIMIT = Reason_optimized_type_check +#else Reason_many = -1, // indicates presence of several reasons Reason_none = 0, // indicates absence of a relevant deopt. // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits @@ -50,7 +71,7 @@ Reason_intrinsic, // saw unexpected operand to intrinsic (@bci) Reason_bimorphic, // saw unexpected object class in bimorphic inlining (@bci) - Reason_unloaded, // unloaded class or constant pool entry + Reason_unloaded, // unloaded or class constant pool entry Reason_uninitialized, // bad class state (uninitialized) Reason_unreached, // code is not reached, compiler Reason_unhandled, // arbitrary compiler limitation @@ -62,10 +83,11 @@ Reason_LIMIT, // Note: Keep this enum in sync. with _trap_reason_name. Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc +#endif // Note: Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of // DataLayout::trap_bits. This dependency is enforced indirectly // via asserts, to avoid excessive direct header-to-header dependencies. - // See Deoptimization::trap_state_reason and class DataLayout. + // See Deoptimization::trap_state_reason and class DataLayout }; // What action must be taken by the runtime? @@ -99,11 +121,11 @@ static int deoptimize_dependents(); // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame - static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map); + static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason); private: // Does the actual work for deoptimizing a single frame - static void deoptimize_single_frame(JavaThread* thread, frame fr); + static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason); // Helper function to revoke biases of all monitors in frame if UseBiasedLocking // is enabled @@ -233,11 +255,11 @@ // Only called from VMDeoptimizeFrame // @argument thread. Thread where stub_frame resides. // @argument id. id of frame that should be deoptimized. - static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id); + static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason); - // If thread is not the current thread then execute + // if thread is not the current thread then execute // VM_DeoptimizeFrame otherwise deoptimize directly. - static void deoptimize_frame(JavaThread* thread, intptr_t* id); + static void deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason); // Statistics static void gather_statistics(DeoptReason reason, DeoptAction action, @@ -251,37 +273,60 @@ // trap_request codes static DeoptReason trap_request_reason(int trap_request) { - if (trap_request < 0) + if (trap_request < 0) { return (DeoptReason) ((~(trap_request) >> _reason_shift) & right_n_bits(_reason_bits)); - else + } else { +#ifdef GRAAL + ShouldNotReachHere(); + return Reason_none; +#else // standard reason for unloaded CP entry return Reason_unloaded; +#endif // GRAAL + } } static DeoptAction trap_request_action(int trap_request) { - if (trap_request < 0) + if (trap_request < 0) { return (DeoptAction) ((~(trap_request) >> _action_shift) & right_n_bits(_action_bits)); - else + } else { +#ifdef GRAAL + ShouldNotReachHere(); + return Action_make_not_compilable; +#else // standard action for unloaded CP entry return _unloaded_action; +#endif // GRAAL + } } static int trap_request_index(int trap_request) { - if (trap_request < 0) + if (trap_request < 0) { return -1; - else + } else { +#ifdef GRAAL + ShouldNotReachHere(); + return -1; +#else return trap_request; +#endif // GRAAL + } } static int make_trap_request(DeoptReason reason, DeoptAction action, int index = -1) { +#ifdef GRAAL + assert(index == -1, "Graal does not use index"); +#endif + assert((1 << _reason_bits) >= Reason_LIMIT, "enough bits"); assert((1 << _action_bits) >= Action_LIMIT, "enough bits"); int trap_request; - if (index != -1) + if (index != -1) { trap_request = index; - else + } else { trap_request = (~(((reason) << _reason_shift) + ((action) << _action_shift))); + } assert(reason == trap_request_reason(trap_request), "valid reason"); assert(action == trap_request_action(trap_request), "valid action"); assert(index == trap_request_index(trap_request), "valid index"); diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/safepoint.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -1060,7 +1060,7 @@ // as otherwise we may never deliver it. if (thread()->has_async_condition()) { ThreadInVMfromJavaNoAsyncException __tiv(thread()); - Deoptimization::deoptimize_frame(thread(), caller_fr.id()); + Deoptimization::deoptimize_frame(thread(), caller_fr.id(), Deoptimization::Reason_constraint); } // If an exception has been installed we must check for a pending deoptimization diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/sharedRuntime.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -665,7 +665,7 @@ RegisterMap reg_map(thread); frame runtime_frame = thread->last_frame(); frame caller_frame = runtime_frame.sender(®_map); - Deoptimization::deoptimize_frame(thread, caller_frame.id()); + Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_not_compiled_exception_handler); return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); } diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/thread.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -2058,7 +2058,7 @@ RegisterMap reg_map(this, UseBiasedLocking); frame compiled_frame = f.sender(®_map); if (compiled_frame.can_be_deoptimized()) { - Deoptimization::deoptimize(this, compiled_frame, ®_map); + Deoptimization::deoptimize(this, compiled_frame, ®_map, Deoptimization::Reason_constraint); } } } @@ -2520,7 +2520,7 @@ StackFrameStream fst(this, UseBiasedLocking); for(; !fst.is_done(); fst.next()) { if (fst.current()->should_be_deoptimized()) { - Deoptimization::deoptimize(this, *fst.current(), fst.register_map()); + Deoptimization::deoptimize(this, *fst.current(), fst.register_map(), Deoptimization::Reason_constraint); } } } diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/vmStructs.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -2455,21 +2455,26 @@ declare_constant(Deoptimization::Reason_many) \ declare_constant(Deoptimization::Reason_none) \ declare_constant(Deoptimization::Reason_null_check) \ - declare_constant(Deoptimization::Reason_null_assert) \ + /*declare_constant(Deoptimization::Reason_null_assert)*/ \ declare_constant(Deoptimization::Reason_range_check) \ declare_constant(Deoptimization::Reason_class_check) \ declare_constant(Deoptimization::Reason_array_check) \ - declare_constant(Deoptimization::Reason_intrinsic) \ - declare_constant(Deoptimization::Reason_bimorphic) \ - declare_constant(Deoptimization::Reason_unloaded) \ - declare_constant(Deoptimization::Reason_uninitialized) \ + /*declare_constant(Deoptimization::Reason_intrinsic)*/ \ + /*declare_constant(Deoptimization::Reason_bimorphic)*/ \ + /*declare_constant(Deoptimization::Reason_unloaded)*/ \ + /*declare_constant(Deoptimization::Reason_uninitialized) */ \ declare_constant(Deoptimization::Reason_unreached) \ - declare_constant(Deoptimization::Reason_unhandled) \ + /*declare_constant(Deoptimization::Reason_unhandled)*/ \ declare_constant(Deoptimization::Reason_constraint) \ declare_constant(Deoptimization::Reason_div0_check) \ - declare_constant(Deoptimization::Reason_age) \ - declare_constant(Deoptimization::Reason_predicate) \ - declare_constant(Deoptimization::Reason_loop_limit_check) \ + /*declare_constant(Deoptimization::Reason_age)*/ \ + /*declare_constant(Deoptimization::Reason_predicate)*/ \ + /*declare_constant(Deoptimization::Reason_loop_limit_check)*/ \ + declare_constant(Deoptimization::Reason_type_checked_inlining) \ + declare_constant(Deoptimization::Reason_optimized_type_check) \ + declare_constant(Deoptimization::Reason_not_compiled_exception_handler) \ + declare_constant(Deoptimization::Reason_unresolved) \ + declare_constant(Deoptimization::Reason_jsr_mismatch) \ declare_constant(Deoptimization::Reason_LIMIT) \ declare_constant(Deoptimization::Reason_RECORDED_LIMIT) \ \ diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/vm_operations.cpp --- a/src/share/vm/runtime/vm_operations.cpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/vm_operations.cpp Thu Mar 15 15:31:34 2012 -0700 @@ -117,14 +117,16 @@ } -VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id) { +VM_DeoptimizeFrame::VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason) { _thread = thread; _id = id; + _reason = reason; } void VM_DeoptimizeFrame::doit() { - Deoptimization::deoptimize_frame_internal(_thread, _id); + assert(_reason > Deoptimization::Reason_none && _reason < Deoptimization::DeoptReason.Reason_LIMIT, "invalid deopt reason"); + Deoptimization::deoptimize_frame_internal(_thread, _id, (Deoptimization::DeoptReason)_reason); } diff -r 6766253384bf -r 0ebca2e35ca5 src/share/vm/runtime/vm_operations.hpp --- a/src/share/vm/runtime/vm_operations.hpp Tue Mar 13 18:53:33 2012 -0700 +++ b/src/share/vm/runtime/vm_operations.hpp Thu Mar 15 15:31:34 2012 -0700 @@ -251,7 +251,8 @@ private: JavaThread* _thread; intptr_t* _id; - VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id); + int _reason; + VM_DeoptimizeFrame(JavaThread* thread, intptr_t* id, int reason); public: VMOp_Type type() const { return VMOp_DeoptimizeFrame; }