changeset 5110:0ebca2e35ca5

more preparations for disabling runtime feedback selectively based on deoptimization history
author Christian Haeubl <christian.haeubl@oracle.com>
date Thu, 15 Mar 2012 15:31:34 -0700
parents 6766253384bf
children 422c979ff392
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptAction.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptReason.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptAction.java graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptReason.java src/share/vm/c1/c1_Runtime1.cpp src/share/vm/prims/jvmtiEnv.cpp src/share/vm/prims/jvmtiEnvBase.cpp src/share/vm/prims/jvmtiImpl.cpp src/share/vm/runtime/deoptimization.cpp src/share/vm/runtime/deoptimization.hpp src/share/vm/runtime/safepoint.cpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/vmStructs.cpp src/share/vm/runtime/vm_operations.cpp src/share/vm/runtime/vm_operations.hpp
diffstat 31 files changed, 296 insertions(+), 215 deletions(-) [+]
line wrap: on
line diff
--- 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) {
--- 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()) {
--- 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();
+        }
     }
 }
--- 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);
--- 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<ValueNode> 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)));
         }
     }
 }
--- 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
--- 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();
             }
--- 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);
         }
--- 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);
 }
 
--- /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
+}
--- /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;
+}
--- 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;
     }
 
--- 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<BooleanNode> 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;
                 }
             }
--- 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;
--- 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);
 
--- 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);
--- 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);
--- 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;
-    }
-}
--- 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;
-    }
-}
--- 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(&reg_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.
   }
--- 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);
       }
     }
 
--- 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
--- 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
--- 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(&reg_map);
   }
-  deoptimize(thread, fr, &reg_map);
+  deoptimize(thread, fr, &reg_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.
--- 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");
--- 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
--- 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(&reg_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();
   }
 
--- 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(&reg_map);
           if (compiled_frame.can_be_deoptimized()) {
-            Deoptimization::deoptimize(this, compiled_frame, &reg_map);
+            Deoptimization::deoptimize(this, compiled_frame, &reg_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);
     }
   }
 }
--- 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)                 \
                                                                           \
--- 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);
 }
 
 
--- 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; }