changeset 5737:f2fc4d13975a

Merge.
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 27 Jun 2012 17:35:32 +0200
parents f96e7b39e9fe (diff) 915952ed97c0 (current diff)
children 50dbe728da9e
files
diffstat 636 files changed, 37729 insertions(+), 25205 deletions(-) [+]
line wrap: on
line diff
--- a/GRAAL_AUTHORS	Wed Jun 27 11:48:26 2012 +0200
+++ b/GRAAL_AUTHORS	Wed Jun 27 17:35:32 2012 +0200
@@ -1,20 +1,7 @@
-Doug Simon (doug.simon@oracle.com)
-* Since December 2011
-
-Christian Wimmer (christian.wimmer@oracle.com)
-* Since December 2011
-
-Lukas Stadler (stadler@ssw.jku.at)
-* July - September 2010: Initial feature-complete implementation, remote compilation
-* Since April 2011: New IR design
-
-Gilles Duboscq (gilles.duboscq@oracle.com)
-* Since April 2011: New IR design
-
-Peter Hofer (hofer@ssw.jku.at)
-* Since May 2011: Graphviz visualization
-
-Thomas Wuerthinger (thomas.wuerthinger@oracle.com)
-* June 2011: Initial prototype
-* October 2010 - January 2011: Bug fixes (all DaCapo's pass), better performance on SciMark than C1
-* Since April 2011: New IR design
+Gilles Duboscq (gdub)
+Peter Hofer
+Christian Humer (chumer)
+Christian Wimmer (cwimmer)
+Doug Simon (dnsimon)
+Lukas Stadler (lstadler)
+Thomas Wuerthinger (thomaswue)
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/AssignRegisters.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/AssignRegisters.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,10 @@
 
 import static com.oracle.graal.alloc.util.LocationUtil.*;
 
-import com.oracle.max.cri.ci.*;
+import java.util.*;
+
 import com.oracle.graal.alloc.util.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.*;
@@ -40,13 +42,13 @@
         this.frameMap = frameMap;
     }
 
-    private CiBitMap curRegisterRefMap;
-    private CiBitMap curFrameRefMap;
+    private BitSet curRegisterRefMap;
+    private BitSet curFrameRefMap;
 
     public void execute() {
-        ValueProcedure useProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value); } };
-        ValueProcedure defProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value); } };
-        ValueProcedure setReferenceProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setReference(value); } };
+        ValueProcedure useProc =          new ValueProcedure() { @Override public Value doValue(Value value) { return use(value); } };
+        ValueProcedure defProc =          new ValueProcedure() { @Override public Value doValue(Value value) { return def(value); } };
+        ValueProcedure setReferenceProc = new ValueProcedure() { @Override public Value doValue(Value value) { return setReference(value); } };
 
         Debug.log("==== start assign registers ====");
         for (int i = lir.linearScanOrder().size() - 1; i >= 0; i--) {
@@ -70,12 +72,12 @@
 
                 if (op.info != null) {
                     Debug.log("    registerRefMap: %s  frameRefMap: %s", curRegisterRefMap, curFrameRefMap);
-                    op.info.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
+                    op.info.finish((BitSet) (curRegisterRefMap.clone()), (BitSet) (curFrameRefMap.clone()), frameMap);
 
                     if (op instanceof LIRXirInstruction) {
                         LIRXirInstruction xir = (LIRXirInstruction) op;
                         if (xir.infoAfter != null) {
-                            xir.infoAfter.finish(new CiBitMap(curRegisterRefMap), new CiBitMap(curFrameRefMap), frameMap);
+                            xir.infoAfter.finish((BitSet) (curRegisterRefMap.clone()), (BitSet) (curFrameRefMap.clone()), frameMap);
                         }
                     }
                 }
@@ -89,10 +91,10 @@
         Debug.log("==== end assign registers ====");
     }
 
-    private CiValue use(CiValue value) {
+    private Value use(Value value) {
         Debug.log("    use %s", value);
         if (isLocation(value)) {
-            CiValue location = asLocation(value).location;
+            Value location = asLocation(value).location;
             frameMap.setReference(location, curRegisterRefMap, curFrameRefMap);
             return location;
         } else {
@@ -101,10 +103,10 @@
         }
     }
 
-    private CiValue def(CiValue value) {
+    private Value def(Value value) {
         Debug.log("    def %s", value);
         if (isLocation(value)) {
-            CiValue location = asLocation(value).location;
+            Value location = asLocation(value).location;
             frameMap.clearReference(location, curRegisterRefMap, curFrameRefMap);
             return location;
         } else {
@@ -113,7 +115,7 @@
         }
     }
 
-    private CiValue setReference(CiValue value) {
+    private Value setReference(Value value) {
         Debug.log("    setReference %s", value);
         frameMap.setReference(asLocation(value).location, curRegisterRefMap, curFrameRefMap);
         return value;
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/DataFlowAnalysis.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/DataFlowAnalysis.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.alloc.simple;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.graal.lir.ValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.*;
@@ -36,9 +36,9 @@
 
 public class DataFlowAnalysis {
     private final LIR lir;
-    private final RiRegisterConfig registerConfig;
+    private final RegisterConfig registerConfig;
 
-    public DataFlowAnalysis(LIR lir, RiRegisterConfig registerConfig) {
+    public DataFlowAnalysis(LIR lir, RegisterConfig registerConfig) {
         this.lir = lir;
         this.registerConfig = registerConfig;
     }
@@ -57,8 +57,8 @@
         return lir.numVariables();
     }
 
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    private boolean isAllocatableRegister(Value value) {
+        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable();
     }
 
 
@@ -93,14 +93,14 @@
         Object entry = killedValues(op.id() + (end ? 1 : 0));
         if (entry == null) {
             // Nothing to do
-        } else if (entry instanceof CiValue) {
-            CiValue newValue = proc.doValue((CiValue) entry, null, null);
+        } else if (entry instanceof Value) {
+            Value newValue = proc.doValue((Value) entry, null, null);
             assert newValue == entry : "procedure does not allow to change values";
         } else {
-            CiValue[] values = (CiValue[]) entry;
+            Value[] values = (Value[]) entry;
             for (int i = 0; i < values.length; i++) {
                 if (values[i] != null) {
-                    CiValue newValue = proc.doValue(values[i], null, null);
+                    Value newValue = proc.doValue(values[i], null, null);
                     assert newValue == values[i] : "procedure does not allow to change values";
                 }
             }
@@ -115,7 +115,7 @@
      * Numbers all instructions in all blocks. The numbering follows the {@linkplain ComputeLinearScanOrder linear scan order}.
      */
     private void numberInstructions() {
-        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return setDef(value); } };
+        ValueProcedure defProc = new ValueProcedure() { @Override public Value doValue(Value value) { return setDef(value); } };
 
         int numInstructions = 0;
         for (Block block : blocks()) {
@@ -140,7 +140,7 @@
         assert curOpId == numInstructions << 1;
     }
 
-    private CiValue setDef(CiValue value) {
+    private Value setDef(Value value) {
         if (isVariable(value)) {
             assert definitions[asVariable(value).index] == 0 : "Variable defined twice";
             definitions[asVariable(value).index] = curOpId;
@@ -154,10 +154,10 @@
     private int curOpId;
 
     private void backwardDataFlow() {
-        ValueProcedure inputProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId); } };
-        ValueProcedure aliveProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return use(value, curOpId + 1); } };
-        ValueProcedure tempProc =     new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, true); } };
-        ValueProcedure outputProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return def(value, false); } };
+        ValueProcedure inputProc =    new ValueProcedure() { @Override public Value doValue(Value value) { return use(value, curOpId); } };
+        ValueProcedure aliveProc =    new ValueProcedure() { @Override public Value doValue(Value value) { return use(value, curOpId + 1); } };
+        ValueProcedure tempProc =     new ValueProcedure() { @Override public Value doValue(Value value) { return def(value, true); } };
+        ValueProcedure outputProc =   new ValueProcedure() { @Override public Value doValue(Value value) { return def(value, false); } };
 
         blockLiveIn = new BitSet[blocks().size()];
         registerLive = new BitSet();
@@ -211,7 +211,7 @@
         Debug.log("==== end backward data flow analysis ====");
     }
 
-    private CiValue use(CiValue value, int killOpId) {
+    private Value use(Value value, int killOpId) {
         Debug.log("    use %s", value);
         if (isVariable(value)) {
             int variableIdx = asVariable(value).index;
@@ -233,7 +233,7 @@
         return value;
     }
 
-    private CiValue def(CiValue value, boolean isTemp) {
+    private Value def(Value value, boolean isTemp) {
         Debug.log("    def %s", value);
         if (isVariable(value)) {
             int variableIdx = asVariable(value).index;
@@ -261,7 +261,7 @@
         return value;
     }
 
-    private void kill(CiValue value, int opId) {
+    private void kill(Value value, int opId) {
         if (opId < 0) {
             return;
         }
@@ -284,10 +284,10 @@
         Object entry = killedValues(opId);
         if (entry == null) {
             setKilledValues(opId, value);
-        } else if (entry instanceof CiValue) {
-            setKilledValues(opId, new CiValue[] {(CiValue) entry, value});
+        } else if (entry instanceof Value) {
+            setKilledValues(opId, new Value[] {(Value) entry, value});
         } else {
-            CiValue[] killed = (CiValue[]) entry;
+            Value[] killed = (Value[]) entry;
             for (int i = 0; i < killed.length; i++) {
                 if (killed[i] == null) {
                     killed[i] = value;
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/LinearScanAllocator.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/LinearScanAllocator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,13 @@
  */
 package com.oracle.graal.alloc.simple;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.graal.alloc.util.LocationUtil.*;
-
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
 import com.oracle.graal.alloc.util.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
@@ -60,17 +59,17 @@
         }
 
         @Override
-        protected CiValue scratchRegister(Variable spilled) {
+        protected Value scratchRegister(Variable spilled) {
             GraalInternalError.shouldNotReachHere("needs working implementation");
 
-            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
-            for (CiRegister reg : availableRegs) {
+            EnumMap<RegisterFlag, Register[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+            Register[] availableRegs = categorizedRegs.get(spilled.flag);
+            for (Register reg : availableRegs) {
                 if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
                     return reg.asValue(spilled.kind);
                 }
             }
-            throw new CiBailout("No register found");
+            throw new BailoutException("No register found");
         }
     }
 
@@ -106,8 +105,8 @@
         return frameMap.target.arch.registers.length;
     }
 
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    private boolean isAllocatableRegister(Value value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable();
     }
 
 
@@ -141,8 +140,8 @@
 
     private MoveResolver moveResolver;
     private LocationMap curLocations;
-    private CiValue[] curInRegisterState;
-    private CiValue[] curOutRegisterState;
+    private Value[] curInRegisterState;
+    private Value[] curOutRegisterState;
     private BitSet curLiveIn;
     private LIRInstruction curOp;
 
@@ -181,19 +180,19 @@
     }
 
     private void allocate() {
-        ValueProcedure recordUseProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return recordUse(value); } };
-        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
-        ValueProcedure unblockProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return unblock(value); } };
-        ValueProcedure killProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value); } };
-        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
-        ValueProcedure useProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
-        ValueProcedure defProc =          new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
+        ValueProcedure recordUseProc =    new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return recordUse(value); } };
+        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public Value doValue(Value value) { return killNonLive(value); } };
+        ValueProcedure unblockProc =      new ValueProcedure() { @Override public Value doValue(Value value) { return unblock(value); } };
+        ValueProcedure killProc =         new ValueProcedure() { @Override public Value doValue(Value value) { return kill(value); } };
+        ValueProcedure blockProc =        new ValueProcedure() { @Override public Value doValue(Value value) { return block(value); } };
+        ValueProcedure useProc =          new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
+        ValueProcedure defProc =          new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
 
         Debug.log("==== start linear scan allocation ====");
         canonicalSpillLocations = new LocationMap(lir.numVariables());
         hintRegisterLocations = new LocationMap(lir.numVariables());
-        curInRegisterState = new CiValue[maxRegisterNum()];
-        curOutRegisterState = new CiValue[maxRegisterNum()];
+        curInRegisterState = new Value[maxRegisterNum()];
+        curOutRegisterState = new Value[maxRegisterNum()];
         for (Block block : lir.linearScanOrder()) {
             Debug.log("start block %s %s", block, block.getLoop());
 
@@ -273,7 +272,7 @@
         Debug.log("==== end linear scan allocation ====");
     }
 
-    private CiValue killNonLive(CiValue value) {
+    private Value killNonLive(Value value) {
         assert isLocation(value);
         if (!curLiveIn.get(asLocation(value).variable.index)) {
             return null;
@@ -286,7 +285,7 @@
         return value;
     }
 
-    private CiValue unblock(CiValue value) {
+    private Value unblock(Value value) {
         if (isAllocatableRegister(value)) {
             Debug.log("    unblock register %s", value);
             int regNum = asRegister(value).number;
@@ -296,7 +295,7 @@
         return value;
     }
 
-    private CiValue kill(CiValue value) {
+    private Value kill(Value value) {
         if (isVariable(value)) {
             Location location = curLocations.get(asVariable(value));
             Debug.log("    kill location %s", location);
@@ -312,7 +311,7 @@
     }
 
 
-    private CiValue block(CiValue value) {
+    private Value block(Value value) {
         if (isAllocatableRegister(value)) {
             Debug.log("    block %s", value);
             int regNum = asRegister(value).number;
@@ -324,15 +323,15 @@
 
     private void spillCallerSaveRegisters() {
         Debug.log("    spill caller save registers in curInRegisterState %s", Arrays.toString(curInRegisterState));
-        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
-            CiValue in = curInRegisterState[reg.number];
+        for (Register reg : frameMap.registerConfig.getCallerSaveRegisters()) {
+            Value in = curInRegisterState[reg.number];
             if (in != null && isLocation(in)) {
                 spill(asLocation(in));
             }
         }
     }
 
-    private CiValue recordUse(CiValue value) {
+    private Value recordUse(Value value) {
         if (isVariable(value)) {
             assert lastUseFor(asVariable(value)) <= curOp.id();
             setLastUseFor(asVariable(value), curOp.id());
@@ -341,7 +340,7 @@
         return value;
     }
 
-    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private Value use(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         assert mode == OperandMode.Input || mode == OperandMode.Alive;
         if (isVariable(value)) {
             // State values are not recorded beforehand because it does not matter if they are spilled. Still, it is necessary to record them as used now.
@@ -376,7 +375,7 @@
 
     private static final EnumSet<OperandFlag> SPILL_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
 
-    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private Value def(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         assert mode == OperandMode.Temp || mode == OperandMode.Output;
         if (isVariable(value)) {
             Debug.log("    def %s %s", mode, value);
@@ -391,8 +390,8 @@
 
     private void fixupEvicted() {
         for (int i = 0; i < curInRegisterState.length; i++) {
-            CiValue in = curInRegisterState[i];
-            CiValue out = curOutRegisterState[i];
+            Value in = curInRegisterState[i];
+            Value out = curOutRegisterState[i];
 
             if (in != null && in != out && isLocation(in) && curLocations.get(asLocation(in).variable) == in) {
                 Debug.log("    %s was evicted by %s, need to allocate new location", in, out);
@@ -409,13 +408,13 @@
 
     private void phiRegisterHints(Block block) {
         Debug.log("    phi register hints for %s", block);
-        CiValue[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions();
+        Value[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions();
         for (Block pred : block.getPredecessors()) {
-            CiValue[] phiInputs = ((StandardOp.PhiJumpOp) pred.lir.get(pred.lir.size() - 1)).getPhiInputs();
+            Value[] phiInputs = ((StandardOp.PhiJumpOp) pred.lir.get(pred.lir.size() - 1)).getPhiInputs();
 
             for (int i = 0; i < phiDefinitions.length; i++) {
-                CiValue phiDefinition = phiDefinitions[i];
-                CiValue phiInput = phiInputs[i];
+                Value phiDefinition = phiDefinitions[i];
+                Value phiInput = phiInputs[i];
 
                 if (isVariable(phiDefinition)) {
                     Location hintResult = processRegisterHint(asVariable(phiDefinition), OperandMode.Output, phiInput);
@@ -427,12 +426,12 @@
         }
     }
 
-    private Location processRegisterHint(Variable variable, OperandMode mode, CiValue registerHint) {
+    private Location processRegisterHint(Variable variable, OperandMode mode, Value registerHint) {
         if (registerHint == null) {
             return null;
         }
         Debug.log("      try registerHint for %s %s: %s", mode, variable, registerHint);
-        CiRegister hint = null;
+        Register hint = null;
         if (isRegister(registerHint)) {
             hint = asRegister(registerHint);
         } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
@@ -446,9 +445,9 @@
 
     private Location allocateRegister(final Variable variable, final OperandMode mode, EnumSet<OperandFlag> flags) {
         if (flags.contains(OperandFlag.RegisterHint)) {
-            CiValue hintResult = curOp.forEachRegisterHint(variable, mode, new ValueProcedure() {
+            Value hintResult = curOp.forEachRegisterHint(variable, mode, new ValueProcedure() {
                 @Override
-                public CiValue doValue(CiValue registerHint) {
+                public Value doValue(Value registerHint) {
                     return processRegisterHint(variable, mode, registerHint);
                 }
             });
@@ -457,16 +456,16 @@
             }
         }
 
-        CiValue hintResult = processRegisterHint(variable, mode, hintRegisterLocations.get(variable));
+        Value hintResult = processRegisterHint(variable, mode, hintRegisterLocations.get(variable));
         if (hintResult != null) {
             return asLocation(hintResult);
         }
 
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
+        EnumMap<RegisterFlag, Register[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        Register[] availableRegs = categorizedRegs.get(variable.flag);
 
         Location bestSpillCandidate = null;
-        for (CiRegister reg : availableRegs) {
+        for (Register reg : availableRegs) {
             if (isFree(reg, mode)) {
                 return selectRegister(reg, variable, mode);
             } else {
@@ -500,7 +499,7 @@
         }
         curLocations.put(newLoc);
 
-        CiRegister reg = asRegister(value.location);
+        Register reg = asRegister(value.location);
         assert curInRegisterState[reg.number] == value;
         curInRegisterState[reg.number] = null;
         if (curOutRegisterState[reg.number] == value) {
@@ -508,7 +507,7 @@
         }
     }
 
-    private boolean isFree(CiRegister reg, OperandMode mode) {
+    private boolean isFree(Register reg, OperandMode mode) {
         switch (mode) {
             case Input:  return curInRegisterState[reg.number] == null;
             case Alive:  return curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null;
@@ -518,9 +517,9 @@
         }
     }
 
-    private Location spillCandidate(CiRegister reg) {
-        CiValue in = curInRegisterState[reg.number];
-        CiValue out = curOutRegisterState[reg.number];
+    private Location spillCandidate(Register reg) {
+        Value in = curInRegisterState[reg.number];
+        Value out = curOutRegisterState[reg.number];
         if (in == out && in != null && isLocation(in) && lastUseFor(asLocation(in).variable) < curOp.id()) {
             return asLocation(in);
         }
@@ -549,7 +548,7 @@
         return result;
     }
 
-    private Location selectRegister(CiRegister reg, Variable variable, OperandMode mode) {
+    private Location selectRegister(Register reg, Variable variable, OperandMode mode) {
         assert isFree(reg, mode);
 
         Location loc = new Location(variable, reg.asValue(variable.kind));
@@ -580,7 +579,7 @@
         final BitSet liveState = new BitSet();
         curLocations.forEachLocation(new ValueProcedure() {
             @Override
-            public CiValue doValue(CiValue value) {
+            public Value doValue(Value value) {
                 liveState.set(asLocation(value).variable.index);
 
                 for (Block pred : block.getPredecessors()) {
@@ -604,7 +603,7 @@
         sb.append("  current lcoations: ");
         curLocations.forEachLocation(new ValueProcedure() {
             @Override
-            public CiValue doValue(CiValue value) {
+            public Value doValue(Value value) {
                 sb.append(value).append(" ");
                 return value;
             }
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/ResolveDataFlow.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/ResolveDataFlow.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,8 +26,8 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.graal.alloc.util.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
@@ -49,7 +49,7 @@
     private LocationMap curFromLocations;
 
     public void execute() {
-        ValueProcedure locMappingProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return locMapping(value); } };
+        ValueProcedure locMappingProc = new ValueProcedure() { @Override public Value doValue(Value value) { return locMapping(value); } };
 
         Debug.log("==== start resolve data flow ====");
         for (Block toBlock : lir.linearScanOrder()) {
@@ -87,7 +87,7 @@
         Debug.log("==== end resolve data flow ====");
     }
 
-    private CiValue locMapping(CiValue value) {
+    private Value locMapping(Value value) {
         Location to = asLocation(value);
         Location from = curFromLocations.get(to.variable);
         if (value != from && from != null) {
@@ -96,7 +96,7 @@
         return value;
     }
 
-    private void phiMapping(CiValue[] inputs, CiValue[] outputs) {
+    private void phiMapping(Value[] inputs, Value[] outputs) {
         assert inputs.length == outputs.length;
         for (int i = 0; i < inputs.length; i++) {
             if (inputs[i] != outputs[i]) {
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/SpillAllAllocator.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/simple/SpillAllAllocator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,13 @@
  */
 package com.oracle.graal.alloc.simple;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.graal.alloc.util.LocationUtil.*;
-
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
 import com.oracle.graal.alloc.util.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
@@ -57,15 +56,15 @@
         }
 
         @Override
-        protected CiValue scratchRegister(Variable spilled) {
-            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-            CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
-            for (CiRegister reg : availableRegs) {
+        protected Value scratchRegister(Variable spilled) {
+            EnumMap<RegisterFlag, Register[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+            Register[] availableRegs = categorizedRegs.get(spilled.flag);
+            for (Register reg : availableRegs) {
                 if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
                     return reg.asValue(spilled.kind);
                 }
             }
-            throw new CiBailout("No register found");
+            throw new BailoutException("No register found");
         }
     }
 
@@ -102,8 +101,8 @@
         return frameMap.target.arch.registers.length;
     }
 
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    private boolean isAllocatableRegister(Value value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable();
     }
 
 
@@ -149,14 +148,14 @@
     }
 
     private void allocate() {
-        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killNonLive(value); } };
-        ValueProcedure killBeginProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, false); } };
-        ValueProcedure killEndProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return kill(value, true); } };
-        ValueProcedure killLocationProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return killLocation(value); } };
-        ValueProcedure blockProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return block(value); } };
-        ValueProcedure loadProc =         new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return load(value, mode, flags); } };
-        ValueProcedure spillProc =        new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return spill(value, mode, flags); } };
-        ValueProcedure useSlotProc =      new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return useSlot(value); } };
+        ValueProcedure killNonLiveProc =  new ValueProcedure() { @Override public Value doValue(Value value) { return killNonLive(value); } };
+        ValueProcedure killBeginProc =    new ValueProcedure() { @Override public Value doValue(Value value) { return kill(value, false); } };
+        ValueProcedure killEndProc =      new ValueProcedure() { @Override public Value doValue(Value value) { return kill(value, true); } };
+        ValueProcedure killLocationProc = new ValueProcedure() { @Override public Value doValue(Value value) { return killLocation(value); } };
+        ValueProcedure blockProc =        new ValueProcedure() { @Override public Value doValue(Value value) { return block(value); } };
+        ValueProcedure loadProc =         new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return load(value, mode, flags); } };
+        ValueProcedure spillProc =        new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return spill(value, mode, flags); } };
+        ValueProcedure useSlotProc =      new ValueProcedure() { @Override public Value doValue(Value value) { return useSlot(value); } };
 
         Debug.log("==== start spill all allocation ====");
         curInRegisterState = new Object[maxRegisterNum()];
@@ -224,7 +223,7 @@
         Debug.log("==== end spill all allocation ====");
     }
 
-    private CiValue killNonLive(CiValue value) {
+    private Value killNonLive(Value value) {
         assert isLocation(value);
         if (!curLiveIn.get(asLocation(value).variable.index)) {
             return null;
@@ -232,7 +231,7 @@
         return value;
     }
 
-    private CiValue kill(CiValue value, boolean end) {
+    private Value kill(Value value, boolean end) {
         if (isVariable(value)) {
             Debug.log("    kill variable %s", value);
 
@@ -268,7 +267,7 @@
         return value;
     }
 
-    private CiValue killLocation(CiValue value) {
+    private Value killLocation(Value value) {
         Debug.log("    kill location %s", value);
         assert isAllocatableRegister(asLocation(value).location);
 
@@ -279,7 +278,7 @@
         return null;
     }
 
-    private CiValue block(CiValue value) {
+    private Value block(Value value) {
         if (isAllocatableRegister(value)) {
             Debug.log("    block %s", value);
             int regNum = asRegister(value).number;
@@ -290,7 +289,7 @@
         return value;
     }
 
-    private CiValue load(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private Value load(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         assert mode == OperandMode.Input || mode == OperandMode.Alive;
         if (flags.contains(OperandFlag.Stack)) {
             return useSlot(value);
@@ -314,7 +313,7 @@
         }
     }
 
-    private CiValue spill(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private Value spill(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         assert mode == OperandMode.Temp || mode == OperandMode.Output;
         if (flags.contains(OperandFlag.Stack)) {
             return defSlot(value);
@@ -335,7 +334,7 @@
         }
     }
 
-    private CiValue useSlot(CiValue value) {
+    private Value useSlot(Value value) {
         if (isVariable(value)) {
             Debug.log("    useSlot %s", value);
             Location stackLoc = curStackLocations.get(asVariable(value));
@@ -347,7 +346,7 @@
         }
     }
 
-    private CiValue defSlot(CiValue value) {
+    private Value defSlot(Value value) {
         if (isVariable(value)) {
             Debug.log("    assignSlot %s", value);
             Location stackLoc = new Location(asVariable(value), frameMap.allocateSpillSlot(value.kind));
@@ -362,11 +361,11 @@
 
     private Location allocateRegister(final Variable variable, final Object[] inRegisterState, final Object[] outRegisterState, OperandMode mode, EnumSet<OperandFlag> flags) {
         if (flags.contains(OperandFlag.RegisterHint)) {
-            CiValue result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
+            Value result = curInstruction.forEachRegisterHint(variable, mode, new ValueProcedure() {
                 @Override
-                public CiValue doValue(CiValue registerHint) {
+                public Value doValue(Value registerHint) {
                     Debug.log("      registerHint %s", registerHint);
-                    CiRegister hint = null;
+                    Register hint = null;
                     if (isRegister(registerHint)) {
                         hint = asRegister(registerHint);
                     } else if (isLocation(registerHint) && isRegister(asLocation(registerHint).location)) {
@@ -384,23 +383,23 @@
             }
         }
 
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
-        CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
+        EnumMap<RegisterFlag, Register[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        Register[] availableRegs = categorizedRegs.get(variable.flag);
 
-        for (CiRegister reg : availableRegs) {
+        for (Register reg : availableRegs) {
             if (isFree(reg, inRegisterState, outRegisterState)) {
                 return selectRegister(reg, variable, inRegisterState, outRegisterState);
             }
 
         }
-        throw new CiBailout("No register found");
+        throw new BailoutException("No register found");
     }
 
-    private static boolean isFree(CiRegister reg, Object[] inRegisterState, Object[] outRegisterState) {
+    private static boolean isFree(Register reg, Object[] inRegisterState, Object[] outRegisterState) {
         return (inRegisterState == null || inRegisterState[reg.number] == null) && (outRegisterState == null || outRegisterState[reg.number] == null);
     }
 
-    private Location selectRegister(CiRegister reg, Variable variable, Object[] inRegisterState, Object[] outRegisterState) {
+    private Location selectRegister(Register reg, Variable variable, Object[] inRegisterState, Object[] outRegisterState) {
         Location loc = new Location(variable, reg.asValue(variable.kind));
         if (inRegisterState != null) {
             inRegisterState[reg.number] = loc;
@@ -418,7 +417,7 @@
         final BitSet liveState = new BitSet();
         curStackLocations.forEachLocation(new ValueProcedure() {
             @Override
-            public CiValue doValue(CiValue value) {
+            public Value doValue(Value value) {
                 liveState.set(asLocation(value).variable.index);
 
                 for (Block pred : block.getPredecessors()) {
@@ -437,7 +436,7 @@
     }
 
     private boolean checkNoCallerSavedRegister() {
-        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
+        for (Register reg : frameMap.registerConfig.getCallerSaveRegisters()) {
             assert curOutRegisterState[reg.number] == null || curOutRegisterState[reg.number] == curInstruction : "caller saved register in use accross call site";
         }
         return true;
@@ -456,7 +455,7 @@
         sb.append("  curVariableLocations: ");
         curStackLocations.forEachLocation(new ValueProcedure() {
             @Override
-            public CiValue doValue(CiValue value) {
+            public Value doValue(Value value) {
                 sb.append(value).append(" ");
                 return value;
             }
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/IntervalPrinter.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/IntervalPrinter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,12 @@
  */
 package com.oracle.graal.alloc.util;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.graal.alloc.util.LocationUtil.*;
-
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.graal.alloc.simple.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.*;
@@ -37,7 +35,7 @@
 
 public final class IntervalPrinter {
 
-    public static void printBeforeAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow) {
+    public static void printBeforeAllocation(String label, LIR lir, RegisterConfig registerConfig, DataFlowAnalysis dataFlow) {
         if (Debug.isDumpEnabled()) {
             IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, null);
             Debug.dump(lir, label);
@@ -45,7 +43,7 @@
         }
     }
 
-    public static void printAfterAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
+    public static void printAfterAllocation(String label, LIR lir, RegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
         if (Debug.isDumpEnabled()) {
             IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, blockEndLocations);
             Debug.dump(lir, label);
@@ -98,13 +96,13 @@
 
 
     private final LIR lir;
-    private final RiRegisterConfig registerConfig;
+    private final RegisterConfig registerConfig;
     private final DataFlowAnalysis dataFlow;
     private final LocationMap[] blockEndLocations;
     private final Variable[] variables;
     private final Map<String, Interval> intervals;
 
-    private IntervalPrinter(LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
+    private IntervalPrinter(LIR lir, RegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
         this.lir = lir;
         this.registerConfig = registerConfig;
         this.dataFlow = dataFlow;
@@ -113,15 +111,15 @@
         this.intervals = new HashMap<>();
     }
 
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    private boolean isAllocatableRegister(Value value) {
+        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable();
     }
 
     private int curOpId;
     private String curUseKind;
 
     public Interval[] execute() {
-        ValueProcedure varProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return var(value); } };
+        ValueProcedure varProc = new ValueProcedure() { @Override public Value doValue(Value value) { return var(value); } };
 
         for (Block block : lir.linearScanOrder()) {
             for (LIRInstruction op : block.lir) {
@@ -129,8 +127,8 @@
             }
         }
 
-        ValueProcedure useProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
-        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, flags); } };
+        ValueProcedure useProc = new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
+        ValueProcedure defProc = new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, flags); } };
 
         intervals.put("call", new Interval(-2, "call", "", "call", "hasCall"));
         intervals.put("st", new Interval(-1, "st", "", "st", "hasState"));
@@ -192,7 +190,7 @@
         return intervalsArray;
     }
 
-    public CiValue var(CiValue value) {
+    public Value var(Value value) {
         if (isLocation(value)) {
             variables[asLocation(value).variable.index] = asLocation(value).variable;
         } else if (isVariable(value)) {
@@ -201,7 +199,7 @@
         return value;
     }
 
-    private Interval findInterval(CiValue value) {
+    private Interval findInterval(Value value) {
         Interval interval;
         if (isLocation(value)) {
             Interval parent = findInterval(asLocation(value).variable);
@@ -237,7 +235,7 @@
         }
     }
 
-    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private Value use(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         Interval interval = findInterval(value);
         if (interval != null) {
             if (interval.uses.size() == 0 || interval.uses.get(interval.uses.size() - 1).pos != curOpId) {
@@ -250,7 +248,7 @@
         return value;
     }
 
-    private CiValue def(CiValue value, EnumSet<OperandFlag> flags) {
+    private Value def(Value value, EnumSet<OperandFlag> flags) {
         Interval interval = findInterval(value);
         if (interval != null) {
             interval.uses.add(new UsePosition(curOpId, useKind(flags)));
@@ -264,7 +262,7 @@
         return value;
     }
 
-    private CiValue out(CiValue value) {
+    private Value out(Value value) {
         Interval interval = findInterval(value);
         if (interval != null) {
             interval.lastTo = curOpId;
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/Location.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/Location.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,16 +22,16 @@
  */
 package com.oracle.graal.alloc.util;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 
-public class Location extends CiValue {
+public class Location extends Value {
     private static final long serialVersionUID = -1786677729152726126L;
 
     public final Variable variable;
-    public final CiValue location;
+    public final Value location;
 
-    public Location(Variable variable, CiValue location) {
+    public Location(Variable variable, Value location) {
         super(variable.kind);
         this.variable = variable;
         this.location = location;
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/LocationMap.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/LocationMap.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,7 +26,7 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.*;
 
@@ -57,7 +57,7 @@
     public void forEachLocation(ValueProcedure proc) {
         for (int i = 0; i < locations.length; i++) {
             if (locations[i] != null) {
-                CiValue newValue = proc.doValue(locations[i], null, null);
+                Value newValue = proc.doValue(locations[i], null, null);
                 assert newValue == null || asLocation(newValue).variable == locations[i].variable;
                 locations[i] = (Location) newValue;
             }
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/LocationUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/LocationUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,17 +22,17 @@
  */
 package com.oracle.graal.alloc.util;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 
-public class LocationUtil extends ValueUtil {
+public class LocationUtil extends LIRValueUtil {
 
-    public static boolean isLocation(CiValue value) {
+    public static boolean isLocation(Value value) {
         assert value != null;
         return value instanceof Location;
     }
 
-    public static Location asLocation(CiValue value) {
+    public static Location asLocation(Value value) {
         assert value != null;
         return (Location) value;
     }
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/MoveResolver.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/MoveResolver.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,11 @@
  */
 package com.oracle.graal.alloc.util;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.graal.alloc.util.LocationUtil.*;
-
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
@@ -36,8 +35,8 @@
     private final LIR lir;
     private final FrameMap frameMap;
     private final int[] registersBlocked;
-    private final Map<CiValue, Integer> valuesBlocked;
-    private final List<CiValue> mappingFrom;
+    private final Map<Value, Integer> valuesBlocked;
+    private final List<Value> mappingFrom;
     private final List<Location> mappingTo;
     private final LIRInsertionBuffer insertionBuffer;
     private int insertPos;
@@ -70,7 +69,7 @@
         assert checkValid();
     }
 
-    public void add(CiValue from, Location to) {
+    public void add(Value from, Location to) {
         assert checkValid();
         assert isLocation(from) || isConstant(from);
         assert from != to;
@@ -120,14 +119,14 @@
         // Block all registers and stack slots that are used as inputs of a move.
         // When a register is blocked, no move to this register is emitted.
         // This is necessary for detecting cycles in moves.
-        for (CiValue from : mappingFrom) {
+        for (Value from : mappingFrom) {
             block(from);
         }
 
         while (mappingFrom.size() > 0) {
             boolean processed = false;
             for (int i = mappingFrom.size() - 1; i >= 0; i--) {
-                CiValue from = mappingFrom.get(i);
+                Value from = mappingFrom.get(i);
                 Location to = mappingTo.get(i);
 
                 if (safeToProcessMove(from, to)) {
@@ -153,19 +152,19 @@
         int exchangeOther = -1;
 
         for (int i = mappingFrom.size() - 1; i >= 0; i--) {
-            CiValue from = mappingFrom.get(i);
+            Value from = mappingFrom.get(i);
             Location to = mappingTo.get(i);
             assert !safeToProcessMove(from, to) : "would not be in this code otherwise";
 
             if (isConstant(from)) {
                 continue;
             }
-            CiValue fromLoc = asLocation(from).location;
+            Value fromLoc = asLocation(from).location;
 
             // Check if we can insert an exchange to save us from spilling.
             if (isRegister(fromLoc) && isRegister(to) && asRegister(fromLoc) != asRegister(to) && blockedCount(to) == 1) {
                 for (int j = mappingFrom.size() - 1; j >= 0; j--) {
-                    CiValue possibleOther = mappingFrom.get(j);
+                    Value possibleOther = mappingFrom.get(j);
                     if (isLocation(possibleOther)) {
                         if (asLocation(possibleOther).location == to.location) {
                             assert exchangeCandidate == -1 : "must not find twice because of blocked check above";
@@ -220,9 +219,9 @@
         }
     }
 
-    private void block(CiValue value) {
+    private void block(Value value) {
         if (isLocation(value)) {
-            CiValue location = asLocation(value).location;
+            Value location = asLocation(value).location;
             if (isRegister(location)) {
                 registersBlocked[asRegister(location).number]++;
             } else {
@@ -232,10 +231,10 @@
         }
     }
 
-    private void unblock(CiValue value) {
+    private void unblock(Value value) {
         if (isLocation(value)) {
             assert blockedCount(asLocation(value)) > 0;
-            CiValue location = asLocation(value).location;
+            Value location = asLocation(value).location;
             if (isRegister(location)) {
                 registersBlocked[asRegister(location).number]--;
             } else {
@@ -248,7 +247,7 @@
     }
 
     private int blockedCount(Location value) {
-        CiValue location = asLocation(value).location;
+        Value location = asLocation(value).location;
         if (isRegister(location)) {
             return registersBlocked[asRegister(location).number];
         } else {
@@ -257,7 +256,7 @@
         }
     }
 
-    private boolean safeToProcessMove(CiValue from, Location to) {
+    private boolean safeToProcessMove(Value from, Location to) {
         int count = blockedCount(to);
         return count == 0 || (count == 1 && isLocation(from) && asLocation(from).location == to.location);
     }
@@ -269,17 +268,17 @@
         throw GraalInternalError.unimplemented();
     }
 
-    private void insertMove(CiValue src, Location dst) {
+    private void insertMove(Value src, Location dst) {
         if (isStackSlot(dst.location) && isLocation(src) && isStackSlot(asLocation(src).location)) {
             // Move between two stack slots. We need a temporary registers. If the allocator can give
             // us a free register, we need two moves: src->scratch, scratch->dst
             // If the allocator cannot give us a free register (it returns a Location in this case),
             // we need to spill the scratch register first, so we need four moves in total.
 
-            CiValue scratch = scratchRegister(dst.variable);
+            Value scratch = scratchRegister(dst.variable);
 
             Location scratchSaved = null;
-            CiValue scratchRegister = scratch;
+            Value scratchRegister = scratch;
             if (isLocation(scratch)) {
                 scratchSaved = new Location(asLocation(scratch).variable, frameMap.allocateSpillSlot(scratch.kind));
                 insertMove(scratch, scratchSaved);
@@ -303,10 +302,10 @@
 
     /**
      * Provides a register that can be used by the move resolver. If the returned value is a
-     * {@link CiRegisterValue}, the register can be overwritten without precautions. If the
+     * {@link RegisterValue}, the register can be overwritten without precautions. If the
      * returned value is a {@link Location}, it needs to be spilled and rescued itself.
      */
-    protected abstract CiValue scratchRegister(Variable spilled);
+    protected abstract Value scratchRegister(Variable spilled);
 
     private boolean checkEmpty() {
         assert insertPos == -1;
@@ -327,7 +326,7 @@
         assert insertionBuffer.initialized() && insertPos != -1;
 
         for (int i = 0; i < mappingTo.size(); i++) {
-            CiValue from = mappingFrom.get(i);
+            Value from = mappingFrom.get(i);
             Location to = mappingTo.get(i);
 
             assert from.kind.stackKind() == to.kind;
--- a/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/RegisterVerifier.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.alloc/src/com/oracle/graal/alloc/util/RegisterVerifier.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,11 @@
  */
 package com.oracle.graal.alloc.util;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.graal.alloc.util.LocationUtil.*;
-
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
@@ -45,11 +44,11 @@
     /**
      * Saved information of previous check.
      * <br>
-     * State mapping: mapping from registers and stack slots ({@link CiRegister} and {@link Integer} stack slot offsets) to the
-     * value that is currently contained in there ({@link Location} for operands that were variables; {@link CiRegisterValue} or
-     * {@link CiStackSlot} for operands that used fixed registers or stack slots).
+     * State mapping: mapping from registers and stack slots ({@link Register} and {@link Integer} stack slot offsets) to the
+     * value that is currently contained in there ({@link Location} for operands that were variables; {@link RegisterValue} or
+     * {@link StackSlot} for operands that used fixed registers or stack slots).
      */
-    private final Map<Object, CiValue>[] blockStates;
+    private final Map<Object, Value>[] blockStates;
 
     private void addToWorkList(Block block) {
         if (!workList.contains(block)) {
@@ -57,15 +56,15 @@
         }
     }
 
-    private Map<Object, CiValue> stateFor(Block block) {
+    private Map<Object, Value> stateFor(Block block) {
         return blockStates[block.getId()];
     }
 
-    private void setStateFor(Block block, Map<Object, CiValue> savedState) {
+    private void setStateFor(Block block, Map<Object, Value> savedState) {
         blockStates[block.getId()] = savedState;
     }
 
-    private static Map<Object, CiValue> copy(Map<Object, CiValue> inputState) {
+    private static Map<Object, Value> copy(Map<Object, Value> inputState) {
         return new HashMap<>(inputState);
     }
 
@@ -82,12 +81,12 @@
         this.blockStates = new Map[lir.linearScanOrder().size()];
     }
 
-    private Map<Object, CiValue> curInputState;
+    private Map<Object, Value> curInputState;
 
     private void verify(Block startBlock) {
-        ValueProcedure useProc =    new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, flags); } };
-        ValueProcedure tempProc =   new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return temp(value); } };
-        ValueProcedure outputProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value) { return output(value); } };
+        ValueProcedure useProc =    new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, flags); } };
+        ValueProcedure tempProc =   new ValueProcedure() { @Override public Value doValue(Value value) { return temp(value); } };
+        ValueProcedure outputProc = new ValueProcedure() { @Override public Value doValue(Value value) { return output(value); } };
 
         curInputState = new HashMap<>();
         setStateFor(startBlock, curInputState);
@@ -125,7 +124,7 @@
     }
 
     private void processSuccessor(Block succ) {
-        Map<Object, CiValue> savedState = stateFor(succ);
+        Map<Object, Value> savedState = stateFor(succ);
         if (savedState == null) {
             // Block was not processed before, so set initial inputState.
             Debug.log("  successor %s: initial visit", succ);
@@ -136,11 +135,11 @@
             // This block was already processed before.
             // Check if new inputState is consistent with savedState.
             Debug.log("  successor %s: state present", succ);
-            Iterator<Map.Entry<Object, CiValue>> iter = savedState.entrySet().iterator();
+            Iterator<Map.Entry<Object, Value>> iter = savedState.entrySet().iterator();
             while (iter.hasNext()) {
-                Map.Entry<Object, CiValue> entry = iter.next();
-                CiValue savedValue = entry.getValue();
-                CiValue inputValue = curInputState.get(entry.getKey());
+                Map.Entry<Object, Value> entry = iter.next();
+                Value savedValue = entry.getValue();
+                Value inputValue = curInputState.get(entry.getKey());
 
                 if (savedValue != inputValue) {
                     // Current inputState and previous savedState assume a different value in this register.
@@ -159,7 +158,7 @@
         Iterator<Object> iter = curInputState.keySet().iterator();
         while (iter.hasNext()) {
             Object value1 = iter.next();
-            if (value1 instanceof CiRegister && frameMap.registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) {
+            if (value1 instanceof Register && frameMap.registerConfig.getAttributesMap()[((Register) value1).number].isCallerSave()) {
                 Debug.log("    remove caller save register %s", value1);
                 iter.remove();
             }
@@ -171,7 +170,7 @@
      * include the kind of the value because we do not want to distinguish between the same register with
      * different kinds.
      */
-    private Object key(CiValue value) {
+    private Object key(Value value) {
         if (isLocation(value)) {
             return key(asLocation(value).location);
         } else if (isRegister(value)) {
@@ -183,13 +182,13 @@
         }
     }
 
-    private boolean isIgnoredRegister(CiValue value) {
-        return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    private boolean isIgnoredRegister(Value value) {
+        return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable();
     }
 
-    private CiValue use(CiValue value, EnumSet<OperandFlag> flags) {
-        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
-            CiValue actual = curInputState.get(key(value));
+    private Value use(Value value, EnumSet<OperandFlag> flags) {
+        if (!isConstant(value) && value != Value.IllegalValue && !isIgnoredRegister(value)) {
+            Value actual = curInputState.get(key(value));
             if (actual == null && flags.contains(OperandFlag.Uninitialized)) {
                 // OK, since uninitialized values are allowed explicitly.
             } else if (value != actual) {
@@ -201,16 +200,16 @@
         return value;
     }
 
-    private CiValue temp(CiValue value) {
-        if (!isConstant(value) && value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+    private Value temp(Value value) {
+        if (!isConstant(value) && value != Value.IllegalValue && !isIgnoredRegister(value)) {
             Debug.log("    temp %s -> remove key %s", value, key(value));
             curInputState.remove(key(value));
         }
         return value;
     }
 
-    private CiValue output(CiValue value) {
-        if (value != CiValue.IllegalValue && !isIgnoredRegister(value)) {
+    private Value output(Value value) {
+        if (value != Value.IllegalValue && !isIgnoredRegister(value)) {
             Debug.log("    output %s -> set key %s", value, key(value));
             curInputState.put(key(value), value);
         }
@@ -223,14 +222,14 @@
         Collections.sort(keys, new Comparator<Object>() {
             @Override
             public int compare(Object o1, Object o2) {
-                if (o1 instanceof CiRegister) {
-                    if (o2 instanceof CiRegister) {
-                        return ((CiRegister) o1).number - ((CiRegister) o2).number;
+                if (o1 instanceof Register) {
+                    if (o2 instanceof Register) {
+                        return ((Register) o1).number - ((Register) o2).number;
                     } else {
                         return -1;
                     }
                 } else {
-                    if (o2 instanceof CiRegister) {
+                    if (o2 instanceof Register) {
                         return 1;
                     } else {
                         return ((Integer) o1).intValue() - ((Integer) o2).intValue();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Address.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents an address in target machine memory, specified via some combination of a base register, an index register,
+ * a displacement and a scale. Note that the base and index registers may be a variable that will get a register assigned
+ * later by the register allocator.
+ */
+public final class Address extends Value {
+    private static final long serialVersionUID = -1003772042519945089L;
+
+    /**
+     * A sentinel value used as a place holder in an instruction stream for an address that will be patched.
+     */
+    public static final Address Placeholder = new Address(Kind.Illegal, Value.IllegalValue);
+
+    private Value base;
+    private Value index;
+    private final Scale scale;
+    private final int displacement;
+
+    /**
+     * Creates a {@code CiAddress} with given base register, no scaling and no displacement.
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     */
+    public Address(Kind kind, Value base) {
+        this(kind, base, IllegalValue, Scale.Times1, 0);
+    }
+
+    /**
+     * Creates a {@code CiAddress} with given base register, no scaling and a given displacement.
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     * @param displacement the displacement
+     */
+    public Address(Kind kind, Value base, int displacement) {
+        this(kind, base, IllegalValue, Scale.Times1, displacement);
+    }
+
+    /**
+     * Creates a {@code CiAddress} with given base and index registers, scaling and displacement.
+     * This is the most general constructor..
+     * @param kind the kind of the value being addressed
+     * @param base the base register
+     * @param index the index register
+     * @param scale the scaling factor
+     * @param displacement the displacement
+     */
+    public Address(Kind kind, Value base, Value index, Scale scale, int displacement) {
+        super(kind);
+        this.setBase(base);
+        this.setIndex(index);
+        this.scale = scale;
+        this.displacement = displacement;
+
+        assert !isConstant(base) && !isStackSlot(base);
+        assert !isConstant(index) && !isStackSlot(index);
+    }
+
+    /**
+     * A scaling factor used in complex addressing modes such as those supported by x86 platforms.
+     */
+    public enum Scale {
+        Times1(1, 0),
+        Times2(2, 1),
+        Times4(4, 2),
+        Times8(8, 3);
+
+        private Scale(int value, int log2) {
+            this.value = value;
+            this.log2 = log2;
+        }
+
+        /**
+         * The value (or multiplier) of this scale.
+         */
+        public final int value;
+
+        /**
+         * The {@linkplain #value value} of this scale log 2.
+         */
+        public final int log2;
+
+        public static Scale fromInt(int scale) {
+            switch (scale) {
+                case 1:  return Times1;
+                case 2:  return Times2;
+                case 4:  return Times4;
+                case 8:  return Times8;
+                default: throw new IllegalArgumentException(String.valueOf(scale));
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        if (this == Placeholder) {
+            return "[<placeholder>]";
+        }
+
+        StringBuilder s = new StringBuilder();
+        s.append(kind.javaName).append("[");
+        String sep = "";
+        if (isLegal(getBase())) {
+            s.append(getBase());
+            sep = " + ";
+        }
+        if (isLegal(getIndex())) {
+            s.append(sep).append(getIndex()).append(" * ").append(getScale().value);
+            sep = " + ";
+        }
+        if (getDisplacement() < 0) {
+            s.append(" - ").append(-getDisplacement());
+        } else if (getDisplacement() > 0) {
+            s.append(sep).append(getDisplacement());
+        }
+        s.append("]");
+        return s.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Address) {
+            Address addr = (Address) obj;
+            return kind == addr.kind && getDisplacement() == addr.getDisplacement() && getBase().equals(addr.getBase()) && getScale() == addr.getScale() && getIndex().equals(addr.getIndex());
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return getBase().hashCode() ^ getIndex().hashCode() ^ (getDisplacement() << 4) ^ (getScale().value << 8) ^ (kind.ordinal() << 12);
+    }
+
+    /**
+     * @return Base register that defines the start of the address computation.
+     * If not present, is denoted by {@link Value#IllegalValue}.
+     */
+    public Value getBase() {
+        return base;
+    }
+
+    public void setBase(Value base) {
+        this.base = base;
+    }
+
+    /**
+     * @return Index register, the value of which (possibly scaled by {@link #scale}) is added to {@link #base}.
+     * If not present, is denoted by {@link Value#IllegalValue}.
+     */
+    public Value getIndex() {
+        return index;
+    }
+
+    public void setIndex(Value index) {
+        this.index = index;
+    }
+
+    /**
+     * @return Scaling factor for indexing, dependent on target operand size.
+     */
+    public Scale getScale() {
+        return scale;
+    }
+
+    /**
+     * @return Optional additive displacement.
+     */
+    public int getDisplacement() {
+        return displacement;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.Register.*;
+
+
+/**
+ * Represents a CPU architecture, including information such as its endianness, CPU
+ * registers, word width, etc.
+ */
+public abstract class Architecture {
+
+    /**
+     * The endianness of the architecture.
+     */
+    public static enum ByteOrder {
+        LittleEndian,
+        BigEndian
+    }
+
+    /**
+     * The number of bits required in a bit map covering all the registers that may store references.
+     * The bit position of a register in the map is the register's {@linkplain Register#number number}.
+     */
+    public final int registerReferenceMapBitCount;
+
+    /**
+     * Represents the natural size of words (typically registers and pointers) of this architecture, in bytes.
+     */
+    public final int wordSize;
+
+    /**
+     * The name of this architecture (e.g. "AMD64", "SPARCv9").
+     */
+    public final String name;
+
+    /**
+     * Array of all available registers on this architecture. The index of each register in this
+     * array is equal to its {@linkplain Register#number number}.
+     */
+    public final Register[] registers;
+
+    /**
+     * Map of all registers keyed by their {@linkplain Register#name names}.
+     */
+    public final HashMap<String, Register> registersByName;
+
+    /**
+     * The byte ordering can be either little or big endian.
+     */
+    public final ByteOrder byteOrder;
+
+    /**
+     * Mask of the barrier constants defined in {@link MemoryBarriers} denoting the barriers that
+     * are not required to be explicitly inserted under this architecture.
+     */
+    public final int implicitMemoryBarriers;
+
+    /**
+     * Determines the barriers in a given barrier mask that are explicitly required on this architecture.
+     *
+     * @param barriers a mask of the barrier constants defined in {@link MemoryBarriers}
+     * @return the value of {@code barriers} minus the barriers unnecessary on this architecture
+     */
+    public final int requiredBarriers(int barriers) {
+        return barriers & ~implicitMemoryBarriers;
+    }
+
+    /**
+     * Offset in bytes from the beginning of a call instruction to the displacement.
+     */
+    public final int machineCodeCallDisplacementOffset;
+
+    /**
+     * The size of the return address pushed to the stack by a call instruction.
+     * A value of 0 denotes that call linkage uses registers instead (e.g. SPARC).
+     */
+    public final int returnAddressSize;
+
+    private final EnumMap<RegisterFlag, Register[]> registersByTypeAndEncoding;
+
+    /**
+     * Gets the register for a given {@linkplain Register#encoding encoding} and type.
+     *
+     * @param encoding a register value as used in a machine instruction
+     * @param type the type of the register
+     */
+    public Register registerFor(int encoding, RegisterFlag type) {
+        Register[] regs = registersByTypeAndEncoding.get(type);
+        assert encoding >= 0 && encoding < regs.length;
+        Register reg = regs[encoding];
+        assert reg != null;
+        return reg;
+    }
+
+    protected Architecture(String name,
+                    int wordSize,
+                    ByteOrder byteOrder,
+                    Register[] registers,
+                    int implicitMemoryBarriers,
+                    int nativeCallDisplacementOffset,
+                    int registerReferenceMapBitCount,
+                    int returnAddressSize) {
+        this.name = name;
+        this.registers = registers;
+        this.wordSize = wordSize;
+        this.byteOrder = byteOrder;
+        this.implicitMemoryBarriers = implicitMemoryBarriers;
+        this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
+        this.registerReferenceMapBitCount = registerReferenceMapBitCount;
+        this.returnAddressSize = returnAddressSize;
+
+        registersByName = new HashMap<>(registers.length);
+        for (Register register : registers) {
+            registersByName.put(register.name, register);
+            assert registers[register.number] == register;
+        }
+
+        registersByTypeAndEncoding = new EnumMap<>(RegisterFlag.class);
+        EnumMap<RegisterFlag, Register[]> categorizedRegs = Register.categorize(registers);
+        for (RegisterFlag type : RegisterFlag.values()) {
+            Register[] regs = categorizedRegs.get(type);
+            int max = Register.maxRegisterEncoding(regs);
+            Register[] regsByEnc = new Register[max + 1];
+            for (Register reg : regs) {
+                regsByEnc[reg.encoding] = reg;
+            }
+            registersByTypeAndEncoding.put(type, regsByEnc);
+        }
+    }
+
+    /**
+     * Converts this architecture to a string.
+     * @return the string representation of this architecture
+     */
+    @Override
+    public final String toString() {
+        return name.toLowerCase();
+    }
+
+    /**
+     * Checks whether this is a 32-bit architecture.
+     * @return {@code true} if this architecture is 32-bit
+     */
+    public final boolean is32bit() {
+        return wordSize == 4;
+    }
+
+    /**
+     * Checks whether this is a 64-bit architecture.
+     * @return {@code true} if this architecture is 64-bit
+     */
+    public final boolean is64bit() {
+        return wordSize == 8;
+    }
+
+    // The following methods are architecture specific and not dependent on state
+    // stored in this class. They have convenient default implementations.
+
+    /**
+     * Checks whether this architecture's normal arithmetic instructions use a two-operand form
+     * (e.g. x86 which overwrites one operand register with the result when adding).
+     * @return {@code true} if this architecture uses two-operand mode
+     */
+    public boolean twoOperandMode() {
+        return false;
+    }
+
+    // TODO: Why enumerate the concrete subclasses here rather
+    // than use instanceof comparisons in code that cares?
+
+    /**
+     * Checks whether the architecture is x86.
+     * @return {@code true} if the architecture is x86
+     */
+    public boolean isX86() {
+        return false;
+    }
+
+    /**
+     * Checks whether the architecture is SPARC.
+     * @return {@code true} if the architecture is SPARC
+     */
+    public boolean isSPARC() {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Class for recording optimistic assumptions made during compilation.
+ * Recorded assumption can be visited for subsequent processing using
+ * an implementation of the {@link CiAssumptionProcessor} interface.
+ */
+public final class Assumptions implements Serializable, Iterable<Assumptions.Assumption> {
+
+    private static final long serialVersionUID = 5152062717588239131L;
+
+    public abstract static class Assumption implements Serializable {
+
+        private static final long serialVersionUID = -1936652569665112915L;
+    }
+
+    /**
+     * An assumption about a unique subtype of a given type.
+     */
+    public static final class ConcreteSubtype extends Assumption {
+
+        private static final long serialVersionUID = -1457173265437676252L;
+
+        /**
+         * Type the assumption is made about.
+         */
+        public final ResolvedJavaType context;
+
+        /**
+         * Assumed unique concrete sub-type of the context type.
+         */
+        public final ResolvedJavaType subtype;
+
+        public ConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
+            this.context = context;
+            this.subtype = subtype;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + context.hashCode();
+            result = prime * result + subtype.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteSubtype) {
+                ConcreteSubtype other = (ConcreteSubtype) obj;
+                return other.context == context && other.subtype == subtype;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * An assumption about a unique implementation of a virtual method.
+     */
+    public static final class ConcreteMethod extends Assumption {
+
+        private static final long serialVersionUID = -7636746737947390059L;
+
+        /**
+         * A virtual (or interface) method whose unique implementation for the receiver type
+         * in {@link #context} is {@link #impl}.
+         */
+        public final ResolvedJavaMethod method;
+
+        /**
+         * A receiver type.
+         */
+        public final ResolvedJavaType context;
+
+        /**
+         * The unique implementation of {@link #method} for {@link #context}.
+         */
+        public final ResolvedJavaMethod impl;
+
+        public ConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
+            this.method = method;
+            this.context = context;
+            this.impl = impl;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + method.hashCode();
+            result = prime * result + context.hashCode();
+            result = prime * result + impl.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteMethod) {
+                ConcreteMethod other = (ConcreteMethod) obj;
+                return other.method == method && other.context == context && other.impl == impl;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * An assumption that specified that a method was used during the compilation.
+     */
+    public static final class MethodContents extends Assumption {
+
+        private static final long serialVersionUID = -4821594103928571659L;
+
+        public final ResolvedJavaMethod method;
+
+        public MethodContents(ResolvedJavaMethod method) {
+            this.method = method;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + method.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteMethod) {
+                ConcreteMethod other = (ConcreteMethod) obj;
+                return other.method == method;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Array with the assumptions. This field is directly accessed from C++ code in the Graal/HotSpot implementation.
+     */
+    private Assumption[] list;
+
+    private int count;
+
+    /**
+     * Returns whether any assumptions have been registered.
+     * @return {@code true} if at least one assumption has been registered, {@code false} otherwise.
+     */
+    public boolean isEmpty() {
+        return count == 0;
+    }
+
+    @Override
+    public Iterator<Assumption> iterator() {
+        return new Iterator<Assumptions.Assumption>() {
+            int index;
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+            public Assumption next() {
+                if (index >= count) {
+                    throw new NoSuchElementException();
+                }
+                return list[index++];
+            }
+            public boolean hasNext() {
+                return index < count;
+            }
+        };
+    }
+
+    /**
+     * Records an assumption that the specified type has no finalizable subclasses.
+     *
+     * @param receiverType the type that is assumed to have no finalizable subclasses
+     * @return {@code true} if the assumption was recorded and can be assumed; {@code false} otherwise
+     */
+    @SuppressWarnings("static-method")
+    public boolean recordNoFinalizableSubclassAssumption(ResolvedJavaType receiverType) {
+        // TODO (thomaswue): Record that assumption correctly.
+        return false;
+    }
+
+    /**
+     * Records that {@code subtype} is the only concrete subtype in the class hierarchy below {@code context}.
+     * @param context the root of the subtree of the class hierarchy that this assumptions is about
+     * @param subtype the one concrete subtype
+     */
+    public void recordConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
+        record(new ConcreteSubtype(context, subtype));
+    }
+
+    /**
+     * Records that {@code impl} is the only possible concrete target for a virtual call to
+     * {@code method} with a receiver of type {@code context}.
+     *
+     * @param method a method that is the target of a virtual call
+     * @param context the receiver type of a call to {@code method}
+     * @param impl the concrete method that is the only possible target for the virtual call
+     */
+    public void recordConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
+        record(new ConcreteMethod(method, context, impl));
+    }
+
+    /**
+     * Records that {@code method} was used during the compilation.
+     *
+     * @param method a method whose contents were used
+     */
+    public void recordMethodContents(ResolvedJavaMethod method) {
+        record(new MethodContents(method));
+    }
+
+    private void record(Assumption assumption) {
+        if (list == null) {
+            list = new Assumption[4];
+        } else {
+            for (int i = 0; i < count; ++i) {
+                if (assumption.equals(list[i])) {
+                    return;
+                }
+            }
+        }
+        if (list.length == count) {
+            Assumption[] newList = new Assumption[list.length * 2];
+            for (int i = 0; i < list.length; ++i) {
+                newList[i] = list[i];
+            }
+            list = newList;
+        }
+        list[count] = assumption;
+        count++;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BailoutException.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.util.*;
+
+/**
+ * {@code CiBailout} is thrown when the compiler refuses to compile a method because of problems with the method.
+ * e.g. bytecode wouldn't verify, too big, JSR/ret too complicated, etc. This exception is <i>not</i>
+ * meant to indicate problems with the compiler itself.
+ */
+public class BailoutException extends RuntimeException {
+
+    public static final long serialVersionUID = 8974598793458772L;
+
+    /**
+     * Create a new {@code CiBailout}.
+     * @param reason a message indicating the reason
+     */
+    public BailoutException(String reason) {
+        super(reason);
+    }
+
+    /**
+     * Create a new {@code CiBailout}.
+     * @param reason a message indicating the reason with a String.format - syntax
+     * @param args parameters to the formatter
+     */
+    public BailoutException(String format, Object... args) {
+        this(String.format(Locale.ENGLISH, format, args));
+    }
+
+    /**
+     * Create a new {@code CiBailout} t due to an internal exception being thrown.
+     * @param reason a message indicating the reason
+     * @param cause the throwable that was the cause of the bailout
+     */
+    public BailoutException(String reason, Throwable cause) {
+        super(reason);
+        initCause(cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodeFrame.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.io.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents the Java bytecode frame state(s) at a given position
+ * including {@link Value locations} where to find the local variables,
+ * operand stack values and locked objects of the bytecode frame(s).
+ */
+public class BytecodeFrame extends BytecodePosition implements Serializable {
+    private static final long serialVersionUID = -345025397165977565L;
+
+    /**
+     * An array of values representing how to reconstruct the state of the Java frame.
+     * This is array is partitioned as follows:
+     * <p>
+     * <table border="1" cellpadding="5" frame="void", rules="all">
+     * <tr><th>Start index (inclusive)</th><th>End index (exclusive)</th><th>Description</th></tr>
+     * <tr><td>0</td>                   <td>numLocals</td>           <td>Local variables</td></tr>
+     * <tr><td>numLocals</td>           <td>numLocals + numStack</td><td>Operand stack</td></tr>
+     * <tr><td>numLocals + numStack</td><td>values.length</td>       <td>Locked objects</td></tr>
+     * </table>
+     * <p>
+     * Note that the number of locals and the number of stack slots may be smaller than the
+     * maximum number of locals and stack slots as specified in the compiled method.
+     */
+    public final Value[] values;
+
+    /**
+     * The number of locals in the values array.
+     */
+    public final int numLocals;
+
+    /**
+     * The number of stack slots in the values array.
+     */
+    public final int numStack;
+
+    /**
+     * The number of locks in the values array.
+     */
+    public final int numLocks;
+
+    /**
+     * In case this frame state belongs to a deoptimization, the leafGraphId will contain the StructuredGraph.graphId() of the graph that originally introduced this deoptimization point.
+     * This id is later on used by the runtime system to evict graphs from the graph cache when deoptimizations originating from them have been hit.
+     */
+    public final long leafGraphId;
+
+    public final boolean rethrowException;
+
+    public final boolean duringCall;
+
+    /**
+     * Creates a new frame object.
+     *
+     * @param caller the caller frame (which may be {@code null})
+     * @param method the method
+     * @param bci a BCI within the method
+     * @param rethrowException specifies if the VM should re-throw the pending exception when deopt'ing using this frame
+     * @param values the frame state {@link #values}
+     * @param numLocals the number of local variables
+     * @param numStack the depth of the stack
+     * @param numLocks the number of locked objects
+     */
+    public BytecodeFrame(BytecodeFrame caller, ResolvedJavaMethod method, int bci, boolean rethrowException, boolean duringCall, Value[] values, int numLocals, int numStack, int numLocks, long leafGraphId) {
+        super(caller, method, bci);
+        assert values != null;
+        this.rethrowException = rethrowException;
+        this.duringCall = duringCall;
+        this.values = values;
+        this.numLocals = numLocals;
+        this.numStack = numStack;
+        this.numLocks = numLocks;
+        this.leafGraphId = leafGraphId;
+        assert !rethrowException || numStack == 1 : "must have exception on top of the stack";
+    }
+
+    /**
+     * Gets the value representing the specified local variable.
+     * @param i the local variable index
+     * @return the value that can be used to reconstruct the local's current value
+     */
+    public Value getLocalValue(int i) {
+        return values[i];
+    }
+
+    /**
+     * Gets the value representing the specified stack slot.
+     * @param i the stack index
+     * @return the value that can be used to reconstruct the stack slot's current value
+     */
+    public Value getStackValue(int i) {
+        return values[i + numLocals];
+    }
+
+    /**
+     * Gets the value representing the specified lock.
+     * @param i the lock index
+     * @return the value that can be used to reconstruct the lock's current value
+     */
+    public Value getLockValue(int i) {
+        return values[i + numLocals + numStack];
+    }
+
+    /**
+     * Gets the caller of this frame.
+     *
+     * @return {@code null} if this frame has no caller
+     */
+    public BytecodeFrame caller() {
+        return (BytecodeFrame) getCaller();
+    }
+
+    @Override
+    public String toString() {
+        return CodeUtil.append(new StringBuilder(100), this).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/BytecodePosition.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.io.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a code position, that is, a chain of inlined methods with bytecode
+ * locations, that is communicated from the compiler to the runtime system. A code position
+ * can be used by the runtime system to reconstruct a source-level stack trace
+ * for exceptions and to create {@linkplain BytecodeFrame frames} for deoptimization.
+ */
+public abstract class BytecodePosition implements Serializable {
+
+    private static final long serialVersionUID = 8633885274526033515L;
+
+    private final BytecodePosition caller;
+    private final ResolvedJavaMethod method;
+    private final int bci;
+
+    /**
+     * Constructs a new object representing a given parent/caller, a given method, and a given BCI.
+     *
+     * @param caller the parent position
+     * @param method the method
+     * @param bci a BCI within the method
+     */
+    public BytecodePosition(BytecodePosition caller, ResolvedJavaMethod method, int bci) {
+        assert method != null;
+        this.caller = caller;
+        this.method = method;
+        this.bci = bci;
+    }
+
+    /**
+     * Converts this code position to a string representation.
+     * @return a string representation of this code position
+     */
+    @Override
+    public String toString() {
+        return CodeUtil.append(new StringBuilder(100), this).toString();
+    }
+
+    /**
+     * Deep equality test.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof BytecodePosition) {
+            BytecodePosition other = (BytecodePosition) obj;
+            if (other.getMethod().equals(getMethod()) && other.getBCI() == getBCI()) {
+                if (getCaller() == null) {
+                    return other.getCaller() == null;
+                }
+                return getCaller().equals(other.getCaller());
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return getBCI();
+    }
+
+    /**
+     * @return The location within the method, as a bytecode index. The constant
+     * {@code -1} may be used to indicate the location is unknown, for example
+     * within code synthesized by the compiler.
+     */
+    public int getBCI() {
+        return bci;
+    }
+
+    /**
+     * @return The runtime interface method for this position.
+     */
+    public ResolvedJavaMethod getMethod() {
+        return method;
+    }
+
+    /**
+     * The position where this position has been called, {@code null} if none.
+     */
+    public BytecodePosition getCaller() {
+        return caller;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.util.*;
+
+
+/**
+ * The callee save area (CSA) is a contiguous space in a stack frame
+ * used to save (and restore) the values of the caller's registers.
+ * This class describes the layout of a CSA in terms of its
+ * {@linkplain #size size}, {@linkplain #slotSize slot size} and
+ * the {@linkplain #registers callee save registers} covered by the CSA.
+ */
+public class CalleeSaveLayout {
+
+    /**
+     * The size (in bytes) of the CSA.
+     */
+    public final int size;
+
+    /**
+     * The size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA.
+     */
+    public final int slotSize;
+
+    /**
+     * Map from {@linkplain Register#number register numbers} to slot indexes in the CSA.
+     */
+    private final int[] regNumToIndex;
+
+    private final Register[] indexToReg;
+
+    /**
+     * The list of registers {@linkplain #contains(Register) contained} by this CSA.
+     */
+    public final Register[] registers;
+
+    /**
+     * The offset from the frame pointer to the CSA. If this is not known, then this field
+     * will have the value {@link Integer#MAX_VALUE}.
+     */
+    public final int frameOffsetToCSA;
+
+    /**
+     * Creates a CSA layout.
+     *
+     * @param size size (in bytes) of the CSA. If this is {@code -1}, then the CSA size will be computed from {@code registers}.
+     * @param slotSize the size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA
+     * @param registers the registers that can be saved in the CSA
+     */
+    public CalleeSaveLayout(int frameOffsetToCSA, int size, int slotSize, Register... registers) {
+        this.frameOffsetToCSA = frameOffsetToCSA;
+        assert slotSize == 0 || CodeUtil.isPowerOf2(slotSize);
+        this.slotSize = slotSize;
+        int maxRegNum = -1;
+        int maxOffset = 0;
+        this.registers = registers;
+        int offset = 0;
+        for (Register reg : registers) {
+            assert offset % slotSize == 0;
+            assert reg.number >= 0;
+            if (reg.number > maxRegNum) {
+                maxRegNum = reg.number;
+            }
+            if (offset > maxOffset) {
+                maxOffset = offset;
+            }
+            offset += reg.spillSlotSize;
+        }
+        if (size == -1) {
+            this.size = offset;
+        } else {
+            assert offset <= size;
+            this.size = size;
+        }
+
+        this.regNumToIndex = new int[maxRegNum + 1];
+        this.indexToReg = offset == 0 ? new Register[0] : new Register[offset / slotSize];
+        Arrays.fill(regNumToIndex, -1);
+        offset = 0;
+        for (Register reg : registers) {
+            int index = offset / slotSize;
+            regNumToIndex[reg.number] = index;
+            indexToReg[index] = reg;
+            offset += reg.spillSlotSize;
+        }
+    }
+
+    /**
+     * Gets the offset of a given register in the CSA.
+     *
+     * @return the offset (in bytes) of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int offsetOf(int reg) {
+        return indexOf(reg) * slotSize;
+    }
+
+    /**
+     * Gets the index of a given register in the CSA.
+     *
+     * @return the index of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int indexOf(int reg) {
+        if (!contains(reg)) {
+            throw new IllegalArgumentException(String.valueOf(reg));
+        }
+        return regNumToIndex[reg];
+    }
+
+    /**
+     * Gets the offset of a given register in the CSA.
+     *
+     * @return the offset (in bytes) of {@code reg} in the CSA
+     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
+     */
+    public int offsetOf(Register reg) {
+        return offsetOf(reg.number);
+    }
+
+    /**
+     * Determines if the CSA includes a slot for a given register.
+     *
+     * @param reg the register to test
+     * @return true if the CSA contains a slot for {@code reg}
+     */
+    public boolean contains(int reg) {
+        return reg >= 0 && reg < regNumToIndex.length && regNumToIndex[reg] != -1;
+    }
+
+    /**
+     * Gets the register whose slot in the CSA is at a given index.
+     *
+     * @param index an index of a slot in the CSA
+     * @return the register whose slot in the CSA is at  {@code index} or {@code null} if {@code index} does not denote a
+     *         slot in the CSA aligned with a register
+     */
+    public Register registerAt(int index) {
+        if (index < 0 || index >= indexToReg.length) {
+            return null;
+        }
+        return indexToReg[index];
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("[");
+        for (Register reg : registers) {
+            if (sb.length() != 1) {
+                sb.append(", ");
+            }
+            sb.append(reg).append("{+").append(offsetOf(reg)).append('}');
+        }
+        return sb.append("] size=").append(size).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import com.oracle.graal.api.meta.*;
+
+
+/**
+ * A calling convention describes the locations in which the arguments for a call are placed.
+ */
+public class CallingConvention {
+
+    /**
+     * Constants denoting the type of a call for which a calling convention is
+     * {@linkplain RegisterConfig#getCallingConvention(Type, CiKind[], CiTarget, boolean) requested}.
+     */
+    public enum Type {
+        /**
+         * A request for the outgoing argument locations at a call site to Java code.
+         */
+        JavaCall(true),
+
+        /**
+         * A request for the incoming argument locations.
+         */
+        JavaCallee(false),
+
+        /**
+         * A request for the outgoing argument locations at a call site to the runtime (which may be Java or native code).
+         */
+        RuntimeCall(true),
+
+        /**
+         * A request for the outgoing argument locations at a call site to
+         * external native code that complies with the platform ABI.
+         */
+        NativeCall(true);
+
+        /**
+         * Determines if this is a request for the outgoing argument locations at a call site.
+         */
+        public final boolean out;
+
+        public static final Type[] VALUES = values();
+
+        private Type(boolean out) {
+            this.out = out;
+        }
+    }
+
+    /**
+     * The amount of stack space (in bytes) required for the stack-based arguments of the call.
+     */
+    public final int stackSize;
+
+    /**
+     * The locations in which the arguments are placed. This array ordered by argument index.
+     */
+    public final Value[] locations;
+
+    public CallingConvention(Value[] locations, int stackSize) {
+        this.locations = locations;
+        this.stackSize = stackSize;
+        assert verify();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        result.append("CallingConvention[");
+        for (Value op : locations) {
+            result.append(op.toString()).append(" ");
+        }
+        result.append("]");
+        return result.toString();
+    }
+
+    private boolean verify() {
+        for (int i = 0; i < locations.length; i++) {
+            Value location = locations[i];
+            assert isStackSlot(location) || isRegister(location);
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Encapsulates the main functionality of the runtime for the compiler, including access
+ * to constant pools, OSR frames, inlining requirements, and runtime calls such as checkcast.
+s */
+public interface CodeCacheProvider extends MetaAccessProvider {
+
+    /**
+     * Get the size in bytes for locking information on the stack.
+     */
+    int sizeOfLockData();
+
+    /**
+     * Returns a disassembly of the given installed code.
+     *
+     * @param code the code that should be disassembled
+     * @return a disassembly. This will be of length 0 if the runtime does not support disassembling.
+     */
+    String disassemble(CodeInfo code, CompilationResult tm);
+
+    /**
+     * Returns the disassembly of the given method in a {@code javap}-like format.
+     *
+     * @param method the method that should be disassembled
+     * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
+     */
+    String disassemble(ResolvedJavaMethod method);
+
+    /**
+     * Gets the register configuration to use when compiling a given method.
+     *
+     * @param method the top level method of a compilation
+     */
+    RegisterConfig getRegisterConfig(JavaMethod method);
+
+    RegisterConfig getGlobalStubRegisterConfig();
+
+    /**
+     * Custom area on the stack of each compiled method that the VM can use for its own purposes.
+     * @return the size of the custom area in bytes
+     */
+    int getCustomStackAreaSize();
+
+    /**
+     * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all cases, even when
+     * the compiled method has no regular call instructions.
+     * @return the minimum size of the outgoing parameter area in bytes
+     */
+    int getMinimumOutgoingSize();
+
+    /**
+     * Performs any runtime-specific conversion on the object used to describe the target of a call.
+     */
+    Object asCallTarget(Object target);
+
+    /**
+     * Returns the maximum absolute offset of a runtime call target from any position in the code cache or -1
+     * when not known or not applicable. Intended for determining the required size of address/offset fields.
+     */
+    long getMaxCallTargetOffset(RuntimeCall rtcall);
+
+    /**
+     * Adds the given machine code as an implementation of the given method without making it the default implementation.
+     * @param method a method to which the executable code is begin added
+     * @param code the code to be added
+     * @param info the object into which details of the installed code will be written.
+     *        Ignored if null, otherwise the info is written to index 0 of this array.
+     * @return a reference to the compiled and ready-to-run code
+     */
+    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult code, CodeInfo[] info);
+
+    /**
+     * Encodes a deoptimization action and a deoptimization reason in an integer value.
+     * @return the encoded value as an integer
+     */
+    int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason);
+
+    /**
+     * Converts a RiDeoptReason into an integer value.
+     * @return An integer value representing the given RiDeoptReason.
+     */
+    int convertDeoptReason(DeoptimizationReason reason);
+
+    /**
+     * Converts a RiDeoptAction into an integer value.
+     * @return An integer value representing the given RiDeoptAction.
+     */
+    int convertDeoptAction(DeoptimizationAction action);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import static java.lang.reflect.Modifier.*;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaTypeProfile.*;
+
+/**
+ * Miscellaneous collection of utility methods used in the {@code CRI} project.
+ */
+public class CodeUtil {
+
+    public static final String NEW_LINE = String.format("%n");
+
+    /**
+     * Gets the annotation of a particular type for a formal parameter of a given method.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @param parameterIndex the index of a formal parameter of {@code method}
+     * @param method the method for which a parameter annotation is being requested
+     * @return the annotation of type {@code annotationClass} for the formal parameter present, else null
+     * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal parameter
+     */
+    public static <T extends Annotation> T getParameterAnnotation(Class<T> annotationClass, int parameterIndex, ResolvedJavaMethod method) {
+        if (parameterIndex >= 0) {
+            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+            for (Annotation a : parameterAnnotations[parameterIndex]) {
+                if (a.annotationType() == annotationClass) {
+                    return annotationClass.cast(a);
+                }
+            }
+        }
+        return null;
+    }
+
+    public static final int K = 1024;
+    public static final int M = 1024 * 1024;
+
+    public static boolean isOdd(int n) {
+        return (n & 1) == 1;
+    }
+
+    public static boolean isEven(int n) {
+        return (n & 1) == 0;
+    }
+
+    /**
+     * Checks whether the specified integer is a power of two.
+     *
+     * @param val the value to check
+     * @return {@code true} if the value is a power of two; {@code false} otherwise
+     */
+    public static boolean isPowerOf2(int val) {
+        return val != 0 && (val & val - 1) == 0;
+    }
+
+    /**
+     * Checks whether the specified long is a power of two.
+     *
+     * @param val the value to check
+     * @return {@code true} if the value is a power of two; {@code false} otherwise
+     */
+    public static boolean isPowerOf2(long val) {
+        return val != 0 && (val & val - 1) == 0;
+    }
+
+    /**
+     * Computes the log (base 2) of the specified integer, rounding down. (E.g {@code log2(8) = 3}, {@code log2(21) = 4}
+     * )
+     *
+     * @param val the value
+     * @return the log base 2 of the value
+     */
+    public static int log2(int val) {
+        assert val > 0 && isPowerOf2(val);
+        return 31 - Integer.numberOfLeadingZeros(val);
+    }
+
+    /**
+     * Computes the log (base 2) of the specified long, rounding down. (E.g {@code log2(8) = 3}, {@code log2(21) = 4})
+     *
+     * @param val the value
+     * @return the log base 2 of the value
+     */
+    public static int log2(long val) {
+        assert val > 0 && isPowerOf2(val);
+        return 63 - Long.numberOfLeadingZeros(val);
+    }
+
+    /**
+     * Gets a string for a given method formatted according to a given format specification. A format specification is
+     * composed of characters that are to be copied verbatim to the result and specifiers that denote an attribute of
+     * the method that is to be copied to the result. A specifier is a single character preceded by a '%' character. The
+     * accepted specifiers and the method attributes they denote are described below:
+     *
+     * <pre>
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'R'       | Qualified return type                                | "int" "java.lang.String"
+     *     'r'       | Unqualified return type                              | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Method name                                          | "add"
+     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
+     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
+     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
+     *     '%'       | A '%' character                                      | "%"
+     * </pre>
+     *
+     * @param format a format specification
+     * @param method the method to be formatted
+     * @param kinds if {@code true} then the types in {@code method}'s signature are printed in the
+     *            {@linkplain Kind#jniName JNI} form of their {@linkplain Kind kind}
+     * @return the result of formatting this method according to {@code format}
+     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
+     */
+    public static String format(String format, JavaMethod method) throws IllegalFormatException {
+        final StringBuilder sb = new StringBuilder();
+        int index = 0;
+        Signature sig = null;
+        while (index < format.length()) {
+            final char ch = format.charAt(index++);
+            if (ch == '%') {
+                if (index >= format.length()) {
+                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification");
+                }
+                final char specifier = format.charAt(index++);
+                boolean qualified = false;
+                switch (specifier) {
+                    case 'R':
+                        qualified = true;
+                        // fall through
+                    case 'r': {
+                        if (sig == null) {
+                            sig = method.signature();
+                        }
+                        sb.append(MetaUtil.toJavaName(sig.returnType(null), qualified));
+                        break;
+                    }
+                    case 'H':
+                        qualified = true;
+                        // fall through
+                    case 'h': {
+                        sb.append(MetaUtil.toJavaName(method.holder(), qualified));
+                        break;
+                    }
+                    case 'n': {
+                        sb.append(method.name());
+                        break;
+                    }
+                    case 'P':
+                        qualified = true;
+                        // fall through
+                    case 'p': {
+                        if (sig == null) {
+                            sig = method.signature();
+                        }
+                        for (int i = 0; i < sig.argumentCount(false); i++) {
+                            if (i != 0) {
+                                sb.append(", ");
+                            }
+                            sb.append(MetaUtil.toJavaName(sig.argumentTypeAt(i, null), qualified));
+                        }
+                        break;
+                    }
+                    case 'f': {
+                        sb.append(!(method instanceof ResolvedJavaMethod) ? "unresolved" : isStatic(((ResolvedJavaMethod) method).accessFlags()) ? "static" : "virtual");
+                        break;
+                    }
+                    case '%': {
+                        sb.append('%');
+                        break;
+                    }
+                    default: {
+                        throw new UnknownFormatConversionException(String.valueOf(specifier));
+                    }
+                }
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Gets a string for a given field formatted according to a given format specification. A format specification is
+     * composed of characters that are to be copied verbatim to the result and specifiers that denote an attribute of
+     * the field that is to be copied to the result. A specifier is a single character preceded by a '%' character. The
+     * accepted specifiers and the field attributes they denote are described below:
+     *
+     * <pre>
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'T'       | Qualified type                                       | "int" "java.lang.String"
+     *     't'       | Unqualified type                                     | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Field name                                           | "age"
+     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
+     *     '%'       | A '%' character                                      | "%"
+     * </pre>
+     *
+     * @param format a format specification
+     * @param field the field to be formatted
+     * @param kinds if {@code true} then {@code field}'s type is printed in the {@linkplain Kind#jniName JNI} form of
+     *            its {@linkplain Kind kind}
+     * @return the result of formatting this field according to {@code format}
+     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
+     */
+    public static String format(String format, JavaField field) throws IllegalFormatException {
+        final StringBuilder sb = new StringBuilder();
+        int index = 0;
+        JavaType type = field.type();
+        while (index < format.length()) {
+            final char ch = format.charAt(index++);
+            if (ch == '%') {
+                if (index >= format.length()) {
+                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification");
+                }
+                final char specifier = format.charAt(index++);
+                boolean qualified = false;
+                switch (specifier) {
+                    case 'T':
+                        qualified = true;
+                        // fall through
+                    case 't': {
+                        sb.append(MetaUtil.toJavaName(type, qualified));
+                        break;
+                    }
+                    case 'H':
+                        qualified = true;
+                        // fall through
+                    case 'h': {
+                        sb.append(MetaUtil.toJavaName(field.holder(), qualified));
+                        break;
+                    }
+                    case 'n': {
+                        sb.append(field.name());
+                        break;
+                    }
+                    case 'f': {
+                        sb.append(!(field instanceof ResolvedJavaField) ? "unresolved" : isStatic(((ResolvedJavaField) field).accessFlags()) ? "static" : "instance");
+                        break;
+                    }
+                    case '%': {
+                        sb.append('%');
+                        break;
+                    }
+                    default: {
+                        throw new UnknownFormatConversionException(String.valueOf(specifier));
+                    }
+                }
+            } else {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Converts a Java source-language class name into the internal form.
+     *
+     * @param className the class name
+     * @return the internal name form of the class name
+     */
+    public static String toInternalName(String className) {
+        return "L" + className.replace('.', '/') + ";";
+    }
+
+    /**
+     * Prepends the String {@code indentation} to every line in String {@code lines}, including a possibly non-empty
+     * line following the final newline.
+     */
+    public static String indent(String lines, String indentation) {
+        if (lines.length() == 0) {
+            return lines;
+        }
+        final String newLine = "\n";
+        if (lines.endsWith(newLine)) {
+            return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
+        }
+        return indentation + lines.replace(newLine, newLine + indentation);
+    }
+
+    /**
+     * Formats the values in a frame as a tabulated string.
+     *
+     * @param frame
+     * @return the values in {@code frame} as a tabulated string
+     */
+    public static String tabulateValues(BytecodeFrame frame) {
+        int cols = Math.max(frame.numLocals, Math.max(frame.numStack, frame.numLocks));
+        assert cols > 0;
+        ArrayList<Object> cells = new ArrayList<>();
+        cells.add("");
+        for (int i = 0; i < cols; i++) {
+            cells.add(i);
+        }
+        cols++;
+        if (frame.numLocals != 0) {
+            cells.add("locals:");
+            cells.addAll(Arrays.asList(frame.values).subList(0, frame.numLocals));
+            cells.addAll(Collections.nCopies(cols - frame.numLocals - 1, ""));
+        }
+        if (frame.numStack != 0) {
+            cells.add("stack:");
+            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals, frame.numLocals + frame.numStack));
+            cells.addAll(Collections.nCopies(cols - frame.numStack - 1, ""));
+        }
+        if (frame.numLocks != 0) {
+            cells.add("locks:");
+            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals + frame.numStack, frame.values.length));
+            cells.addAll(Collections.nCopies(cols - frame.numLocks - 1, ""));
+        }
+        Object[] cellArray = cells.toArray();
+        for (int i = 0; i < cellArray.length; i++) {
+            if ((i % cols) != 0) {
+                cellArray[i] = "|" + cellArray[i];
+            }
+        }
+        return CodeUtil.tabulate(cellArray, cols, 1, 1);
+    }
+
+    /**
+     * Formats a given table as a string. The value of each cell is produced by {@link String#valueOf(Object)}.
+     *
+     * @param cells the cells of the table in row-major order
+     * @param cols the number of columns per row
+     * @param lpad the number of space padding inserted before each formatted cell value
+     * @param rpad the number of space padding inserted after each formatted cell value
+     * @return a string with one line per row and each column left-aligned
+     */
+    public static String tabulate(Object[] cells, int cols, int lpad, int rpad) {
+        int rows = (cells.length + (cols - 1)) / cols;
+        int[] colWidths = new int[cols];
+        for (int col = 0; col < cols; col++) {
+            for (int row = 0; row < rows; row++) {
+                int index = col + (row * cols);
+                if (index < cells.length) {
+                    Object cell = cells[index];
+                    colWidths[col] = Math.max(colWidths[col], String.valueOf(cell).length());
+                }
+            }
+        }
+        StringBuilder sb = new StringBuilder();
+        String nl = NEW_LINE;
+        for (int row = 0; row < rows; row++) {
+            for (int col = 0; col < cols; col++) {
+                int index = col + (row * cols);
+                if (index < cells.length) {
+                    for (int i = 0; i < lpad; i++) {
+                        sb.append(' ');
+                    }
+                    Object cell = cells[index];
+                    String s = String.valueOf(cell);
+                    int w = s.length();
+                    sb.append(s);
+                    while (w < colWidths[col]) {
+                        sb.append(' ');
+                        w++;
+                    }
+                    for (int i = 0; i < rpad; i++) {
+                        sb.append(' ');
+                    }
+                }
+            }
+            sb.append(nl);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Convenient shortcut for calling {@link #appendLocation(StringBuilder, JavaMethod, int)} without having to supply a
+     * a {@link StringBuilder} instance and convert the result to a string.
+     */
+    public static String toLocation(ResolvedJavaMethod method, int bci) {
+        return appendLocation(new StringBuilder(), method, bci).toString();
+    }
+
+    /**
+     * Appends a string representation of a location specified by a given method and bci to a given
+     * {@link StringBuilder}. If a stack trace element with a non-null file name and non-negative line number is
+     * {@linkplain JavaMethod#toStackTraceElement(int) available} for the given method, then the string returned is the
+     * {@link StackTraceElement#toString()} value of the stack trace element, suffixed by the bci location. For example:
+     *
+     * <pre>
+     *     java.lang.String.valueOf(String.java:2930) [bci: 12]
+     * </pre>
+     *
+     * Otherwise, the string returned is the value of {@code CiUtil.format("%H.%n(%p)"}, suffixed by the bci location.
+     * For example:
+     *
+     * <pre>
+     *     java.lang.String.valueOf(int) [bci: 12]
+     * </pre>
+     *
+     * @param sb
+     * @param method
+     * @param bci
+     * @return
+     */
+    public static StringBuilder appendLocation(StringBuilder sb, ResolvedJavaMethod method, int bci) {
+        if (method != null) {
+            StackTraceElement ste = method.toStackTraceElement(bci);
+            if (ste.getFileName() != null && ste.getLineNumber() > 0) {
+                sb.append(ste);
+            } else {
+                sb.append(CodeUtil.format("%H.%n(%p)", method));
+            }
+        } else {
+            sb.append("Null method");
+        }
+        return sb.append(" [bci: ").append(bci).append(']');
+    }
+
+    /**
+     * Appends a formatted code position to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param pos the code position to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, BytecodePosition pos) {
+        appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI());
+        if (pos.getCaller() != null) {
+            sb.append(NEW_LINE);
+            append(sb, pos.getCaller());
+        }
+        return sb;
+    }
+
+    /**
+     * Appends a formatted frame to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param frame the frame to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, BytecodeFrame frame) {
+        appendLocation(sb.append("at "), frame.getMethod(), frame.getBCI());
+        if (frame.values != null && frame.values.length > 0) {
+            sb.append(NEW_LINE);
+            String table = tabulateValues(frame);
+            String[] rows = table.split(NEW_LINE);
+            for (int i = 0; i < rows.length; i++) {
+                String row = rows[i];
+                if (!row.trim().isEmpty()) {
+                    sb.append("  ").append(row);
+                    if (i != rows.length - 1) {
+                        sb.append(NEW_LINE);
+                    }
+                }
+            }
+        }
+        if (frame.caller() != null) {
+            sb.append(NEW_LINE);
+            append(sb, frame.caller());
+        } else if (frame.getCaller() != null) {
+            sb.append(NEW_LINE);
+            append(sb, frame.getCaller());
+        }
+        return sb;
+    }
+
+    /**
+     * Formats a location present in a register or frame reference map.
+     */
+    public static class RefMapFormatter {
+
+        /**
+         * The size of a stack slot.
+         */
+        public final int slotSize;
+
+        /**
+         * The register used as the frame pointer.
+         */
+        public final Register fp;
+
+        public final Architecture arch;
+
+        /**
+         * The offset (in bytes) from the slot pointed to by {@link #fp} to the slot corresponding to bit 0 in the frame
+         * reference map.
+         */
+        public final int refMapToFPOffset;
+
+        public RefMapFormatter(Architecture arch, int slotSize, Register fp, int refMapToFPOffset) {
+            this.arch = arch;
+            this.slotSize = slotSize;
+            this.fp = fp;
+            this.refMapToFPOffset = refMapToFPOffset;
+        }
+
+        public String formatStackSlot(int frameRefMapIndex) {
+            int refMapOffset = frameRefMapIndex * slotSize;
+            int fpOffset = refMapOffset + refMapToFPOffset;
+            if (fpOffset >= 0) {
+                return fp + "+" + fpOffset;
+            }
+            return fp.name + fpOffset;
+        }
+
+        public String formatRegister(int regRefMapIndex) {
+            return arch.registers[regRefMapIndex].toString();
+        }
+    }
+
+    /**
+     * Appends a formatted debug info to a {@link StringBuilder}.
+     *
+     * @param sb the {@link StringBuilder} to append to
+     * @param info the debug info to format and append to {@code sb}
+     * @return the value of {@code sb}
+     */
+    public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatter) {
+        String nl = NEW_LINE;
+        if (info.hasRegisterRefMap()) {
+            sb.append("  reg-ref-map:");
+            BitSet bm = info.getRegisterRefMap();
+            if (formatter != null) {
+                for (int reg = bm.nextSetBit(0); reg >= 0; reg = bm.nextSetBit(reg + 1)) {
+                    sb.append(" " + formatter.formatRegister(reg));
+                }
+            }
+            sb.append(' ').append(bm).append(nl);
+        }
+        if (info.hasStackRefMap()) {
+            sb.append("frame-ref-map:");
+            BitSet bm = info.getFrameRefMap();
+            if (formatter != null) {
+                for (int i = bm.nextSetBit(0); i >= 0; i = bm.nextSetBit(i + 1)) {
+                    sb.append(" " + formatter.formatStackSlot(i));
+                }
+            }
+            sb.append(' ').append(bm).append(nl);
+        }
+        BytecodeFrame frame = info.frame();
+        if (frame != null) {
+            append(sb, frame);
+        } else if (info.getBytecodePosition() != null) {
+            append(sb, info.getBytecodePosition());
+        }
+        return sb;
+    }
+
+    public static Kind[] signatureToKinds(ResolvedJavaMethod method) {
+        Kind receiver = isStatic(method.accessFlags()) ? null : method.holder().kind();
+        return signatureToKinds(method.signature(), receiver);
+    }
+
+    public static Kind[] signatureToKinds(Signature signature, Kind receiverKind) {
+        int args = signature.argumentCount(false);
+        Kind[] result;
+        int i = 0;
+        if (receiverKind != null) {
+            result = new Kind[args + 1];
+            result[0] = receiverKind;
+            i = 1;
+        } else {
+            result = new Kind[args];
+        }
+        for (int j = 0; j < args; j++) {
+            result[i + j] = signature.argumentKindAt(j);
+        }
+        return result;
+    }
+
+    public static Class< ? >[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) {
+        int count = signature.argumentCount(false);
+        Class< ? >[] result = new Class< ? >[count];
+        for (int i = 0; i < result.length; ++i) {
+            result[i] = signature.argumentTypeAt(i, accessingClass).resolve(accessingClass).toJava();
+        }
+        return result;
+    }
+
+    /**
+     * Formats some profiling information associated as a string.
+     *
+     * @param info the profiling info to format
+     * @param method an optional method that augments the profile string returned
+     * @param sep the separator to use for each separate profile record
+     */
+    public static String profileToString(ProfilingInfo info, ResolvedJavaMethod method, String sep) {
+        StringBuilder buf = new StringBuilder(100);
+        if (method != null) {
+            buf.append(String.format("canBeStaticallyBound: %b%s", method.canBeStaticallyBound(), sep)).
+            append(String.format("invocationCount: %d%s", method.invocationCount(), sep));
+        }
+        for (int i = 0; i < info.codeSize(); i++) {
+            if (info.getExecutionCount(i) != -1) {
+                buf.append(String.format("executionCount@%d: %d%s", i, info.getExecutionCount(i), sep));
+            }
+
+            if (info.getBranchTakenProbability(i) != -1) {
+                buf.append(String.format("branchProbability@%d: %.3f%s", i, info.getBranchTakenProbability(i), sep));
+            }
+
+            double[] switchProbabilities = info.getSwitchProbabilities(i);
+            if (switchProbabilities != null) {
+                buf.append(String.format("switchProbabilities@%d:", i));
+                for (int j = 0; j < switchProbabilities.length; j++) {
+                    buf.append(String.format(" %.3f", switchProbabilities[j]));
+                }
+                buf.append(sep);
+            }
+
+            if (info.getExceptionSeen(i) != ExceptionSeen.FALSE) {
+                buf.append(String.format("exceptionSeen@%d: %s%s", i, info.getExceptionSeen(i).name(), sep));
+            }
+
+            JavaTypeProfile typeProfile = info.getTypeProfile(i);
+            if (typeProfile != null) {
+                ProfiledType[] ptypes = typeProfile.getTypes();
+                if (ptypes != null) {
+                    buf.append(String.format("types@%d:", i));
+                    for (int j = 0; j < ptypes.length; j++) {
+                        ProfiledType ptype = ptypes[j];
+                        buf.append(String.format(" %.3f (%s)%s", ptype.probability, ptype.type, sep));
+                    }
+                    buf.append(String.format(" %.3f <not recorded>%s", typeProfile.getNotRecordedProbability(), sep));
+                }
+            }
+        }
+
+        boolean firstDeoptReason = true;
+        for (DeoptimizationReason reason: DeoptimizationReason.values()) {
+            int count = info.getDeoptimizationCount(reason);
+            if (count > 0) {
+                if (firstDeoptReason) {
+                    buf.append("deoptimization history").append(sep);
+                    firstDeoptReason = false;
+                }
+                buf.append(String.format(" %s: %d%s", reason.name(), count, sep));
+            }
+        }
+        if (buf.length() == 0) {
+            return "";
+        }
+        String s = buf.toString();
+        assert s.endsWith(sep);
+        return s.substring(0, s.length() - sep.length());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationQueue.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+
+public interface CompilationQueue {
+    boolean enqueue(final ResolvedJavaMethod method, final int entryBCI, boolean blocking, int priority) throws Throwable;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents the output from compiling a method, including the compiled machine code, associated data and references,
+ * relocation information, deoptimization information, etc. It is the essential component of a {@link CiResult}, which also includes
+ * {@linkplain CiStatistics compilation statistics} and {@linkplain BailoutException failure information}.
+ */
+public class CompilationResult implements Serializable {
+
+    private static final long serialVersionUID = -1319947729753702434L;
+
+    /**
+     * Represents a code position with associated additional information.
+     */
+    public abstract static class Site implements Serializable {
+        private static final long serialVersionUID = -8214214947651979102L;
+        /**
+         * The position (or offset) of this site with respect to the start of the target method.
+         */
+        public final int pcOffset;
+
+        public Site(int pos) {
+            this.pcOffset = pos;
+        }
+    }
+
+    /**
+     * Represents a safepoint with associated debug info.
+     */
+    public static class Safepoint extends Site implements Comparable<Safepoint> {
+        private static final long serialVersionUID = 2479806696381720162L;
+        public final DebugInfo debugInfo;
+
+        Safepoint(int pcOffset, DebugInfo debugInfo) {
+            super(pcOffset);
+            this.debugInfo = debugInfo;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(pcOffset);
+            sb.append("[<safepoint>]");
+            appendDebugInfo(sb, debugInfo);
+            return sb.toString();
+        }
+
+        @Override
+        public int compareTo(Safepoint o) {
+            if (pcOffset < o.pcOffset) {
+                return -1;
+            } else if (pcOffset > o.pcOffset) {
+                return 1;
+            }
+            return 0;
+        }
+    }
+
+    /**
+     * Represents a call in the code.
+     */
+    public static final class Call extends Safepoint {
+        private static final long serialVersionUID = 1440741241631046954L;
+
+        /**
+         * The target of the call.
+         */
+        public final Object target;
+
+        /**
+         * The size of the call instruction.
+         */
+        public final int size;
+
+        /**
+         * Specifies if this call is direct or indirect. A direct call has an immediate operand encoding
+         * the absolute or relative (to the call itself) address of the target. An indirect call has a
+         * register or memory operand specifying the target address of the call.
+         */
+        public final boolean direct;
+
+        Call(Object target, int pcOffset, int size, boolean direct, DebugInfo debugInfo) {
+            super(pcOffset, debugInfo);
+            this.size = size;
+            this.target = target;
+            this.direct = direct;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(pcOffset);
+            sb.append('[');
+            sb.append(target);
+            sb.append(']');
+
+            if (debugInfo != null) {
+                appendDebugInfo(sb, debugInfo);
+            }
+
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Represents a reference to data from the code. The associated data can be any constant.
+     */
+    public static final class DataPatch extends Site {
+        private static final long serialVersionUID = 5771730331604867476L;
+        public final Constant constant;
+        public final int alignment;
+
+        DataPatch(int pcOffset, Constant data, int alignment) {
+            super(pcOffset);
+            this.constant = data;
+            this.alignment = alignment;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%d[<data patch referring to data %s>]", pcOffset, constant);
+        }
+    }
+
+    /**
+     * Provides extra information about instructions or data at specific positions in {@link CompilationResult#targetCode()}.
+     * This is optional information that can be used to enhance a disassembly of the code.
+     */
+    public abstract static class CodeAnnotation implements Serializable {
+        private static final long serialVersionUID = -7903959680749520748L;
+        public final int position;
+
+        public CodeAnnotation(int position) {
+            this.position = position;
+        }
+    }
+
+    /**
+     * A string comment about one or more instructions at a specific position in the code.
+     */
+    public static final class CodeComment extends CodeAnnotation {
+        /**
+         *
+         */
+        private static final long serialVersionUID = 6802287188701961401L;
+        public final String value;
+        public CodeComment(int position, String comment) {
+            super(position);
+            this.value = comment;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": " + value;
+        }
+    }
+
+    /**
+     * Labels some inline data in the code.
+     */
+    public static final class InlineData extends CodeAnnotation {
+        private static final long serialVersionUID = 305997507263827108L;
+        public final int size;
+        public InlineData(int position, int size) {
+            super(position);
+            this.size = size;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": size=" + size;
+        }
+    }
+
+    /**
+     * Describes a table of signed offsets embedded in the code. The offsets are relative to the starting
+     * address of the table. This type of table maybe generated when translating a multi-way branch
+     * based on a key value from a dense value set (e.g. the {@code tableswitch} JVM instruction).
+     *
+     * The table is indexed by the contiguous range of integers from {@link #low} to {@link #high} inclusive.
+     */
+    public static final class JumpTable extends CodeAnnotation {
+        private static final long serialVersionUID = 2222194398353801831L;
+
+        /**
+         * The low value in the key range (inclusive).
+         */
+        public final int low;
+
+        /**
+         * The high value in the key range (inclusive).
+         */
+        public final int high;
+
+        /**
+         * The size (in bytes) of each table entry.
+         */
+        public final int entrySize;
+
+        public JumpTable(int position, int low, int high, int entrySize) {
+            super(position);
+            this.low = low;
+            this.high = high;
+            this.entrySize = entrySize;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": [" + low + " .. " + high + "]";
+        }
+    }
+
+    /**
+     * Describes a table of key and offset pairs. The offset in each table entry is relative to the address of
+     * the table. This type of table maybe generated when translating a multi-way branch
+     * based on a key value from a sparse value set (e.g. the {@code lookupswitch} JVM instruction).
+     */
+    public static final class LookupTable extends CodeAnnotation {
+        private static final long serialVersionUID = 8367952567559116160L;
+
+        /**
+         * The number of entries in the table.
+         */
+        public final int npairs;
+
+        /**
+         * The size (in bytes) of entry's key.
+         */
+        public final int keySize;
+
+        /**
+         * The size (in bytes) of entry's offset value.
+         */
+        public final int offsetSize;
+
+        public LookupTable(int position, int npairs, int keySize, int offsetSize) {
+            super(position);
+            this.npairs = npairs;
+            this.keySize = keySize;
+            this.offsetSize = offsetSize;
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName() + "@" + position + ": [npairs=" + npairs + ", keySize=" + keySize + ", offsetSize=" + offsetSize + "]";
+        }
+    }
+
+    /**
+     * Represents exception handler information for a specific code position. It includes the catch code position as
+     * well as the caught exception type.
+     */
+    public static final class ExceptionHandler extends Site {
+        private static final long serialVersionUID = 4897339464722665281L;
+        public final int handlerPos;
+
+        ExceptionHandler(int pcOffset, int handlerPos) {
+            super(pcOffset);
+            this.handlerPos = handlerPos;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%d[<exception edge to %d>]", pcOffset, handlerPos);
+        }
+    }
+
+    public static final class Mark extends Site {
+        private static final long serialVersionUID = 3612943150662354844L;
+        public final Object id;
+        public final Mark[] references;
+
+        Mark(int pcOffset, Object id, Mark[] references) {
+            super(pcOffset);
+            this.id = id;
+            this.references = references;
+        }
+
+        @Override
+        public String toString() {
+            if (id == null) {
+                return String.format("%d[<mark with %d references>]", pcOffset, references.length);
+            } else if (id instanceof Integer) {
+                return String.format("%d[<mark with %d references and id %s>]", pcOffset, references.length, Integer.toHexString((Integer) id));
+            } else {
+                return String.format("%d[<mark with %d references and id %s>]", pcOffset, references.length, id.toString());
+            }
+        }
+    }
+
+    private final List<Safepoint> safepoints = new ArrayList<>();
+    private final List<DataPatch> dataReferences = new ArrayList<>();
+    private final List<ExceptionHandler> exceptionHandlers = new ArrayList<>();
+    private final List<Mark> marks = new ArrayList<>();
+
+    private int frameSize = -1;
+    private int customStackAreaOffset = -1;
+    private int registerRestoreEpilogueOffset = -1;
+    /**
+     * The buffer containing the emitted machine code.
+     */
+    private byte[] targetCode;
+
+    /**
+     * The leading number of bytes in {@link #targetCode} containing the emitted machine code.
+     */
+    private int targetCodeSize;
+
+    private ArrayList<CodeAnnotation> annotations;
+
+    private Assumptions assumptions;
+
+    /**
+     * Constructs a new target method.
+     */
+    public CompilationResult() {
+    }
+
+    public void setAssumptions(Assumptions assumptions) {
+        this.assumptions = assumptions;
+    }
+
+    public Assumptions assumptions() {
+        return assumptions;
+    }
+
+    /**
+     * Sets the frame size in bytes. Does not include the return address pushed onto the
+     * stack, if any.
+     *
+     * @param size the size of the frame in bytes
+     */
+    public void setFrameSize(int size) {
+        frameSize = size;
+    }
+
+    /**
+     * Sets the machine that has been generated by the compiler.
+     *
+     * @param code the machine code generated
+     * @param size the size of the machine code
+     */
+    public void setTargetCode(byte[] code, int size) {
+        targetCode = code;
+        targetCodeSize = size;
+    }
+
+    /**
+     * Records a reference to the data section in the code section (e.g. to load an integer or floating point constant).
+     *
+     * @param codePos the position in the code where the data reference occurs
+     * @param data the data that is referenced
+     * @param alignment the alignment requirement of the data or 0 if there is no alignment requirement
+     */
+    public void recordDataReference(int codePos, Constant data, int alignment) {
+        assert codePos >= 0 && data != null;
+        getDataReferences().add(new DataPatch(codePos, data, alignment));
+    }
+
+    /**
+     * Records a call in the code array.
+     *
+     * @param codePos the position of the call in the code array
+     * @param size the size of the call instruction
+     * @param target the {@link CodeCacheProvider#asCallTarget(Object) target} being called
+     * @param debugInfo the debug info for the call
+     * @param direct specifies if this is a {@linkplain Call#direct direct} call
+     */
+    public void recordCall(int codePos, int size, Object target, DebugInfo debugInfo, boolean direct) {
+        final Call call = new Call(target, codePos, size, direct, debugInfo);
+        addSafepoint(call);
+    }
+
+    /**
+     * Records an exception handler for this method.
+     *
+     * @param codePos  the position in the code that is covered by the handler
+     * @param handlerPos    the position of the handler
+     * @param throwableType the type of exceptions handled by the handler
+     */
+    public void recordExceptionHandler(int codePos, int handlerPos) {
+        getExceptionHandlers().add(new ExceptionHandler(codePos, handlerPos));
+    }
+
+    /**
+     * Records a safepoint in the code array.
+     *
+     * @param codePos the position of the safepoint in the code array
+     * @param debugInfo the debug info for the safepoint
+     */
+    public void recordSafepoint(int codePos, DebugInfo debugInfo) {
+        addSafepoint(new Safepoint(codePos, debugInfo));
+    }
+
+    private void addSafepoint(Safepoint safepoint) {
+        // The safepoints list must always be sorted
+        if (!getSafepoints().isEmpty() && getSafepoints().get(getSafepoints().size() - 1).pcOffset >= safepoint.pcOffset) {
+            // This re-sorting should be very rare
+            Collections.sort(getSafepoints());
+        }
+        getSafepoints().add(safepoint);
+    }
+
+    /**
+     * Records an instruction mark within this method.
+     *
+     * @param codePos the position in the code that is covered by the handler
+     * @param id the identifier for this mark
+     * @param references an array of other marks that this mark references
+     */
+    public Mark recordMark(int codePos, Object id, Mark[] references) {
+        Mark mark = new Mark(codePos, id, references);
+        getMarks().add(mark);
+        return mark;
+    }
+
+    /**
+     * Allows a method to specify the offset of the epilogue that restores the callee saved registers. Must be called
+     * iff the method is a callee saved method and stores callee registers on the stack.
+     *
+     * @param registerRestoreEpilogueOffset the offset in the machine code where the epilogue begins
+     */
+    public void setRegisterRestoreEpilogueOffset(int registerRestoreEpilogueOffset) {
+        assert this.registerRestoreEpilogueOffset == -1;
+        this.registerRestoreEpilogueOffset = registerRestoreEpilogueOffset;
+    }
+
+    /**
+     * The frame size of the method in bytes.
+     *
+     * @return the frame size
+     */
+    public int frameSize() {
+        assert frameSize != -1 : "frame size not yet initialized!";
+        return frameSize;
+    }
+
+    /**
+     * @return the code offset of the start of the epilogue that restores all callee saved registers, or -1 if this is
+     *         not a callee saved method
+     */
+    public int registerRestoreEpilogueOffset() {
+        return registerRestoreEpilogueOffset;
+    }
+
+    /**
+     * Offset in bytes for the custom stack area (relative to sp).
+     * @return the offset in bytes
+     */
+    public int customStackAreaOffset() {
+        return customStackAreaOffset;
+    }
+
+    /**
+     * @see #customStackAreaOffset()
+     * @param offset
+     */
+    public void setCustomStackAreaOffset(int offset) {
+        customStackAreaOffset = offset;
+    }
+
+    /**
+     * @return the machine code generated for this method
+     */
+    public byte[] targetCode() {
+        return targetCode;
+    }
+
+    /**
+     * @return the size of the machine code generated for this method
+     */
+    public int targetCodeSize() {
+        return targetCodeSize;
+    }
+
+    /**
+     * @return the code annotations or {@code null} if there are none
+     */
+    public List<CodeAnnotation> annotations() {
+        return annotations;
+    }
+
+    public void addAnnotation(CodeAnnotation annotation) {
+        assert annotation != null;
+        if (annotations == null) {
+            annotations = new ArrayList<>();
+        }
+        annotations.add(annotation);
+    }
+
+    private static void appendDebugInfo(StringBuilder sb, DebugInfo info) {
+        if (info != null) {
+            appendRefMap(sb, "stackMap", info.getFrameRefMap());
+            appendRefMap(sb, "registerMap", info.getRegisterRefMap());
+            BytecodePosition codePos = info.getBytecodePosition();
+            if (codePos != null) {
+                CodeUtil.appendLocation(sb.append(" "), codePos.getMethod(), codePos.getBCI());
+                if (info.hasFrame()) {
+                    sb.append(" #locals=").append(info.frame().numLocals).append(" #expr=").append(info.frame().numStack);
+                    if (info.frame().numLocks > 0) {
+                        sb.append(" #locks=").append(info.frame().numLocks);
+                    }
+                }
+            }
+        }
+    }
+
+    private static void appendRefMap(StringBuilder sb, String name, BitSet map) {
+        if (map != null) {
+            sb.append(' ').append(name).append('[').append(map.toString()).append(']');
+        }
+    }
+
+    /**
+     * @return the list of safepoints, sorted by {@link Site#pcOffset}
+     */
+    public List<Safepoint> getSafepoints() {
+        return safepoints;
+    }
+
+    /**
+     * @return the list of data references
+     */
+    public List<DataPatch> getDataReferences() {
+        return dataReferences;
+    }
+
+    /**
+     * @return the list of exception handlers
+     */
+    public List<ExceptionHandler> getExceptionHandlers() {
+        return exceptionHandlers;
+    }
+
+    /**
+     * @return the list of marks
+     */
+    public List<Mark> getMarks() {
+        return marks;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Represents the debugging information for a particular place in the code,
+ * which includes the code position, a reference map, and deoptimization information.
+ */
+public class DebugInfo implements Serializable {
+
+    private static final long serialVersionUID = -6047206624915812516L;
+
+    private final BytecodePosition bytecodePosition;
+    private final BitSet registerRefMap;
+    private final BitSet frameRefMap;
+
+    /**
+     * Creates a new {@code CiDebugInfo} from the given values.
+     *
+     * @param codePos the {@linkplain BytecodePosition code position} or {@linkplain BytecodeFrame frame} info
+     * @param registerRefMap the register map
+     * @param frameRefMap the reference map for {@code frame}, which may be {@code null}
+     */
+    public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap) {
+        this.bytecodePosition = codePos;
+        this.registerRefMap = registerRefMap;
+        this.frameRefMap = frameRefMap;
+    }
+
+    /**
+     * @return {@code true} if this debug information has a frame
+     */
+    public boolean hasFrame() {
+        return getBytecodePosition() instanceof BytecodeFrame;
+    }
+
+    /**
+     * @return {@code true} if this debug info has a reference map for the registers
+     */
+    public boolean hasRegisterRefMap() {
+        return getRegisterRefMap() != null && getRegisterRefMap().size() > 0;
+    }
+
+    /**
+     * @return {@code true} if this debug info has a reference map for the stack
+     */
+    public boolean hasStackRefMap() {
+        return getFrameRefMap() != null && getFrameRefMap().size() > 0;
+    }
+
+
+    /**
+     * Gets the deoptimization information for each inlined frame (if available).
+     *
+     * @return {@code null} if no frame de-opt info is {@linkplain #hasDebugFrame available}
+     */
+    public BytecodeFrame frame() {
+        if (hasFrame()) {
+            return (BytecodeFrame) getBytecodePosition();
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return CodeUtil.append(new StringBuilder(100), this, null).toString();
+    }
+
+    /**
+     * @return The code position (including all inlined methods) of this debug info.
+     * If this is a {@link BytecodeFrame} instance, then it is also the deoptimization information for each inlined frame.
+     */
+    public BytecodePosition getBytecodePosition() {
+        return bytecodePosition;
+    }
+
+    /**
+     * @return The reference map for the registers at this point. The reference map is <i>packed</i> in that
+     * for bit {@code k} in byte {@code n}, it refers to the register whose
+     * {@linkplain Register#number number} is {@code (k + n * 8)}.
+     */
+    public BitSet getRegisterRefMap() {
+        return registerRefMap;
+    }
+
+    /**
+     * @return The reference map for the stack frame at this point. A set bit at {@code k} in the map
+     * represents stack slot number {@code k}.
+     */
+    public BitSet getFrameRefMap() {
+        return frameRefMap;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java	Wed Jun 27 17:35:32 2012 +0200
@@ -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.api.code;
+
+
+public enum DeoptimizationAction {
+    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.api.code/src/com/oracle/graal/api/code/MonitorValue.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+public final class MonitorValue extends Value {
+    private static final long serialVersionUID = 8241681800464483691L;
+
+    private Value owner;
+    private final Value lockData;
+    private final boolean eliminated;
+
+    public MonitorValue(Value owner, Value lockData, boolean eliminated) {
+        super(Kind.Illegal);
+        this.owner = owner;
+        this.lockData = lockData;
+        this.eliminated = eliminated;
+    }
+
+    public Value getOwner() {
+        return owner;
+    }
+
+    public void setOwner(Value newOwner) {
+        this.owner = newOwner;
+    }
+
+    public Value getLockData() {
+        return lockData;
+    }
+
+    public boolean isEliminated() {
+        return eliminated;
+    }
+
+    @Override
+    public String toString() {
+        return "monitor[" + owner + (lockData != null ? ", " + lockData : "") + (eliminated ? ", eliminated" : "") + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a target machine register.
+ */
+public final class Register implements Comparable<Register>, Serializable {
+
+    private static final long serialVersionUID = -7213269157816016300L;
+
+    /**
+     * Invalid register.
+     */
+    public static final Register None = new Register(-1, -1, 0, "noreg");
+
+    /**
+     * Frame pointer of the current method. All spill slots and outgoing stack-based arguments
+     * are addressed relative to this register.
+     */
+    public static final Register Frame = new Register(-2, -2, 0, "framereg", RegisterFlag.CPU);
+
+    public static final Register CallerFrame = new Register(-3, -3, 0, "callerframereg", RegisterFlag.CPU);
+
+    /**
+     * The identifier for this register that is unique across all the registers in a {@link Architecture}.
+     * A valid register has {@code number > 0}.
+     */
+    public final int number;
+
+    /**
+     * The mnemonic of this register.
+     */
+    public final String name;
+
+    /**
+     * The actual encoding in a target machine instruction for this register, which may or
+     * may not be the same as {@link #number}.
+     */
+    public final int encoding;
+
+    /**
+     * The size of the stack slot used to spill the value of this register.
+     */
+    public final int spillSlotSize;
+
+    /**
+     * The set of {@link RegisterFlag} values associated with this register.
+     */
+    private final int flags;
+
+    /**
+     * An array of {@link RegisterValue} objects, for this register, with one entry
+     * per {@link Kind}, indexed by {@link Kind#ordinal}.
+     */
+    private final RegisterValue[] values;
+
+    /**
+     * Attributes that characterize a register in a useful way.
+     *
+     */
+    public enum RegisterFlag {
+        /**
+         * Denotes an integral (i.e. non floating point) register.
+         */
+        CPU,
+
+        /**
+         * Denotes a register whose lowest order byte can be addressed separately.
+         */
+        Byte,
+
+        /**
+         * Denotes a floating point register.
+         */
+        FPU;
+
+        public final int mask = 1 << (ordinal() + 1);
+    }
+
+    /**
+     * Creates a {@code CiRegister} instance.
+     *
+     * @param number unique identifier for the register
+     * @param encoding the target machine encoding for the register
+     * @param spillSlotSize the size of the stack slot used to spill the value of the register
+     * @param name the mnemonic name for the register
+     * @param flags the set of {@link RegisterFlag} values for the register
+     */
+    public Register(int number, int encoding, int spillSlotSize, String name, RegisterFlag... flags) {
+        this.number = number;
+        this.name = name;
+        this.spillSlotSize = spillSlotSize;
+        this.flags = createMask(flags);
+        this.encoding = encoding;
+
+        values = new RegisterValue[Kind.VALUES.length];
+        for (Kind kind : Kind.VALUES) {
+            values[kind.ordinal()] = new RegisterValue(kind, this);
+        }
+    }
+
+    private static int createMask(RegisterFlag... flags) {
+        int result = 0;
+        for (RegisterFlag f : flags) {
+            result |= f.mask;
+        }
+        return result;
+    }
+
+    public boolean isSet(RegisterFlag f) {
+        return (flags & f.mask) != 0;
+    }
+
+    /**
+     * Gets this register as a {@linkplain RegisterValue value} with a specified kind.
+     * @param kind the specified kind
+     * @return the {@link RegisterValue}
+     */
+    public RegisterValue asValue(Kind kind) {
+        return values[kind.ordinal()];
+    }
+
+    /**
+     * Gets this register as a {@linkplain RegisterValue value} with no particular kind.
+     * @return a {@link RegisterValue} with {@link Kind#Illegal} kind.
+     */
+    public RegisterValue asValue() {
+        return asValue(Kind.Illegal);
+    }
+
+    /**
+     * Determines if this is a valid register.
+     * @return {@code true} iff this register is valid
+     */
+    public boolean isValid() {
+        return number >= 0;
+    }
+
+    /**
+     * Determines if this a floating point register.
+     */
+    public boolean isFpu() {
+        return isSet(RegisterFlag.FPU);
+    }
+
+    /**
+     * Determines if this a general purpose register.
+     */
+    public boolean isCpu() {
+        return isSet(RegisterFlag.CPU);
+    }
+
+    /**
+     * Determines if this register has the {@link RegisterFlag#Byte} attribute set.
+     * @return {@code true} iff this register has the {@link RegisterFlag#Byte} attribute set.
+     */
+    public boolean isByte() {
+        return isSet(RegisterFlag.Byte);
+    }
+
+    /**
+     * Categorizes a set of registers by {@link RegisterFlag}.
+     *
+     * @param registers a list of registers to be categorized
+     * @return a map from each {@link RegisterFlag} constant to the list of registers for which the flag is
+     *         {@linkplain #isSet(RegisterFlag) set}
+     */
+    public static EnumMap<RegisterFlag, Register[]> categorize(Register[] registers) {
+        EnumMap<RegisterFlag, Register[]> result = new EnumMap<>(RegisterFlag.class);
+        for (RegisterFlag flag : RegisterFlag.values()) {
+            ArrayList<Register> list = new ArrayList<>();
+            for (Register r : registers) {
+                if (r.isSet(flag)) {
+                    list.add(r);
+                }
+            }
+            result.put(flag, list.toArray(new Register[list.size()]));
+        }
+        return result;
+    }
+
+    /**
+     * Gets the maximum register {@linkplain #number number} in a given set of registers.
+     *
+     * @param registers the set of registers to process
+     * @return the maximum register number for any register in {@code registers}
+     */
+    public static int maxRegisterNumber(Register[] registers) {
+        int max = Integer.MIN_VALUE;
+        for (Register r : registers) {
+            if (r.number > max) {
+                max = r.number;
+            }
+        }
+        return max;
+    }
+
+    /**
+     * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
+     *
+     * @param registers the set of registers to process
+     * @return the maximum register encoding for any register in {@code registers}
+     */
+    public static int maxRegisterEncoding(Register[] registers) {
+        int max = Integer.MIN_VALUE;
+        for (Register r : registers) {
+            if (r.encoding > max) {
+                max = r.encoding;
+            }
+        }
+        return max;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public int compareTo(Register o) {
+        if (number < o.number) {
+            return -1;
+        }
+        if (number > o.number) {
+            return 1;
+        }
+        return 0;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterAttributes.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.util.*;
+
+/**
+ * A collection of register attributes. The specific attribute values for a register may be
+ * local to a compilation context. For example, a {@link RegisterConfig} in use during
+ * a compilation will determine which registers are callee saved.
+ */
+public class RegisterAttributes {
+    private final boolean callerSave;
+    private final boolean calleeSave;
+    private final boolean allocatable;
+
+    public RegisterAttributes(boolean isCallerSave, boolean isCalleeSave, boolean isAllocatable) {
+        this.callerSave = isCallerSave;
+        this.calleeSave = isCalleeSave;
+        this.allocatable = isAllocatable;
+    }
+
+    public static final RegisterAttributes NONE = new RegisterAttributes(false, false, false);
+
+    /**
+     * Creates a map from register {@linkplain Register#number numbers} to register
+     * {@linkplain RegisterAttributes attributes} for a given register configuration and set of
+     * registers.
+     *
+     * @param registerConfig a register configuration
+     * @param registers a set of registers
+     * @return an array whose length is the max register number in {@code registers} plus 1. An element at index i holds
+     *         the attributes of the register whose number is i.
+     */
+    public static RegisterAttributes[] createMap(RegisterConfig registerConfig, Register[] registers) {
+        RegisterAttributes[] map = new RegisterAttributes[registers.length];
+        for (Register reg : registers) {
+            if (reg != null) {
+                CalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
+                RegisterAttributes attr = new RegisterAttributes(
+                                Arrays.asList(registerConfig.getCallerSaveRegisters()).contains(reg),
+                                csl == null ? false : Arrays.asList(csl.registers).contains(reg),
+                                Arrays.asList(registerConfig.getAllocatableRegisters()).contains(reg));
+                if (map.length <= reg.number) {
+                    map = Arrays.copyOf(map, reg.number + 1);
+                }
+                map[reg.number] = attr;
+            }
+        }
+        for (int i = 0; i < map.length; i++) {
+            if (map[i] == null) {
+                map[i] = NONE;
+            }
+        }
+        return map;
+    }
+
+    /**
+     * @return Denotes a register that is available for use by a register allocator.
+     */
+    public boolean isAllocatable() {
+        return allocatable;
+    }
+
+    /**
+     * @return Denotes a register whose value preservation (if required) across a call is the responsibility of the callee.
+     */
+    public boolean isCalleeSave() {
+        return calleeSave;
+    }
+
+    /**
+     * @return Denotes a register whose value preservation (if required) across a call is the responsibility of the caller.
+     */
+    public boolean isCallerSave() {
+        return callerSave;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterConfig.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.CallingConvention.*;
+import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.meta.*;
+
+/**
+ * A register configuration binds roles and {@linkplain RegisterAttributes attributes}
+ * to physical registers.
+ */
+public interface RegisterConfig {
+
+    /**
+     * Gets the register to be used for returning a value of a given kind.
+     */
+    Register getReturnRegister(Kind kind);
+
+    /**
+     * Gets the register to which {@link Register#Frame} and {@link Register#CallerFrame} are bound.
+     */
+    Register getFrameRegister();
+
+    Register getScratchRegister();
+
+    /**
+     * Gets the calling convention describing how arguments are passed.
+     *
+     * @param type the type of calling convention being requested
+     * @param parameters the types of the arguments of the call
+     * @param target the target platform
+     * @param stackOnly ignore registers
+     */
+    CallingConvention getCallingConvention(Type type, Kind[] parameters, TargetDescription target, boolean stackOnly);
+
+    /**
+     * Gets the ordered set of registers that are can be used to pass parameters
+     * according to a given calling convention.
+     *
+     * @param type the type of calling convention
+     * @param flag specifies whether registers for {@linkplain RegisterFlag#CPU integral} or
+     *             {@linkplain} RegisterFlag#FPU floating point} parameters are being requested
+     * @return the ordered set of registers that may be used to pass parameters in a call conforming to {@code type}
+     */
+    Register[] getCallingConventionRegisters(Type type, RegisterFlag flag);
+
+    /**
+     * Gets the set of registers that can be used by the register allocator.
+     */
+    Register[] getAllocatableRegisters();
+
+    /**
+     * Gets the set of registers that can be used by the register allocator,
+     * {@linkplain Register#categorize(Register[]) categorized} by register {@linkplain RegisterFlag flags}.
+     *
+     * @return a map from each {@link RegisterFlag} constant to the list of {@linkplain #getAllocatableRegisters()
+     *         allocatable} registers for which the flag is {@linkplain #isSet(RegisterFlag) set}
+     *
+     */
+    EnumMap<RegisterFlag, Register[]> getCategorizedAllocatableRegisters();
+
+    /**
+     * Gets the registers whose values must be preserved by a method across any call it makes.
+     */
+    Register[] getCallerSaveRegisters();
+
+    /**
+     * Gets the layout of the callee save area of this register configuration.
+     *
+     * @return {@code null} if there is no callee save area
+     */
+    CalleeSaveLayout getCalleeSaveLayout();
+
+    /**
+     * Gets a map from register {@linkplain Register#number numbers} to register
+     * {@linkplain RegisterAttributes attributes} for this register configuration.
+     *
+     * @return an array where an element at index i holds the attributes of the register whose number is i
+     * @see Register#categorize(Register[])
+     */
+    RegisterAttributes[] getAttributesMap();
+
+    /**
+     * Gets the register corresponding to a runtime-defined role.
+     *
+     * @param id the identifier of a runtime-defined register role
+     * @return the register playing the role specified by {@code id}
+     */
+    Register getRegisterForRole(int id);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterValue.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance of {@code
+ * CiRegisterValue} for each ({@link Register}, {@link Kind}) pair. Use {@link Register#asValue(Kind)} to
+ * retrieve the canonical {@link RegisterValue} instance for a given (register,kind) pair.
+ */
+public final class RegisterValue extends Value {
+    private static final long serialVersionUID = 7999341472196897163L;
+
+    private final Register reg;
+
+    /**
+     * Should only be called from {@link Register#CiRegister} to ensure canonicalization.
+     */
+    protected RegisterValue(Kind kind, Register register) {
+        super(kind);
+        this.reg = register;
+    }
+
+    @Override
+    public int hashCode() {
+        return (getRegister().number << 4) ^ kind.ordinal();
+    }
+
+    @Override
+    public String toString() {
+        return getRegister().name + kindSuffix();
+    }
+
+    /**
+     * @return the register that contains the value
+     */
+    public Register getRegister() {
+        return reg;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCall.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import static com.oracle.graal.api.meta.Kind.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Enumerates the calls that must be provided by the runtime system. The compiler
+ * may generate code that calls the runtime services for unresolved and slow cases of some
+ * bytecodes.
+ */
+public enum RuntimeCall {
+    UnwindException(Void, Object),
+    Deoptimize(Void),
+    RegisterFinalizer(Void, Object),
+    SetDeoptInfo(Void, Object),
+    CreateNullPointerException(Object),
+    CreateOutOfBoundsException(Object, Int),
+    JavaTimeMillis(Long),
+    JavaTimeNanos(Long),
+    Debug(Void),
+    ArithmeticFrem(Float, Float, Float),
+    ArithmeticDrem(Double, Double, Double),
+    ArithmeticCos(Double, Double),
+    ArithmeticTan(Double, Double),
+    ArithmeticSin(Double, Double),
+    GenericCallback(Object, Object, Object),
+    LogPrimitive(Void, Int, Long, Boolean),
+    LogObject(Void, Object, Boolean, Boolean);
+
+    public final Kind resultKind;
+    public final Kind[] arguments;
+
+    private RuntimeCall(Kind resultKind, Kind... args) {
+        this.resultKind = resultKind;
+        this.arguments = args;
+    }
+
+    public boolean hasSideEffect() {
+        switch (this) {
+            case LogObject:
+            case LogPrimitive:
+                return false;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackSlot.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import static com.oracle.graal.api.meta.Kind.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame
+ * or an incoming stack-based argument in a method's {@linkplain #inCallerFrame() caller's frame}.
+ */
+public final class StackSlot extends Value {
+    private static final long serialVersionUID = -7725071921307318433L;
+
+    private final int offset;
+    private final boolean addFrameSize;
+
+    /**
+     * Gets a {@link StackSlot} instance representing a stack slot at a given index
+     * holding a value of a given kind.
+     *
+     * @param kind The kind of the value stored in the stack slot.
+     * @param offset The offset of the stack slot (in bytes)
+     * @param inCallerFrame Specifies if the offset is relative to the stack pointer,
+     *        or the beginning of the frame (stack pointer + total frame size).
+     */
+    public static StackSlot get(Kind kind, int offset, boolean addFrameSize) {
+        assert kind.stackKind() == kind;
+        assert addFrameSize || offset >= 0;
+
+        if (offset % CACHE_GRANULARITY == 0) {
+            StackSlot[][] cache;
+            int index = offset / CACHE_GRANULARITY;
+            if (!addFrameSize) {
+                cache = OUT_CACHE;
+            } else if (offset >= 0) {
+                cache = IN_CACHE;
+            } else {
+                cache = SPILL_CACHE;
+                index = -index;
+            }
+            StackSlot[] slots = cache[kind.ordinal()];
+            if (index < slots.length) {
+                StackSlot slot = slots[index];
+                assert slot.kind == kind && slot.offset == offset && slot.addFrameSize == addFrameSize;
+                return slot;
+            }
+        }
+        return new StackSlot(kind, offset, addFrameSize);
+    }
+
+    /**
+     * Private constructor to enforce use of {@link #get()} so that a cache can be used.
+     */
+    private StackSlot(Kind kind, int offset, boolean addFrameSize) {
+        super(kind);
+        this.offset = offset;
+        this.addFrameSize = addFrameSize;
+    }
+
+    /**
+     * Gets the offset of this stack slot, relative to the stack pointer.
+     * @return The offset of this slot (in bytes).
+     */
+    public int offset(int totalFrameSize) {
+        assert totalFrameSize > 0 || !addFrameSize;
+        int result = offset + (addFrameSize ? totalFrameSize : 0);
+        assert result >= 0;
+        return result;
+    }
+
+    public boolean inCallerFrame() {
+        return addFrameSize && offset >= 0;
+    }
+
+    public int rawOffset() {
+        return offset;
+    }
+
+    public boolean rawAddFrameSize() {
+        return addFrameSize;
+    }
+
+    @Override
+    public int hashCode() {
+        return kind.ordinal() ^ (offset << 4) ^ (addFrameSize ? 15 : 0);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof StackSlot) {
+            StackSlot l = (StackSlot) o;
+            return l.kind == kind && l.offset == offset && l.addFrameSize == addFrameSize;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        if (!addFrameSize) {
+            return "out:" + offset + kindSuffix();
+        } else if (offset >= 0) {
+            return "in:" + offset + kindSuffix();
+        } else {
+            return "stack:" + (-offset) + kindSuffix();
+        }
+    }
+
+    /**
+     * Gets this stack slot used to pass an argument from the perspective of a caller.
+     */
+    public StackSlot asOutArg() {
+        assert offset >= 0;
+        if (addFrameSize) {
+            return get(kind, offset, false);
+        }
+        return this;
+    }
+
+    /**
+     * Gets this stack slot used to pass an argument from the perspective of a callee.
+     */
+    public StackSlot asInArg() {
+        assert offset >= 0;
+        if (!addFrameSize) {
+            return get(kind, offset, true);
+        }
+        return this;
+    }
+
+
+    private static final int CACHE_GRANULARITY = 8;
+    private static final int SPILL_CACHE_PER_KIND_SIZE = 100;
+    private static final int PARAM_CACHE_PER_KIND_SIZE = 10;
+
+    private static final StackSlot[][] SPILL_CACHE = makeCache(SPILL_CACHE_PER_KIND_SIZE, -1, true);
+    private static final StackSlot[][] IN_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, true);
+    private static final StackSlot[][] OUT_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, false);
+
+    private static StackSlot[][] makeCache(int cachePerKindSize, int sign, boolean addFrameSize) {
+        StackSlot[][] cache = new StackSlot[Kind.VALUES.length][];
+        for (Kind kind : new Kind[] {Illegal, Int, Long, Float, Double, Object, Jsr}) {
+            StackSlot[] slots = new StackSlot[cachePerKindSize];
+            for (int i = 0; i < cachePerKindSize; i++) {
+                slots[i] = new StackSlot(kind, sign * i * CACHE_GRANULARITY, addFrameSize);
+            }
+            cache[kind.ordinal()] = slots;
+        }
+        return cache;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+
+/**
+ * Represents the target machine for a compiler, including the CPU architecture, the size of pointers and references,
+ * alignment of stacks, caches, etc.
+ */
+public class TargetDescription {
+    public final Architecture arch;
+
+    /**
+     * The OS page size.
+     */
+    public final int pageSize;
+
+    /**
+     * Specifies if this is a multi-processor system.
+     */
+    public final boolean isMP;
+
+    /**
+     * Specifies if this target supports encoding objects inline in the machine code.
+     */
+    public final boolean inlineObjects;
+
+    /**
+     * The machine word size on this target.
+     */
+    public final int wordSize;
+
+    /**
+     * The CiKind to be used for representing raw pointers and CPU registers.
+     */
+    public final Kind wordKind;
+
+    /**
+     * The stack alignment requirement of the platform. For example,
+     * from Appendix D of <a href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures Optimization Reference Manual</a>:
+     * <pre>
+     *     "It is important to ensure that the stack frame is aligned to a
+     *      16-byte boundary upon function entry to keep local __m128 data,
+     *      parameters, and XMM register spill locations aligned throughout
+     *      a function invocation."
+     * </pre>
+     */
+    public final int stackAlignment;
+
+    /**
+     * @see http://docs.sun.com/app/docs/doc/806-0477/6j9r2e2b9?a=view
+     */
+    public final int stackBias;
+
+    /**
+     * The cache alignment.
+     */
+    public final int cacheAlignment;
+
+    /**
+     * Specifies how {@code long} and {@code double} constants are to be stored
+     * in {@linkplain BytecodeFrame frames}. This is useful for VMs such as HotSpot
+     * where convention the interpreter uses is that the second local
+     * holds the first raw word of the native long or double representation.
+     * This is actually reasonable, since locals and stack arrays
+     * grow downwards in all implementations.
+     * If, on some machine, the interpreter's Java locals or stack
+     * were to grow upwards, the embedded doubles would be word-swapped.)
+     */
+    public final boolean debugInfoDoubleWordsInSecondSlot;
+
+    /**
+     * Temporary flag to distinguish between the semantics necessary for HotSpot and Maxine.
+     */
+    // TODO This should go away when XIR goes away, and the logic be part of the VM-specific lowering.
+    public final boolean invokeSnippetAfterArguments;
+
+    public TargetDescription(Architecture arch,
+             boolean isMP,
+             int stackAlignment,
+             int pageSize,
+             int cacheAlignment,
+             boolean inlineObjects,
+             boolean debugInfoDoubleWordsInSecondSlot,
+             boolean invokeSnippetAfterArguments) {
+        this.arch = arch;
+        this.pageSize = pageSize;
+        this.isMP = isMP;
+        this.wordSize = arch.wordSize;
+        if (wordSize == 8) {
+            this.wordKind = Kind.Long;
+        } else {
+            this.wordKind = Kind.Int;
+        }
+        this.stackAlignment = stackAlignment;
+        this.stackBias = 0; // TODO: configure with param once SPARC port exists
+        this.cacheAlignment = cacheAlignment;
+        this.inlineObjects = inlineObjects;
+        this.debugInfoDoubleWordsInSecondSlot = debugInfoDoubleWordsInSecondSlot;
+        this.invokeSnippetAfterArguments = invokeSnippetAfterArguments;
+    }
+
+    /**
+     * Gets the size in bytes of the specified kind for this target.
+     *
+     * @param kind the kind for which to get the size
+     * @return the size in bytes of {@code kind}
+     */
+    public int sizeInBytes(Kind kind) {
+        // Checkstyle: stop
+        switch (kind) {
+            case Boolean: return 1;
+            case Byte: return 1;
+            case Char: return 2;
+            case Short: return 2;
+            case Int: return 4;
+            case Long: return 8;
+            case Float: return 4;
+            case Double: return 8;
+            case Object: return wordSize;
+            case Jsr: return 4;
+            default: return 0;
+        }
+        // Checkstyle: resume
+    }
+
+    /**
+     * Aligns the given frame size (without return instruction pointer) to the stack
+     * alignment size and return the aligned size (without return instruction pointer).
+     * @param frameSize the initial frame size to be aligned
+     * @return the aligned frame size
+     */
+    public int alignFrameSize(int frameSize) {
+        int x = frameSize + arch.returnAddressSize + (stackAlignment - 1);
+        return (x / stackAlignment) * stackAlignment - arch.returnAddressSize;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+public class ValueUtil {
+    public static boolean isIllegal(Value value) {
+        assert value != null;
+        return value == Value.IllegalValue;
+    }
+
+    public static boolean isLegal(Value value) {
+        return !isIllegal(value);
+    }
+
+    public static boolean isVirtualObject(Value value) {
+        assert value != null;
+        return value instanceof VirtualObject;
+    }
+
+    public static VirtualObject asVirtualObject(Value value) {
+        assert value != null;
+        return (VirtualObject) value;
+    }
+
+    public static boolean isConstant(Value value) {
+        assert value != null;
+        return value instanceof Constant;
+    }
+
+    public static Constant asConstant(Value value) {
+        assert value != null;
+        return (Constant) value;
+    }
+
+
+    public static boolean isStackSlot(Value value) {
+        assert value != null;
+        return value instanceof StackSlot;
+    }
+
+    public static StackSlot asStackSlot(Value value) {
+        assert value != null;
+        return (StackSlot) value;
+    }
+
+    public static boolean isAddress(Value value) {
+        assert value != null;
+        return value instanceof Address;
+    }
+
+    public static Address asAddress(Value value) {
+        assert value != null;
+        return (Address) value;
+    }
+
+
+    public static boolean isRegister(Value value) {
+        assert value != null;
+        return value instanceof RegisterValue;
+    }
+
+    public static Register asRegister(Value value) {
+        assert value != null;
+        return ((RegisterValue) value).getRegister();
+    }
+
+    public static Register asIntReg(Value value) {
+        assert value.kind == Kind.Int || value.kind == Kind.Jsr;
+        return asRegister(value);
+    }
+
+    public static Register asLongReg(Value value) {
+        assert value.kind == Kind.Long : value.kind;
+        return asRegister(value);
+    }
+
+    public static Register asObjectReg(Value value) {
+        assert value.kind == Kind.Object;
+        return asRegister(value);
+    }
+
+    public static Register asFloatReg(Value value) {
+        assert value.kind == Kind.Float;
+        return asRegister(value);
+    }
+
+    public static Register asDoubleReg(Value value) {
+        assert value.kind == Kind.Double;
+        return asRegister(value);
+    }
+
+
+    public static boolean sameRegister(Value v1, Value v2) {
+        return isRegister(v1) && isRegister(v2) && asRegister(v1) == asRegister(v2);
+    }
+
+    public static boolean sameRegister(Value v1, Value v2, Value v3) {
+        return sameRegister(v1, v2) && sameRegister(v1, v3);
+    }
+
+    public static boolean differentRegisters(Value v1, Value v2) {
+        return !isRegister(v1) || !isRegister(v2) || asRegister(v1) != asRegister(v2);
+    }
+
+    public static boolean differentRegisters(Value v1, Value v2, Value v3) {
+        return differentRegisters(v1, v2) && differentRegisters(v1, v3) && differentRegisters(v2, v3);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * An instance of this class represents an object whose allocation was removed by escape analysis. The information stored in the {@link VirtualObject} is used during
+ * deoptimization to recreate the object.
+ */
+public final class VirtualObject extends Value {
+    private static final long serialVersionUID = -2907197776426346021L;
+
+    private final JavaType type;
+    private Value[] values;
+    private final int id;
+
+    /**
+     * Creates a new CiVirtualObject for the given type, with the given fields. If the type is an instance class then the values array needs to have one entry for each field, ordered in
+     * like the fields returned by {@link ResolvedJavaType#declaredFields()}. If the type is an array then the length of the values array determines the reallocated array length.
+     * @param type the type of the object whose allocation was removed during compilation. This can be either an instance of an array type.
+     * @param values an array containing all the values to be stored into the object when it is recreated.
+     * @param id a unique id that identifies the object within the debug information for one position in the compiled code.
+     * @return a new CiVirtualObject instance.
+     */
+    public static VirtualObject get(JavaType type, Value[] values, int id) {
+        return new VirtualObject(type, values, id);
+    }
+
+    private VirtualObject(JavaType type, Value[] values, int id) {
+        super(Kind.Object);
+        this.type = type;
+        this.values = values;
+        this.id = id;
+    }
+
+    @Override
+    public String toString() {
+        return "vobject:" + id;
+    }
+
+    /**
+     * @return the type of the object whose allocation was removed during compilation. This can be either an instance of an array type.
+     */
+    public JavaType type() {
+        return type;
+    }
+
+    /**
+     * @return an array containing all the values to be stored into the object when it is recreated.
+     */
+    public Value[] values() {
+        return values;
+    }
+
+    /**
+     * @return the unique id that identifies the object within the debug information for one position in the compiled code.
+     */
+    public int id() {
+        return id;
+    }
+
+    /**
+     * Overwrites the current set of values with a new one.
+     * @param values an array containing all the values to be stored into the object when it is recreated.
+     */
+    public void setValues(Value[] values) {
+        this.values = values;
+    }
+
+    @Override
+    public int hashCode() {
+        return kind.ordinal() + type.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o instanceof VirtualObject) {
+            VirtualObject l = (VirtualObject) o;
+            if (l.type != type || l.values.length != values.length) {
+                return false;
+            }
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] != l.values[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/package-info.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010, 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 that defines the interface between a Java application that wants to install code and the runtime.
+ */
+package com.oracle.graal.api.code;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/Interpreter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,29 @@
+/*
+ * 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.api.interpreter;
+
+import com.oracle.graal.api.meta.*;
+
+public interface Interpreter extends VirtualMachineComponent {
+    Object execute(ResolvedJavaMethod method, Object... arguments);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/CodeInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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.api.meta;
+
+/**
+ * Represents some code installed in the code cache of the runtime.
+ * This encapsulated details are only for informational purposes.
+ * At any time, the runtime may invalidate the underlying code (e.g. due to deopt etc).
+ */
+public interface CodeInfo {
+
+    /**
+     * Gets the start address of this installed code.
+     */
+    long start();
+
+    /**
+     * Gets a copy of this installed code.
+     */
+    byte[] code();
+
+    /**
+     * Gets the method (if any) from which this installed code was compiled.
+     */
+    ResolvedJavaMethod method();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents a constant (boxed) value, such as an integer, floating point number, or object reference,
+ * within the compiler and across the compiler/runtime interface. Exports a set of {@code Constant}
+ * instances that represent frequently used constant values, such as {@link #ZERO}.
+ */
+public final class Constant extends Value {
+    private static final long serialVersionUID = -6355452536852663986L;
+
+    private static final Constant[] INT_CONSTANT_CACHE = new Constant[100];
+    static {
+        for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) {
+            INT_CONSTANT_CACHE[i] = new Constant(Kind.Int, i);
+        }
+    }
+
+    public static final Constant NULL_OBJECT = new Constant(Kind.Object, null);
+    public static final Constant INT_MINUS_1 = new Constant(Kind.Int, -1);
+    public static final Constant INT_0 = forInt(0);
+    public static final Constant INT_1 = forInt(1);
+    public static final Constant INT_2 = forInt(2);
+    public static final Constant INT_3 = forInt(3);
+    public static final Constant INT_4 = forInt(4);
+    public static final Constant INT_5 = forInt(5);
+    public static final Constant LONG_0 = new Constant(Kind.Long, 0L);
+    public static final Constant LONG_1 = new Constant(Kind.Long, 1L);
+    public static final Constant FLOAT_0 = new Constant(Kind.Float, Float.floatToRawIntBits(0.0F));
+    public static final Constant FLOAT_1 = new Constant(Kind.Float, Float.floatToRawIntBits(1.0F));
+    public static final Constant FLOAT_2 = new Constant(Kind.Float, Float.floatToRawIntBits(2.0F));
+    public static final Constant DOUBLE_0 = new Constant(Kind.Double, Double.doubleToRawLongBits(0.0D));
+    public static final Constant DOUBLE_1 = new Constant(Kind.Double, Double.doubleToRawLongBits(1.0D));
+    public static final Constant TRUE = new Constant(Kind.Boolean, 1L);
+    public static final Constant FALSE = new Constant(Kind.Boolean, 0L);
+
+    static {
+        assert FLOAT_0 != forFloat(-0.0F) : "Constant for 0.0f must be different from -0.0f";
+        assert DOUBLE_0 != forDouble(-0.0d) : "Constant for 0.0d must be different from -0.0d";
+        assert NULL_OBJECT.isNull();
+    }
+
+    /**
+     * The boxed object value. This is ignored iff {@code !kind.isObject()}.
+     */
+    private final Object object;
+
+    /**
+     * The boxed primitive value as a {@code long}. This is ignored iff {@code kind.isObject()}.
+     * For {@code float} and {@code double} values, this value is the result of
+     * {@link Float#floatToRawIntBits(float)} and {@link Double#doubleToRawLongBits(double)} respectively.
+     */
+    private final long primitive;
+
+    /**
+     * Create a new constant represented by the specified object reference.
+     *
+     * @param kind the type of this constant
+     * @param object the value of this constant
+     */
+    private Constant(Kind kind, Object object) {
+        super(kind);
+        this.object = object;
+        this.primitive = 0L;
+    }
+
+    /**
+     * Create a new constant represented by the specified primitive.
+     *
+     * @param kind the type of this constant
+     * @param primitive the value of this constant
+     */
+    public Constant(Kind kind, long primitive) {
+        super(kind);
+        this.object = null;
+        this.primitive = primitive;
+    }
+
+    /**
+     * Checks whether this constant is non-null.
+     * @return {@code true} if this constant is a primitive, or an object constant that is not null
+     */
+    public boolean isNonNull() {
+        return !kind.isObject() || object != null;
+    }
+
+    /**
+     * Checks whether this constant is null.
+     * @return {@code true} if this constant is the null constant
+     */
+    public boolean isNull() {
+        return kind.isObject() && object == null;
+    }
+
+    @Override
+    public String toString() {
+        return kind.javaName + "[" + kind.format(boxedValue()) + (kind != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]";
+    }
+
+    /**
+     * Gets this constant's value as a string.
+     *
+     * @return this constant's value as a string
+     */
+    public String valueString() {
+        if (kind.isPrimitive()) {
+            return boxedValue().toString();
+        } else if (kind.isObject()) {
+            if (object == null) {
+                return "null";
+            } else if (object instanceof String) {
+                return "\"" + object + "\"";
+            } else {
+                return "<object: " + kind.format(object) + ">";
+            }
+        } else if (kind.isJsr()) {
+            return "bci:" + boxedValue().toString();
+        } else {
+            return "???";
+        }
+    }
+
+    /**
+     * Returns the value of this constant as a boxed Java value.
+     * @return the value of this constant
+     */
+    public Object boxedValue() {
+        // Checkstyle: stop
+        switch (kind) {
+            case Byte: return (byte) asInt();
+            case Boolean: return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE;
+            case Short: return (short) asInt();
+            case Char: return (char) asInt();
+            case Jsr: return (int) primitive;
+            case Int: return asInt();
+            case Long: return asLong();
+            case Float: return asFloat();
+            case Double: return asDouble();
+            case Object: return object;
+        }
+        // Checkstyle: resume
+        throw new IllegalArgumentException();
+    }
+
+    private boolean valueEqual(Constant other, boolean ignoreKind) {
+        // must have equivalent kinds to be equal
+        if (!ignoreKind && kind != other.kind) {
+            return false;
+        }
+        if (kind.isObject()) {
+            return object == other.object;
+        }
+        return primitive == other.primitive;
+    }
+
+    /**
+     * Converts this constant to a primitive int.
+     * @return the int value of this constant
+     */
+    public int asInt() {
+        if (kind.stackKind().isInt() || kind.isJsr()) {
+            return (int) primitive;
+        }
+        throw new Error("Constant is not int: " + this);
+    }
+
+    /**
+     * Converts this constant to a primitive boolean.
+     * @return the boolean value of this constant
+     */
+    public boolean asBoolean() {
+        if (kind == Kind.Boolean) {
+            return primitive != 0L;
+        }
+        throw new Error("Constant is not boolean: " + this);
+    }
+
+    /**
+     * Converts this constant to a primitive long.
+     * @return the long value of this constant
+     */
+    public long asLong() {
+        // Checkstyle: stop
+        switch (kind.stackKind()) {
+            case Jsr:
+            case Int:
+            case Long: return primitive;
+            case Float: return (long) asFloat();
+            case Double: return (long) asDouble();
+            default: throw new Error("Constant is not long: " + this);
+        }
+        // Checkstyle: resume
+    }
+
+    /**
+     * Converts this constant to a primitive float.
+     * @return the float value of this constant
+     */
+    public float asFloat() {
+        if (kind.isFloat()) {
+            return Float.intBitsToFloat((int) primitive);
+        }
+        throw new Error("Constant is not float: " + this);
+    }
+
+    /**
+     * Converts this constant to a primitive double.
+     * @return the double value of this constant
+     */
+    public double asDouble() {
+        if (kind.isFloat()) {
+            return Float.intBitsToFloat((int) primitive);
+        }
+        if (kind.isDouble()) {
+            return Double.longBitsToDouble(primitive);
+        }
+        throw new Error("Constant is not double: " + this);
+    }
+
+    /**
+     * Converts this constant to the object reference it represents.
+     * @return the object which this constant represents
+     */
+    public Object asObject() {
+        if (kind.isObject()) {
+            return object;
+        }
+        throw new Error("Constant is not object: " + this);
+    }
+
+    /**
+     * Converts this constant to the jsr reference it represents.
+     * @return the object which this constant represents
+     */
+    public int asJsr() {
+        if (kind.isJsr()) {
+            return (int) primitive;
+        }
+        throw new Error("Constant is not jsr: " + this);
+    }
+
+    /**
+     * Unchecked access to a primitive value.
+     * @return
+     */
+    public long asPrimitive() {
+        if (kind.isObject()) {
+            throw new Error("Constant is not primitive: " + this);
+        }
+        return primitive;
+    }
+
+    /**
+     * Computes the hashcode of this constant.
+     * @return a suitable hashcode for this constant
+     */
+    @Override
+    public int hashCode() {
+        if (kind.isObject()) {
+            return System.identityHashCode(object);
+        }
+        return (int) primitive;
+    }
+
+    /**
+     * Checks whether this constant equals another object. This is only
+     * true if the other object is a constant and has the same value.
+     * @param o the object to compare equality
+     * @return {@code true} if this constant is equivalent to the specified object
+     */
+    @Override
+    public boolean equals(Object o) {
+        return o == this || o instanceof Constant && valueEqual((Constant) o, false);
+    }
+
+    /**
+     * Creates a boxed double constant.
+     * @param d the double value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forDouble(double d) {
+        if (Double.compare(0.0D, d) == 0) {
+            return DOUBLE_0;
+        }
+        if (Double.compare(d, 1.0D) == 0) {
+            return DOUBLE_1;
+        }
+        return new Constant(Kind.Double, Double.doubleToRawLongBits(d));
+    }
+
+    /**
+     * Creates a boxed float constant.
+     * @param f the float value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forFloat(float f) {
+        if (Float.compare(f, 0.0F) == 0) {
+            return FLOAT_0;
+        }
+        if (Float.compare(f, 1.0F) == 0) {
+            return FLOAT_1;
+        }
+        if (Float.compare(f, 2.0F) == 0) {
+            return FLOAT_2;
+        }
+        return new Constant(Kind.Float, Float.floatToRawIntBits(f));
+    }
+
+    /**
+     * Creates a boxed long constant.
+     * @param i the long value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forLong(long i) {
+        return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new Constant(Kind.Long, i);
+    }
+
+    /**
+     * Creates a boxed integer constant.
+     * @param i the integer value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forInt(int i) {
+        if (i == -1) {
+            return INT_MINUS_1;
+        }
+        if (i >= 0 && i < INT_CONSTANT_CACHE.length) {
+            return INT_CONSTANT_CACHE[i];
+        }
+        return new Constant(Kind.Int, i);
+    }
+
+    /**
+     * Creates a boxed byte constant.
+     * @param i the byte value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forByte(byte i) {
+        return new Constant(Kind.Byte, i);
+    }
+
+    /**
+     * Creates a boxed boolean constant.
+     * @param i the boolean value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forBoolean(boolean i) {
+        return i ? TRUE : FALSE;
+    }
+
+    /**
+     * Creates a boxed char constant.
+     * @param i the char value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forChar(char i) {
+        return new Constant(Kind.Char, i);
+    }
+
+    /**
+     * Creates a boxed short constant.
+     * @param i the short value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forShort(short i) {
+        return new Constant(Kind.Short, i);
+    }
+
+    /**
+     * Creates a boxed address (jsr/ret address) constant.
+     * @param i the address value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forJsr(int i) {
+        return new Constant(Kind.Jsr, i);
+    }
+
+    /**
+     * Creates a boxed object constant.
+     * @param o the object value to box
+     * @return a boxed copy of {@code value}
+     */
+    public static Constant forObject(Object o) {
+        if (o == null) {
+            return NULL_OBJECT;
+        }
+        return new Constant(Kind.Object, o);
+    }
+
+    /**
+     * Creates a boxed constant for the given kind from an Object.
+     * The object needs to be of the Java boxed type corresponding to the kind.
+     * @param kind the kind of the constant to create
+     * @param value the Java boxed value: a Byte instance for CiKind Byte, etc.
+     * @return the boxed copy of {@code value}
+     */
+    public static Constant forBoxed(Kind kind, Object value) {
+        switch (kind) {
+            case Boolean:
+                return forBoolean((Boolean) value);
+            case Byte:
+                return forByte((Byte) value);
+            case Char:
+                return forChar((Character) value);
+            case Short:
+                return forShort((Short) value);
+            case Int:
+                return forInt((Integer) value);
+            case Long:
+                return forLong((Long) value);
+            case Float:
+                return forFloat((Float) value);
+            case Double:
+                return forDouble((Double) value);
+            case Object:
+                return forObject(value);
+            default:
+                throw new RuntimeException("cannot create Constant for boxed " + kind + " value");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantPool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents the runtime representation of the constant pool that is
+ * used by the compiler when parsing bytecode. Provides methods to look up a constant
+ * pool entry without performing resolution. They are used during compilation.
+ */
+public interface ConstantPool {
+
+    /**
+     * Makes sure that the type referenced by the specified constant pool entry is loaded and
+     * initialized. This can be used to compile time resolve a type. It works for field, method,
+     * or type constant pool entries.
+     * @param cpi the index of the constant pool entry that references the type
+     * @param opcode the opcode of the instruction that references the type
+     */
+    void loadReferencedType(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a field. If {@code opcode} is non-negative, then resolution checks
+     * specific to the JVM instruction it denotes are performed if the field is already resolved.
+     * Should any of these checks fail, an {@linkplain JavaField#isResolved() unresolved}
+     * field reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
+     * @return a reference to the field at {@code cpi} in this pool
+     * @throws ClassFormatError if the entry at {@code cpi} is not a field
+     */
+    JavaField lookupField(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a method. If {@code opcode} is non-negative, then resolution checks
+     * specific to the JVM instruction it denotes are performed if the method is already resolved.
+     * Should any of these checks fail, an {@linkplain JavaMethod#isResolved() unresolved}
+     * method reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
+     * @return a reference to the method at {@code cpi} in this pool
+     * @throws ClassFormatError if the entry at {@code cpi} is not a method
+     */
+    JavaMethod lookupMethod(int cpi, int opcode);
+
+    /**
+     * Looks up a reference to a type. If {@code opcode} is non-negative, then resolution checks
+     * specific to the JVM instruction it denotes are performed if the type is already resolved.
+     * Should any of these checks fail, an {@linkplain JavaType#isResolved() unresolved}
+     * type reference is returned.
+     *
+     * @param cpi the constant pool index
+     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
+     * @return a reference to the compiler interface type
+     */
+    JavaType lookupType(int cpi, int opcode);
+
+    /**
+     * Looks up a method signature.
+     *
+     * @param cpi the constant pool index
+     * @return the method signature at index {@code cpi} in this constant pool
+     */
+    Signature lookupSignature(int cpi);
+
+    /**
+     * Looks up a constant at the specified index.
+     * @param cpi the constant pool index
+     * @return the {@code Constant} or {@code JavaType} instance representing the constant pool entry
+     */
+    Object lookupConstant(int cpi);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationReason.java	Wed Jun 27 17:35:32 2012 +0200
@@ -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.api.meta;
+
+
+public enum DeoptimizationReason {
+    None,
+    NullCheckException,
+    BoundsCheckException,
+    ClassCastException,
+    ArrayStoreException,
+    UnreachedCode,
+    TypeCheckedInliningViolated,
+    OptimizedTypeCheckViolated,
+    NotCompiledExceptionHandler,
+    Unresolved,
+    JavaSubroutineMismatch,
+    ArithmeticException,
+    RuntimeConstraint;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ExceptionHandler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents an exception handler within the bytecode.
+ */
+public final class ExceptionHandler {
+    private final int startBCI;
+    private final int endBCI;
+    private final int handlerBCI;
+    private final int catchTypeCPI;
+    private final JavaType catchType;
+
+    /**
+     * Creates a new exception handler with the specified ranges.
+     * @param startBCI the start index of the protected range
+     * @param endBCI the end index of the protected range
+     * @param catchBCI the index of the handler
+     * @param catchTypeCPI the index of the throwable class in the constant pool
+     * @param catchType the type caught by this exception handler
+     */
+    public ExceptionHandler(int startBCI, int endBCI, int catchBCI, int catchTypeCPI, JavaType catchType) {
+        this.startBCI = startBCI;
+        this.endBCI = endBCI;
+        this.handlerBCI = catchBCI;
+        this.catchTypeCPI = catchTypeCPI;
+        this.catchType = catchType;
+    }
+
+    /**
+     * Gets the start bytecode index of the protected range of this handler.
+     * @return the start bytecode index
+     */
+    public int startBCI() {
+        return startBCI;
+    }
+
+    /**
+     * Gets the end bytecode index of the protected range of this handler.
+     * @return the end bytecode index
+     */
+    public int endBCI() {
+        return endBCI;
+    }
+
+    /**
+     * Gets the bytecode index of the handler block of this handler.
+     * @return the handler block bytecode index
+     */
+    public int handlerBCI() {
+        return handlerBCI;
+    }
+
+    /**
+     * Gets the index into the constant pool representing the type of exception
+     * caught by this handler.
+     * @return the constant pool index of the catch type
+     */
+    public int catchTypeCPI() {
+        return catchTypeCPI;
+    }
+
+    /**
+     * Checks whether this handler catches all exceptions.
+     * @return {@code true} if this handler catches all exceptions
+     */
+    public boolean isCatchAll() {
+        return catchTypeCPI == 0;
+    }
+
+    /**
+     * The type of exception caught by this exception handler.
+     *
+     * @return the exception type
+     */
+    public JavaType catchType() {
+        return catchType;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ExceptionSeen.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,37 @@
+/*
+ * 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.api.meta;
+
+
+/**
+ * Represents the three possibilities that an exception was seen at a specific BCI.
+ */
+public enum ExceptionSeen {
+    TRUE,
+    FALSE,
+    NOT_SUPPORTED;
+
+    public static ExceptionSeen get(boolean value) {
+        return value ? TRUE : FALSE;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/InstalledCode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents a compiled instance of a method. It may have been invalidated or removed in the meantime.
+ */
+public interface InstalledCode {
+
+    public abstract class MethodInvalidatedException extends RuntimeException {
+
+        private static final long serialVersionUID = -3540232440794244844L;
+    }
+
+    /**
+     * Returns the method to which the compiled code belongs.
+     * @return the method to which the compiled code belongs.
+     */
+    ResolvedJavaMethod method();
+
+    /**
+     * @return true if the code represented by this object is still valid, false otherwise (may happen due to deopt, etc.)
+     */
+    boolean isValid();
+
+    Object execute(Object arg1, Object arg2, Object arg3);
+
+    Object executeVarargs(Object... args);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents a reference to a Java field, including both resolved and unresolved fields. Fields, like methods and types, are
+ * resolved through {@link ConstantPool constant pools}.
+ */
+public interface JavaField {
+    /**
+     * Gets the name of this field as a string.
+     * @return the name of this field
+     */
+    String name();
+
+    /**
+     * Gets the type of this field as a compiler-runtime interface type.
+     * @return the type of this field
+     */
+    JavaType type();
+
+    /**
+     * Gets the kind of this field.
+     * @return the kind
+     */
+    Kind kind();
+
+    /**
+     * Gets the holder of this field as a compiler-runtime interface type.
+     * @return the holder of this field
+     */
+    JavaType holder();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethod.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents resolved and unresolved Java methods. Methods, like fields and types, are resolved through
+ * {@link ConstantPool constant pools}.
+ */
+public interface JavaMethod {
+
+    /**
+     * Gets the name of the method as a string.
+     * @return the name of the method
+     */
+    String name();
+
+    /**
+     * Gets the type in which this method is declared.
+     * @return the type in which this method is declared
+     */
+    JavaType holder();
+
+    /**
+     * Gets the signature of the method.
+     * @return the signature of the method
+     */
+    Signature signature();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents a resolved or unresolved type in the compiler-runtime interface. Types include primitives, objects, {@code void},
+ * and arrays thereof.
+ */
+public interface JavaType {
+
+    /**
+     * Represents each of the several different parts of the runtime representation of
+     * a type which compiled code may need to reference individually. These may or may not be
+     * different objects or data structures, depending on the runtime system.
+     */
+    public enum Representation {
+        /**
+         * The runtime representation of the data structure containing the static fields of this type.
+         */
+        StaticFields,
+
+        /**
+         * The runtime representation of the Java class object of this type.
+         */
+        JavaClass,
+
+        /**
+         * The runtime representation of the "hub" of this type--that is, the closest part of the type
+         * representation which is typically stored in the object header.
+         */
+        ObjectHub
+    }
+
+    /**
+     * Gets the name of this type in internal form. The following are examples of strings returned by this method:
+     * <pre>
+     *     "Ljava/lang/Object;"
+     *     "I"
+     *     "[[B"
+     * </pre>
+     *
+     * @return the name of this type in internal form
+     */
+    String name();
+
+    /**
+     * For array types, gets the type of the components.
+     * @return the component type of this array type
+     */
+    JavaType componentType();
+
+    /**
+     * Gets the type representing an array with elements of this type.
+     * @return a new compiler interface type representing an array of this type
+     */
+    JavaType arrayOf();
+
+    /**
+     * Gets the kind of this compiler interface type.
+     * @return the kind
+     */
+    Kind kind();
+
+    /**
+     * Gets the kind used to represent the specified part of this type.
+     * @param r the part of the this type
+     * @return the kind of constants for the specified part of the type
+     */
+    Kind getRepresentationKind(Representation r);
+
+    /**
+     * Resolved this Java type and returns the result.
+     * @param accessingClass the class that requests resolving this type
+     * @return the resolved Java type
+     */
+    ResolvedJavaType resolve(ResolvedJavaType accessingClass);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.io.*;
+
+/**
+ * This profile object represents the type profile at a specific BCI. The precision of the supplied values may vary,
+ * but a runtime that provides this information should be aware that it will be used to guide performance-critical
+ * decisions like speculative inlining, etc.
+ */
+public final class JavaTypeProfile implements Serializable {
+
+    private static final long serialVersionUID = -6877016333706838441L;
+
+    /**
+     * A profiled type that has a probability. Profiled types are naturally sorted in
+     * descending order of their probabilities.
+     */
+    public static class ProfiledType implements Comparable<ProfiledType>, Serializable {
+        private static final long serialVersionUID = 7838575753661305744L;
+        public final ResolvedJavaType type;
+        public final double probability;
+
+        public ProfiledType(ResolvedJavaType type, double probability) {
+            assert type != null;
+            assert probability >= 0.0D && probability <= 1.0D;
+            this.type = type;
+            this.probability = probability;
+        }
+
+        @Override
+        public int compareTo(ProfiledType o) {
+            if (probability > o.probability) {
+                return -1;
+            } else if (probability < o.probability) {
+                return 1;
+            }
+            return 0;
+        }
+    }
+
+    private final double notRecordedProbability;
+    private final ProfiledType[] ptypes;
+
+    /**
+     * Determines if an array of profiled types are sorted in descending order of their probabilities.
+     */
+    public static boolean isSorted(ProfiledType[] ptypes) {
+        for (int i = 1; i < ptypes.length; i++) {
+            if (ptypes[i - 1].probability < ptypes[i].probability) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public JavaTypeProfile(double notRecordedProbability, ProfiledType... ptypes) {
+        this.ptypes = ptypes;
+        this.notRecordedProbability = notRecordedProbability;
+        assert isSorted(ptypes);
+    }
+
+    /**
+     * Returns the estimated probability of all types that could not be recorded due to profiling limitations.
+     * @return double value >= 0.0 and <= 1.0
+     */
+    public double getNotRecordedProbability() {
+        return notRecordedProbability;
+    }
+
+    /**
+     * A list of types for which the runtime has recorded probability information.
+     */
+    public ProfiledType[] getTypes() {
+        return ptypes;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import static com.oracle.graal.api.meta.Kind.Flags.*;
+
+import java.lang.reflect.*;
+
+import sun.misc.*;
+
+/**
+ * Denotes the basic kinds of types in CRI, including the all the Java primitive types,
+ * for example, {@link Kind#Int} for {@code int} and {@link Kind#Object}
+ * for all object types.
+ * A kind has a single character short name, a Java name, and a set of flags
+ * further describing its behavior.
+ */
+public enum Kind {
+    Boolean('z', "boolean", PRIMITIVE | STACK_INT),
+    Byte   ('b', "byte",    PRIMITIVE | STACK_INT),
+    Short  ('s', "short",   PRIMITIVE | STACK_INT),
+    Char   ('c', "char",    PRIMITIVE | STACK_INT),
+    Int    ('i', "int",     PRIMITIVE | STACK_INT),
+    Float  ('f', "float",   PRIMITIVE),
+    Long   ('j', "long",    PRIMITIVE),
+    Double ('d', "double",  PRIMITIVE),
+    Object ('a', "Object",  0),
+    Void   ('v', "void",    0),
+    /** Denote a bytecode address in a {@code JSR} bytecode. */
+    Jsr    ('r', "jsr",     0),
+    /** The non-type. */
+    Illegal('-', "illegal", 0);
+
+    public static final Kind[] VALUES = values();
+    public static final Kind[] JAVA_VALUES = new Kind[] {Kind.Boolean, Kind.Byte, Kind.Short, Kind.Char, Kind.Int, Kind.Float, Kind.Long, Kind.Double, Kind.Object};
+
+    Kind(char ch, String name, int flags) {
+        this.typeChar = ch;
+        this.javaName = name;
+        this.flags = flags;
+    }
+
+    static class Flags {
+        /**
+         * Behaves as an integer when on Java evaluation stack.
+         */
+        public static final int STACK_INT   = 0x0004;
+        /**
+         * Represents a Java primitive type.
+         */
+        public static final int PRIMITIVE   = 0x0008;
+    }
+
+    /**
+     * The flags for this kind.
+     */
+    private final int flags;
+
+    /**
+     * The name of the kind as a single character.
+     */
+    public final char typeChar;
+
+    /**
+     * The name of this kind which will also be it Java programming language name if
+     * it is {@linkplain #isPrimitive() primitive} or {@code void}.
+     */
+    public final String javaName;
+
+    /**
+     * Checks whether this type is valid as an {@code int} on the Java operand stack.
+     * @return {@code true} if this type is represented by an {@code int} on the operand stack
+     */
+    public boolean isInt() {
+        return (flags & STACK_INT) != 0;
+    }
+
+    /**
+     * Checks whether this type is a Java primitive type.
+     * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, {@link #Short},
+     *                                 {@link #Int}, {@link #Long}, {@link #Float} or {@link #Double}.
+     */
+    public boolean isPrimitive() {
+        return (flags & PRIMITIVE) != 0;
+    }
+
+    /**
+     * Gets the kind that represents this kind when on the Java operand stack.
+     * @return the kind used on the operand stack
+     */
+    public Kind stackKind() {
+        if (isInt()) {
+            return Int;
+        }
+        return this;
+    }
+
+    public static Kind fromTypeString(String typeString) {
+        assert typeString.length() > 0;
+        final char first = typeString.charAt(0);
+        if (first == '[' || first == 'L') {
+            return Kind.Object;
+        }
+        return Kind.fromPrimitiveOrVoidTypeChar(first);
+    }
+
+    /**
+     * Gets the kind from the character describing a primitive or void.
+     * @param ch the character
+     * @return the kind
+     */
+    public static Kind fromPrimitiveOrVoidTypeChar(char ch) {
+        // Checkstyle: stop
+        switch (ch) {
+            case 'Z': return Boolean;
+            case 'C': return Char;
+            case 'F': return Float;
+            case 'D': return Double;
+            case 'B': return Byte;
+            case 'S': return Short;
+            case 'I': return Int;
+            case 'J': return Long;
+            case 'V': return Void;
+        }
+        // Checkstyle: resume
+        throw new IllegalArgumentException("unknown primitive or void type character: " + ch);
+    }
+
+    public Class< ? > toJavaClass() {
+        // Checkstyle: stop
+        switch(this) {
+            case Void:      return java.lang.Void.TYPE;
+            case Long:      return java.lang.Long.TYPE;
+            case Int:       return java.lang.Integer.TYPE;
+            case Byte:      return java.lang.Byte.TYPE;
+            case Char:      return java.lang.Character.TYPE;
+            case Double:    return java.lang.Double.TYPE;
+            case Float:     return java.lang.Float.TYPE;
+            case Short:     return java.lang.Short.TYPE;
+            case Boolean:   return java.lang.Boolean.TYPE;
+            default:        return null;
+        }
+        // Checkstyle: resume
+    }
+
+    public Class< ? > toBoxedJavaClass() {
+        // Checkstyle: stop
+        switch(this) {
+            case Void:      return null;
+            case Long:      return java.lang.Long.class;
+            case Int:       return java.lang.Integer.class;
+            case Byte:      return java.lang.Byte.class;
+            case Char:      return java.lang.Character.class;
+            case Double:    return java.lang.Double.class;
+            case Float:     return java.lang.Float.class;
+            case Short:     return java.lang.Short.class;
+            case Boolean:   return java.lang.Boolean.class;
+            default:        return null;
+        }
+        // Checkstyle: resume
+    }
+
+    /**
+     * Checks whether this value type is void.
+     * @return {@code true} if this type is void
+     */
+    public final boolean isVoid() {
+        return this == Kind.Void;
+    }
+
+    /**
+     * Checks whether this value type is long.
+     * @return {@code true} if this type is long
+     */
+    public final boolean isLong() {
+        return this == Kind.Long;
+    }
+
+    /**
+     * Checks whether this value type is float.
+     * @return {@code true} if this type is float
+     */
+    public final boolean isFloat() {
+        return this == Kind.Float;
+    }
+
+    /**
+     * Checks whether this value type is double.
+     * @return {@code true} if this type is double
+     */
+    public final boolean isDouble() {
+        return this == Kind.Double;
+    }
+
+    /**
+     * Checks whether this value type is float or double.
+     * @return {@code true} if this type is float or double
+     */
+    public final boolean isFloatOrDouble() {
+        return this == Kind.Double || this == Kind.Float;
+    }
+
+   /**
+     * Checks whether this value type is an object type.
+     * @return {@code true} if this type is an object
+     */
+    public final boolean isObject() {
+        return this == Kind.Object;
+    }
+
+    /**
+     * Checks whether this value type is an address type.
+     * @return {@code true} if this type is an address
+     */
+    public boolean isJsr() {
+        return this == Kind.Jsr;
+    }
+
+    /**
+     * Converts this value type to a string.
+     */
+    @Override
+    public String toString() {
+        return javaName;
+    }
+
+    /**
+     * Marker interface for types that should be {@linkplain Kind#format(Object) formatted}
+     * with their {@link Object#toString()} value.
+     */
+    public interface FormatWithToString {}
+
+    /**
+     * Gets a formatted string for a given value of this kind.
+     *
+     * @param value a value of this kind
+     * @return a formatted string for {@code value} based on this kind
+     */
+    public String format(Object value) {
+        if (isObject()) {
+            if (value == null) {
+                return "null";
+            } else {
+                if (value instanceof String) {
+                    String s = (String) value;
+                    if (s.length() > 50) {
+                        return "\"" + s.substring(0, 30) + "...\"";
+                    } else {
+                        return " \"" + s + '"';
+                    }
+                } else if (value instanceof JavaType) {
+                    return "class " + MetaUtil.toJavaName((JavaType) value);
+                } else if (value instanceof Enum || value instanceof FormatWithToString) {
+                    return String.valueOf(value);
+                } else if (value instanceof Class< ? >) {
+                    return ((Class< ? >) value).getName() + ".class";
+                } else if (value.getClass().isArray()) {
+                    return formatArray(value);
+                } else {
+                    return MetaUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value);
+                }
+            }
+        } else {
+            return value.toString();
+        }
+    }
+
+    private static final int MAX_FORMAT_ARRAY_LENGTH = Integer.getInteger("maxFormatArrayLength", 5);
+
+    private static String formatArray(Object array) {
+        Class< ? > componentType = array.getClass().getComponentType();
+        assert componentType != null;
+        int arrayLength = Array.getLength(array);
+        StringBuilder buf = new StringBuilder(MetaUtil.getSimpleName(componentType, true)).
+                        append('[').
+                        append(arrayLength).
+                        append("]{");
+        int length = Math.min(MAX_FORMAT_ARRAY_LENGTH, arrayLength);
+        boolean primitive = componentType.isPrimitive();
+        for (int i = 0; i < length; i++) {
+            if (primitive) {
+                buf.append(Array.get(array, i));
+            } else {
+                Object o = ((Object[]) array)[i];
+                buf.append(Kind.Object.format(o));
+            }
+            if (i != length - 1) {
+                buf.append(", ");
+            }
+        }
+        if (arrayLength != length) {
+            buf.append(", ...");
+        }
+        return buf.append('}').toString();
+    }
+
+    public final char signatureChar() {
+        return Character.toUpperCase(typeChar);
+    }
+
+    public final int arrayBaseOffset() {
+        switch(this) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_BASE_OFFSET;
+            case Char:
+                return Unsafe.ARRAY_CHAR_BASE_OFFSET;
+            case Short:
+                return Unsafe.ARRAY_SHORT_BASE_OFFSET;
+            case Int:
+                return Unsafe.ARRAY_INT_BASE_OFFSET;
+            case Long:
+                return Unsafe.ARRAY_LONG_BASE_OFFSET;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+            default:
+                assert false : "unexpected kind: " + this;
+                return -1;
+        }
+    }
+
+    public final int arrayIndexScale() {
+        switch(this) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_INDEX_SCALE;
+            case Char:
+                return Unsafe.ARRAY_CHAR_INDEX_SCALE;
+            case Short:
+                return Unsafe.ARRAY_SHORT_INDEX_SCALE;
+            case Int:
+                return Unsafe.ARRAY_INT_INDEX_SCALE;
+            case Long:
+                return Unsafe.ARRAY_LONG_INDEX_SCALE;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+            default:
+                assert false : "unexpected kind: " + this;
+                return -1;
+        }
+    }
+
+    public Constant readUnsafeConstant(Object value, long displacement) {
+        assert value != null;
+        Unsafe u = Unsafe.getUnsafe();
+        switch(this) {
+            case Boolean:
+                return Constant.forBoolean(u.getBoolean(value, displacement));
+            case Byte:
+                return Constant.forByte(u.getByte(value, displacement));
+            case Char:
+                return Constant.forChar(u.getChar(value, displacement));
+            case Short:
+                return Constant.forShort(u.getShort(value, displacement));
+            case Int:
+                return Constant.forInt(u.getInt(value, displacement));
+            case Long:
+                return Constant.forLong(u.getLong(value, displacement));
+            case Float:
+                return Constant.forFloat(u.getFloat(value, displacement));
+            case Double:
+                return Constant.forDouble(u.getDouble(value, displacement));
+            case Object:
+                return Constant.forObject(u.getObject(value, displacement));
+            default:
+                assert false : "unexpected kind: " + this;
+                return null;
+        }
+    }
+
+    public long minValue() {
+        switch (this) {
+            case Boolean:
+                return 0;
+            case Byte:
+                return java.lang.Byte.MIN_VALUE;
+            case Char:
+                return java.lang.Character.MIN_VALUE;
+            case Short:
+                return java.lang.Short.MIN_VALUE;
+            case Jsr:
+            case Int:
+                return java.lang.Integer.MIN_VALUE;
+            case Long:
+                return java.lang.Long.MIN_VALUE;
+            default:
+                throw new IllegalArgumentException("illegal call to minValue on " + this);
+        }
+    }
+
+    public long maxValue() {
+        switch (this) {
+            case Boolean:
+                return 1;
+            case Byte:
+                return java.lang.Byte.MAX_VALUE;
+            case Char:
+                return java.lang.Character.MAX_VALUE;
+            case Short:
+                return java.lang.Short.MAX_VALUE;
+            case Jsr:
+            case Int:
+                return java.lang.Integer.MAX_VALUE;
+            case Long:
+                return java.lang.Long.MAX_VALUE;
+            default:
+                throw new IllegalArgumentException("illegal call to maxValue on " + this);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.lang.reflect.*;
+
+
+public interface MetaAccessProvider {
+
+
+    /**
+     * Returns the JavaType object representing the base type for the given kind.
+     */
+    ResolvedJavaType getResolvedJavaType(Kind kind);
+
+    /**
+     * Returns the type of the given constant object.
+     *
+     * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()}
+     */
+    ResolvedJavaType getTypeOf(Constant constant);
+
+
+    ResolvedJavaType getResolvedJavaType(Class<?> clazz);
+
+    /**
+     * Used by the canonicalizer to compare objects, since a given runtime might not want to expose the real objects to the compiler.
+     *
+     * @return true if the two parameters represent the same runtime object, false otherwise
+     */
+    boolean areConstantObjectsEqual(Constant x, Constant y);
+
+    /**
+     * Provides the {@link JavaMethod} for a {@link Method} obtained via reflection.
+     */
+    ResolvedJavaMethod getResolvedJavaMethod(Method reflectionMethod);
+
+    /**
+     * Gets the length of the array that is wrapped in a Constant object.
+     */
+    int getArrayLength(Constant array);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+
+public class MetaUtil {
+    /**
+     * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for anonymous and local
+     * classes.
+     *
+     * @param clazz the class for which the simple name is being requested
+     * @param withEnclosingClass specifies if the returned name should be qualified with the name(s) of the enclosing
+     *            class/classes of {@code clazz} (if any). This option is ignored if {@code clazz} denotes an anonymous
+     *            or local class.
+     * @return the simple name
+     */
+    public static String getSimpleName(Class< ? > clazz, boolean withEnclosingClass) {
+        final String simpleName = clazz.getSimpleName();
+        if (simpleName.length() != 0) {
+            if (withEnclosingClass) {
+                String prefix = "";
+                Class< ? > enclosingClass = clazz;
+                while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) {
+                    prefix = prefix + enclosingClass.getSimpleName() + ".";
+                }
+                return prefix + simpleName;
+            }
+            return simpleName;
+        }
+        // Must be an anonymous or local class
+        final String name = clazz.getName();
+        int index = name.indexOf('$');
+        if (index == -1) {
+            return name;
+        }
+        index = name.lastIndexOf('.', index);
+        if (index == -1) {
+            return name;
+        }
+        return name.substring(index + 1);
+    }
+
+
+    /**
+     * Converts a given type to its Java programming language name. The following are examples of strings returned by
+     * this method:
+     *
+     * <pre>
+     *     qualified == true:
+     *         java.lang.Object
+     *         int
+     *         boolean[][]
+     *     qualified == false:
+     *         Object
+     *         int
+     *         boolean[][]
+     * </pre>
+     *
+     * @param riType the type to be converted to a Java name
+     * @param qualified specifies if the package prefix of the type should be included in the returned name
+     * @return the Java name corresponding to {@code riType}
+     */
+    public static String toJavaName(JavaType riType, boolean qualified) {
+        Kind kind = riType.kind();
+        if (kind.isObject()) {
+            return internalNameToJava(riType.name(), qualified);
+        }
+        return riType.kind().javaName;
+    }
+
+    /**
+     * Converts a given type to its Java programming language name. The following are examples of strings returned by
+     * this method:
+     *
+     * <pre>
+     *      java.lang.Object
+     *      int
+     *      boolean[][]
+     * </pre>
+     *
+     * @param riType the type to be converted to a Java name
+     * @return the Java name corresponding to {@code riType}
+     */
+    public static String toJavaName(JavaType riType) {
+        return (riType == null) ? null : internalNameToJava(riType.name(), true);
+    }
+
+    public static String internalNameToJava(String name, boolean qualified) {
+        switch (name.charAt(0)) {
+            case 'L': {
+                String result = name.substring(1, name.length() - 1).replace('/', '.');
+                if (!qualified) {
+                    final int lastDot = result.lastIndexOf('.');
+                    if (lastDot != -1) {
+                        result = result.substring(lastDot + 1);
+                    }
+                }
+                return result;
+
+            }
+            case '[':
+                return internalNameToJava(name.substring(1), qualified) + "[]";
+            default:
+                if (name.length() != 1) {
+                    throw new IllegalArgumentException("Illegal internal name: " + name);
+                }
+                return Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0)).javaName;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,80 @@
+/*
+ * 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.api.meta;
+
+/**
+ * Provides access to the profiling information of one specific method.
+ * Every accessor method returns the information that is available at the time of invocation.
+ * If a method is invoked multiple times, it may return significantly different results for every invocation
+ * as the profiling information may be changed by other Java threads at any time.
+ */
+public interface ProfilingInfo {
+
+    /**
+     * Gets the length of the code associated with this profile.
+     */
+    int codeSize();
+
+    /**
+     * Returns an estimate of how often the branch at the given byte code was taken.
+     * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if this information is not available.
+     */
+    double getBranchTakenProbability(int bci);
+
+    /**
+     * Returns an estimate of how often the switch cases are taken at the given BCI.
+     * The default case is stored as the last entry.
+     * @return A double value that contains the estimated probabilities, with 0.0 meaning never and 1.0 meaning always,
+     * or -1 if this information is not available.
+     */
+    double[] getSwitchProbabilities(int bci);
+
+    /**
+     * Returns the TypeProfile for the given BCI.
+     * @return Returns an JavaTypeProfile object, or null if not available.
+     */
+    JavaTypeProfile getTypeProfile(int bci);
+
+    /**
+     * Returns information if the given BCI did ever throw an exception.
+     * @return {@link ExceptionSeen#TRUE} if the instruction has thrown an exception at least once,
+     * {@link ExceptionSeen#FALSE} if it never threw an exception, and {@link ExceptionSeen#NOT_SUPPORTED}
+     * if this information was not recorded.
+     */
+    ExceptionSeen getExceptionSeen(int bci);
+
+    /**
+     * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts to each other,
+     * as the returned value highly depends on the time of invocation.
+     * @return the estimated execution count or -1 if not available.
+     */
+    int getExecutionCount(int bci);
+
+    /**
+     * Returns how frequently a method was deoptimized for the given deoptimization reason. This only indicates how
+     * often the method did fall back to the interpreter for the execution and does not indicate how often it was recompiled.
+     * @param reason the reason for which the number of deoptimizations should be queried
+     * @return the number of times the compiled method deoptimized for the given reason.
+     */
+    int getDeoptimizationCount(DeoptimizationReason reason);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+/**
+ * Represents a reference to a resolved Java field. Fields, like methods and types, are
+ * resolved through {@link ConstantPool constant pools}.
+ */
+public interface ResolvedJavaField extends JavaField {
+
+    /**
+     * Gets the access flags for this field. Only the flags specified in the JVM specification
+     * will be included in the returned mask. The utility methods in the {@link Modifier} class
+     * should be used to query the returned mask for the presence/absence of individual flags.
+     * @return the mask of JVM defined field access flags defined for this field
+     */
+    int accessFlags();
+
+    /**
+     * Gets the constant value of this field if available.
+     * @param receiver object from which this field's value is to be read. This value is ignored if this field is static.
+     * @return the constant value of this field or {@code null} if the constant value is not available
+     */
+    Constant constantValue(Constant receiver);
+
+    /**
+     * Gets the current value of the field if available.
+     * @param receiver object from which this field's value is to be read. This value is ignored if this field is static.
+     * @return the value of this field or {@code null} if the value is not available (e.g., because the field holder is not yet initialized).
+     */
+    Constant getValue(Constant receiver);
+
+    /**
+     * Gets the holder of this field as a compiler-runtime interface type.
+     * @return the holder of this field
+     */
+    ResolvedJavaType holder();
+
+    /**
+     * Returns this field's annotation of a specified type.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return the annotation of type {@code annotationClass} for this field if present, else null
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Represents resolved Java methods. Methods, like fields and types, are resolved through
+ * {@link ConstantPool constant pools}.
+ */
+public interface ResolvedJavaMethod extends JavaMethod {
+
+    /**
+     * Gets the bytecode of the method, if the method {@linkplain #isResolved()} and has code.
+     * The returned byte array does not contain breakpoints or non-Java bytecodes.
+     * @return the bytecode of the method or {@code null} if none is available
+     */
+    byte[] code();
+
+    /**
+     * Gets the size of the bytecode of the method, if the method {@linkplain #isResolved()} and has code.
+     * @return the size of the bytecode in bytes, or 0 if no bytecode is available
+     */
+    int codeSize();
+
+    /**
+     * Gets the size of the compiled machine code.
+     * @return the size of the compiled machine code in bytes, or 0 if no compiled code exists.
+     */
+    int compiledCodeSize();
+
+    /**
+     * Gets an estimate how complex it is to compile this method.
+     * @return A value >= 0, where higher means more complex.
+     */
+    int compilationComplexity();
+
+    /**
+     * Gets the symbol used to link this method if it is native, otherwise {@code null}.
+     */
+    String jniSymbol();
+
+    /**
+     * Gets the type in which this method is declared.
+     * @return the type in which this method is declared
+     */
+    ResolvedJavaType holder();
+
+    /**
+     * Gets the maximum number of locals used in this method's bytecode.
+     * @return the maximum number of locals
+     */
+    int maxLocals();
+
+    /**
+     * Gets the maximum number of stack slots used in this method's bytecode.
+     * @return the maximum number of stack slots
+     */
+    int maxStackSize();
+
+    /**
+     * Checks whether this method has balanced monitor operations.
+     * @return {@code true} if the method has balanced monitor operations
+     */
+    boolean hasBalancedMonitors();
+
+    /**
+     * Gets the access flags for this method. Only the flags specified in the JVM specification
+     * will be included in the returned mask. The utility methods in the {@link Modifier} class
+     * should be used to query the returned mask for the presence/absence of individual flags.
+     * @return the mask of JVM defined method access flags defined for this method
+     */
+    int accessFlags();
+
+    /**
+     * Checks whether this method is a leaf method.
+     * @return {@code true} if the method is a leaf method (that is, is final or private)
+     */
+    boolean isLeafMethod();
+
+    /**
+     * Checks whether this method is a class initializer.
+     * @return {@code true} if the method is a class initializer
+     */
+    boolean isClassInitializer();
+
+    /**
+     * Checks whether this method is a constructor.
+     * @return {@code true} if the method is a constructor
+     */
+    boolean isConstructor();
+
+    /**
+     * Checks whether this method can be statically bound (that is, it is final or private or static).
+     * @return {@code true} if this method can be statically bound
+     */
+    boolean canBeStaticallyBound();
+
+    /**
+     * Gets the list of exception handlers for this method.
+     * @return the list of exception handlers
+     */
+    ExceptionHandler[] exceptionHandlers();
+
+    /**
+     * Gets a stack trace element for this method and a given bytecode index.
+     */
+    StackTraceElement toStackTraceElement(int bci);
+
+    /**
+     * Provides an estimate of how often this method has been executed.
+     * @return The number of invocations, or -1 if this information isn't available.
+     */
+    int invocationCount();
+
+    /**
+     * Returns an object that provides access to the method's profiling information.
+     * @return The profiling information recorded for this method.
+     */
+    ProfilingInfo profilingInfo();
+
+    /**
+     * Returns a map that the compiler can use to store objects that should survive the current compilation.
+     */
+    Map<Object, Object> compilerStorage();
+
+    /**
+     * Returns a pointer to the method's constant pool.
+     * @return the constant pool
+     */
+    ConstantPool getConstantPool();
+
+    /**
+     * Returns this method's annotation of a specified type.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return the annotation of type {@code annotationClass} for this method if present, else null
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns an array of arrays that represent the annotations on the formal
+     * parameters, in declaration order, of this method.
+     *
+     * @see Method#getParameterAnnotations()
+     * @see CiUtil#getParameterAnnotation(int, JavaResolvedMethod)
+     */
+    Annotation[][] getParameterAnnotations();
+
+    /**
+     * Returns an array of {@link Type} objects that represent the formal
+     * parameter types, in declaration order, of this method.
+     *
+     * @see Method#getGenericParameterTypes()
+     */
+    Type[] getGenericParameterTypes();
+
+    /**
+     * @return {@code true} if this method can be inlined
+     */
+    boolean canBeInlined();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+/**
+ * Represents a resolved Java types. Types include primitives, objects, {@code void},
+ * and arrays thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools}.
+ */
+public interface ResolvedJavaType extends JavaType {
+
+    /**
+     * Gets the encoding of (that is, a constant representing the value of) the specified part of this type.
+     * @param r the part of the this type
+     * @return a constant representing a reference to the specified part of this type
+     */
+    Constant getEncoding(Representation r);
+
+    /**
+     * Checks whether this type has a finalizer method.
+     * @return {@code true} if this class has a finalizer
+     */
+    boolean hasFinalizer();
+
+    /**
+     * Checks whether this type has any finalizable subclasses so far. Any decisions
+     * based on this information require the registration of a dependency, since
+     * this information may change.
+     * @return {@code true} if this class has any subclasses with finalizers
+     */
+    boolean hasFinalizableSubclass();
+
+    /**
+     * Checks whether this type is an interface.
+     * @return {@code true} if this type is an interface
+     */
+    boolean isInterface();
+
+    /**
+     * Checks whether this type is an instance class.
+     * @return {@code true} if this type is an instance class
+     */
+    boolean isInstanceClass();
+
+    /**
+     * Checks whether this type is an array class.
+     * @return {@code true} if this type is an array class
+     */
+    boolean isArrayClass();
+
+    /**
+     * Gets the access flags for this type. Only the flags specified in the JVM specification
+     * will be included in the returned mask. The utility methods in the {@link Modifier} class
+     * should be used to query the returned mask for the presence/absence of individual flags.
+     * @return the mask of JVM defined class access flags defined for this type
+     */
+    int accessFlags();
+
+    /**
+     * Checks whether this type is initialized.
+     * @return {@code true} if this type is initialized
+     */
+    boolean isInitialized();
+
+    /**
+     * Checks whether this type is a subtype of another type.
+     * @param other the type to test
+     * @return {@code true} if this type a subtype of the specified type
+     */
+    boolean isSubtypeOf(ResolvedJavaType other);
+
+    /**
+     * Checks whether the specified object is an instance of this type.
+     * @param obj the object to test
+     * @return {@code true} if the object is an instance of this type
+     */
+    boolean isInstance(Constant obj);
+
+    /**
+     * Attempts to get an exact type for this type. Final classes,
+     * arrays of final classes, and primitive types all have exact types.
+     * @return the exact type of this type, if it exists; {@code null} otherwise
+     */
+    ResolvedJavaType exactType();
+
+    /**
+     * Gets the super type of this type or {@code null} if no such type exists.
+     */
+    ResolvedJavaType superType();
+
+    /**
+     * Walks the class hierarchy upwards and returns the least common type that is a super type of both
+     * the current and the given type.
+     * @return the least common type that is a super type of both the current and the given type, or null if primitive types are involved.
+     */
+    ResolvedJavaType leastCommonAncestor(ResolvedJavaType otherType);
+
+    /**
+     * Attempts to get the unique concrete subtype of this type.
+     * @return the exact type of this type, if it exists; {@code null} otherwise
+     */
+    ResolvedJavaType uniqueConcreteSubtype();
+
+    /**
+     * For array types, gets the type of the components.
+     * @return the component type of this array type
+     */
+    ResolvedJavaType componentType();
+
+    /**
+     * Gets the type representing an array with elements of this type.
+     * @return a new compiler interface type representing an array of this type
+     */
+    ResolvedJavaType arrayOf();
+
+    /**
+     * Resolves the method implementation for virtual dispatches on objects
+     * of this dynamic type.
+     * @param method the method to select the implementation of
+     * @return the method implementation that would be selected at runtime
+     */
+    ResolvedJavaMethod resolveMethodImpl(ResolvedJavaMethod method);
+
+    /**
+     * Given an JavaMethod a, returns a concrete JavaMethod b that is the only possible
+     * unique target for a virtual call on a(). Returns {@code null} if either no
+     * such concrete method or more than one such method exists. Returns the method a
+     * if a is a concrete method that is not overridden. If the compiler uses the
+     * result of this method for its compilation, it must register an assumption
+     * (see {@link CiAssumptions}), because dynamic class loading can invalidate
+     * the result of this method.
+     * @param method the method a for which a unique concrete target is searched
+     * @return the unique concrete target or {@code null} if no such target exists
+     *         or assumptions are not supported by this runtime
+     */
+    ResolvedJavaMethod uniqueConcreteMethod(ResolvedJavaMethod method);
+
+    /**
+     * Returns the instance fields declared in this class sorted by field offset.
+     * @return an array of instance fields
+     */
+    ResolvedJavaField[] declaredFields();
+
+    /**
+     * Returns this type's annotation of a specified type.
+     *
+     * @param annotationClass the Class object corresponding to the annotation type
+     * @return the annotation of type {@code annotationClass} for this type if present, else null
+     */
+    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
+
+    /**
+     * Returns the java.lang.Class object representing this JavaType instance or {@code null} if none exists.
+     * @return the java.lang.Class object
+     */
+    Class<?> toJava();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Represents a method signature provided by the runtime.
+ *
+ * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#7035">Method Descriptors</a>
+ */
+public interface Signature {
+    /**
+     * Gets the number of arguments in this signature, adding 1 for a receiver if requested.
+     *
+     * @param receiver true if 1 is to be added to the result for a receiver
+     * @return the number of arguments + 1 iff {@code receiver == true}
+     */
+    int argumentCount(boolean receiver);
+
+    /**
+     * Gets the argument type at the specified position. This method will return a
+     * {@linkplain JavaType#isResolved() resolved} type if possible but without
+     * triggering any class loading or resolution.
+     *
+     * @param index the index into the parameters, with {@code 0} indicating the first parameter
+     * @param accessingClass the context of the type lookup. If accessing class is resolved, its class loader
+     *        is used to retrieve an existing resolved type. This value can be {@code null} if the caller does
+     *        not care for a resolved type.
+     * @return the {@code index}'th argument type
+     */
+    JavaType argumentTypeAt(int index, ResolvedJavaType accessingClass);
+
+    /**
+     * Gets the argument kind at the specified position.
+     * @param index the index into the parameters, with {@code 0} indicating the first parameter
+     * @return the kind of the argument at the specified position
+     */
+    Kind argumentKindAt(int index);
+
+    /**
+     * Gets the return type of this signature. This method will return a
+     * {@linkplain ResolvedJavaType resolved} type if possible but without
+     * triggering any class loading or resolution.
+     *
+     * @param accessingClass the context of the type lookup. If accessing class is resolved, its class loader
+     *        is used to retrieve an existing resolved type. This value can be {@code null} if the caller does
+     *        not care for a resolved type.
+     * @return the compiler interface type representing the return type
+     */
+    JavaType returnType(JavaType accessingClass);
+
+    /**
+     * Gets the return kind of this signature.
+     * @return the return kind
+     */
+    Kind returnKind();
+
+    /**
+     * Converts this signature to a string.
+     * @return the signature as a string
+     */
+    String asString();
+
+    /**
+     * Gets the size, in Java slots, of the arguments to this signature.
+     * @param withReceiver {@code true} if to add a slot for a receiver object; {@code false} not to include the receiver
+     * @return the size of the arguments in slots
+     */
+    int argumentSlots(boolean withReceiver);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.io.*;
+
+/**
+ * Abstract base class for values manipulated by the compiler. All values have a {@linkplain Kind kind} and are immutable.
+ */
+public abstract class Value implements Serializable {
+    private static final long serialVersionUID = -6909397188697766469L;
+
+    @SuppressWarnings("serial")
+    public static Value IllegalValue = new Value(Kind.Illegal) {
+        @Override
+        public String toString() {
+            return "-";
+        }
+    };
+
+    /**
+     * The kind of this value.
+     */
+    public final Kind kind;
+
+    /**
+     * Initializes a new value of the specified kind.
+     * @param kind the kind
+     */
+    protected Value(Kind kind) {
+        this.kind = kind;
+    }
+
+    /**
+     * String representation of the kind, which should be the end of all {@link #toString()} implementation of subclasses.
+     */
+    protected final String kindSuffix() {
+        return "|" + kind.typeChar;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/VirtualMachineComponent.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+
+public interface VirtualMachineComponent {
+    void setOption(String name, String value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/package-info.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2009, 2011, 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 that defines the interface between a runtime and a Java application that wants to access meta information.
+ */
+package com.oracle.graal.api.meta;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.test/src/com/oracle/graal/api/GraalTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+
+public class GraalTest {
+
+    @Test
+    public void testRuntimeAvailable() {
+        assertNotNull(Graal.getRuntime());
+        System.out.println(Graal.getRuntime().getClass());
+    }
+
+    @Test
+    public void testRuntimeNamed() {
+        assertNotNull(Graal.getRuntime().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api/src/com/oracle/graal/api/Graal.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api;
+
+public class Graal {
+
+    private static GraalRuntime runtime;
+
+    private static native GraalRuntime initializeRuntime();
+
+    public static GraalRuntime getRuntime() {
+        return runtime;
+    }
+
+    static {
+        try {
+            runtime = initializeRuntime();
+        } catch (UnsatisfiedLinkError e) {
+            runtime = new GraalRuntime() {
+                @Override
+                public String getName() {
+                    return "";
+                }
+                @Override
+                public <T> T getCapability(Class<T> clazz) {
+                    return null;
+                }
+            };
+        }
+    }
+
+    public static <T> T getRequiredCapability(Class<T> clazz) {
+        T t = getRuntime().getCapability(clazz);
+        if (t == null) {
+            throw new IllegalAccessError("Runtime does not expose required capability " + clazz.getName());
+        }
+        return t;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api/src/com/oracle/graal/api/GraalRuntime.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api;
+
+
+public interface GraalRuntime {
+    String getName();
+    <T> T getCapability(Class<T> clazz);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/BigBangTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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.boot;
+
+import org.junit.*;
+
+public class BigBangTest {
+
+    @Test
+    public void helloWorldTest() {
+        BootImageGenerator generator = new BootImageGenerator();
+        generator.addEntryMethod(TestPrograms.class, "helloWorldTest");
+        Assert.assertArrayEquals(generator.getBigBang().printState(), new int[]{3, 118, 58, 21});
+    }
+
+    @Test
+    public void formattedOutputTest() {
+        BootImageGenerator generator = new BootImageGenerator();
+        generator.addEntryMethod(TestPrograms.class, "formattedOutputTest");
+        Assert.assertArrayEquals(generator.getBigBang().printState(), new int[]{15, 979, 346, 98});
+    }
+
+
+    @Test
+    public void newTest() {
+        BootImageGenerator generator = new BootImageGenerator();
+        generator.addEntryMethod(TestPrograms.class, "newTest");
+        Assert.assertArrayEquals(generator.getBigBang().printState(), new int[]{0, 3, 0, 0});
+    }
+
+
+    @Test
+    public void arraycopyTest() {
+        BootImageGenerator generator = new BootImageGenerator();
+        generator.addEntryMethod(TestPrograms.class, "arraycopyTest");
+        Assert.assertArrayEquals(generator.getBigBang().printState(), new int[]{2, 6, 0, 0});
+    }
+
+    @Test
+    public void arrayListTest() {
+        BootImageGenerator generator = new BootImageGenerator();
+        generator.addEntryMethod(TestPrograms.class, "arrayListTest");
+        Assert.assertArrayEquals(generator.getBigBang().printState(), new int[]{2, 20, 3, 2});
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/BootImageClassLoaderTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,79 @@
+/*
+ * 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.boot;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+
+public class BootImageClassLoaderTest {
+
+    @Test
+    public void test() throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, SecurityException {
+
+        TestClassB.x = 1;
+        BootImageClassLoader l = new BootImageClassLoader();
+
+        // Assert that the class definition is really duplicated.
+        Class<?> bClass = Class.forName(TestClassB.class.getCanonicalName(), true, l);
+        Assert.assertNotSame(TestClassB.class, bClass);
+
+        // Assert that the class definition is not duplicated more than once.
+        Assert.assertSame(bClass, l.convert(TestClassB.class));
+
+        // Set field x such that it is used by the subsequent static initializer for TestClassA.
+        Field bField = bClass.getFields()[0];
+        bField.setAccessible(true);
+        bField.set(null, 2);
+
+        // Assert that the class definition is duplicated.
+        Class<?> aClass = l.convert(TestClassA.class);
+        Assert.assertNotSame(TestClassA.class, aClass);
+
+        // Assert that the original version of TestClassA was initialized correctly.
+        Assert.assertEquals(1, TestClassA.x);
+
+        // Assert that the duplicated version of TestClassA was initialized correctly.
+        Field aField = aClass.getFields()[0];
+        aField.setAccessible(true);
+        Assert.assertEquals(2, aField.getInt(null));
+
+        // Assert that system classes are not duplicated.
+        Assert.assertSame(Object.class, l.convert(Object.class));
+        Assert.assertSame(Object.class, Class.forName(Object.class.getCanonicalName(), true, l));
+    }
+
+}
+
+class TestClassA {
+    public static int x;
+
+    static {
+        x = TestClassB.x;
+    }
+}
+
+class TestClassB {
+    public static int x;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/TestPrograms.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,60 @@
+/*
+ * 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.boot;
+
+import java.util.*;
+
+public class TestPrograms {
+    public static void helloWorldTest() {
+        System.out.println("Hello world!");
+    }
+
+    public static void formattedOutputTest() {
+        System.out.printf("%s %s!", "Hello", "world");
+    }
+
+    @SuppressWarnings("unused")
+    public static void newTest() {
+        Integer x = new Integer(5);
+    }
+
+    public static void arraycopyTest() {
+        Object[] arr = new Object[1];
+        arr[0] = new TestObject();
+        TestObject[] newArr = Arrays.copyOf(arr, 1, TestObject[].class);
+        newArr[0].testMethod();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static void arrayListTest() {
+        ArrayList list = new ArrayList();
+        list.add(new TestObject());
+        TestObject[] newArr = (TestObject[]) list.toArray(new TestObject[0]);
+        newArr[0].testMethod();
+    }
+
+    public static class TestObject {
+        public void testMethod() {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BigBang.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,297 @@
+/*
+ * 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.boot;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.java.*;
+
+public class BigBang {
+
+    private static final int THREADS = 4;
+
+    private MetaAccessProvider metaAccessProvider;
+    private int postedOperationCount;
+
+    // Mappings from Graal IR and Graal meta-data to element instances.
+    private Map<Node, Element> sinkMap = new IdentityHashMap<>();
+    private Map<ResolvedJavaField, FieldElement> fieldMap = new IdentityHashMap<>();
+    private Map<ResolvedJavaMethod, MethodElement> methodMap = new IdentityHashMap<>();
+    private Map<ResolvedJavaType, ArrayTypeElement> arrayTypeMap = new IdentityHashMap<>();
+
+    // Processing queue.
+    private ThreadPoolExecutor executor = new ThreadPoolExecutor(THREADS, THREADS, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory());
+
+    public BigBang(MetaAccessProvider metaAccessProvider) {
+        this.metaAccessProvider = metaAccessProvider;
+    }
+
+    public synchronized FieldElement getProcessedField(ResolvedJavaField field) {
+        assert field != null;
+        if (!fieldMap.containsKey(field)) {
+            fieldMap.put(field, new FieldElement(field));
+        }
+        return fieldMap.get(field);
+    }
+
+    public synchronized MethodElement getProcessedMethod(ResolvedJavaMethod method) {
+        assert method != null;
+        if (!methodMap.containsKey(method)) {
+            methodMap.put(method, new MethodElement(method));
+        }
+        return methodMap.get(method);
+    }
+
+    public synchronized ArrayTypeElement getProcessedArrayType(ResolvedJavaType type) {
+        assert type != null;
+        if (!arrayTypeMap.containsKey(type)) {
+            arrayTypeMap.put(type, new ArrayTypeElement(type));
+        }
+        return arrayTypeMap.get(type);
+    }
+
+    public synchronized Element getSinkElement(Node node, Node sourceNode) {
+        if (!sinkMap.containsKey(node)) {
+            Element resultElement = Element.BLACK_HOLE;
+            if (node instanceof PhiNode) {
+                PhiNode phiNode = (PhiNode) node;
+                resultElement = new PhiElement(phiNode);
+            } else if (node instanceof CheckCastNode) {
+                CheckCastNode checkCastNode = (CheckCastNode) node;
+                resultElement = new CastElement(checkCastNode);
+            } else if (node instanceof ValueProxyNode) {
+                ValueProxyNode proxyNode = (ValueProxyNode) node;
+                resultElement = new ProxyElement(proxyNode);
+            } else if (node instanceof StoreFieldNode) {
+                StoreFieldNode storeFieldNode = (StoreFieldNode) node;
+                resultElement = getProcessedField(storeFieldNode.field());
+            } else if (node instanceof StoreIndexedNode) {
+                StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
+                if (storeIndexedNode.elementKind() == Kind.Object) {
+                    resultElement = getProcessedArrayType(metaAccessProvider.getResolvedJavaType(Object[].class));
+                }
+            } else if (node instanceof ReturnNode) {
+                ReturnNode returnNode = (ReturnNode) node;
+                ResolvedJavaMethod method = ((StructuredGraph) returnNode.graph()).method();
+                resultElement = getProcessedMethod(method);
+            } else {
+                if (node instanceof FrameState || node instanceof MonitorEnterNode || node instanceof MonitorExitNode || node instanceof LoadFieldNode || node instanceof IsNullNode || node instanceof InstanceOfNode) {
+                    // OK.
+                } else {
+                    System.out.println("Unknown sink - black hole? " + node);
+                }
+            }
+
+            sinkMap.put(node, resultElement);
+        }
+
+        if (node instanceof StoreIndexedNode) {
+            StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
+            if (storeIndexedNode.value() != sourceNode) {
+                return Element.BLACK_HOLE;
+            }
+        }
+
+        if (node instanceof StoreFieldNode) {
+            StoreFieldNode storeFieldNode = (StoreFieldNode) node;
+            if (storeFieldNode.value() != sourceNode) {
+                return Element.BLACK_HOLE;
+            }
+        }
+        return sinkMap.get(node);
+    }
+
+    public synchronized void registerSourceCallTargetNode(MethodCallTargetNode methodCallTargetNode) {
+        InvokeElement invokeElement = new InvokeElement(methodCallTargetNode);
+        sinkMap.put(methodCallTargetNode, invokeElement);
+        invokeElement.expandStaticMethod(this);
+    }
+
+    public synchronized void registerSourceNode(Node node) {
+        Element resultElement = null;
+        if (node instanceof LoadFieldNode) {
+            LoadFieldNode loadFieldNode = (LoadFieldNode) node;
+            resultElement = getProcessedField(loadFieldNode.field());
+        } else if (node instanceof LoadIndexedNode) {
+            LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
+            if (loadIndexedNode.kind() == Kind.Object) {
+                resultElement = getProcessedArrayType(metaAccessProvider.getResolvedJavaType(Object[].class));
+            }
+        } else if (node instanceof LocalNode) {
+            LocalNode localNode = (LocalNode) node;
+            if (localNode.kind() == Kind.Object) {
+                ResolvedJavaMethod method = ((StructuredGraph) localNode.graph()).method();
+                resultElement = getProcessedMethod(method).getParameter(localNode.index());
+                System.out.println("resultElement = " + resultElement + " index= " + localNode.index() + ", node=" + node);
+            }
+        }
+
+        if (resultElement != null) {
+            resultElement.postAddUsage(this, node);
+        }
+    }
+
+    public synchronized void postOperation(UniverseExpansionOp operation) {
+        System.out.println("posting operation " + operation);
+        executor.execute(operation);
+        postedOperationCount++;
+    }
+
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccessProvider;
+    }
+
+    public void finish() {
+        while (true) {
+            try {
+                Thread.sleep(10);
+                boolean terminated;
+                int oldPostedOperationCount;
+                synchronized (this) {
+                    terminated = (executor.getCompletedTaskCount() == postedOperationCount);
+                    oldPostedOperationCount = postedOperationCount;
+                }
+
+                if (terminated) {
+                    checkObjectGraph();
+                    synchronized (this) {
+                        if (postedOperationCount == oldPostedOperationCount) {
+                            System.out.printf("Big bang simulation completed in %d operations.\n", postedOperationCount);
+                            executor.shutdown();
+                            break;
+                        }
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private void checkObjectGraph() {
+        List<FieldElement> originalRoots = new ArrayList<>();
+        synchronized (this) {
+            for (FieldElement field : fieldMap.values()) {
+                if (field.isStatic()) {
+                    originalRoots.add(field);
+                }
+            }
+        }
+
+        Map<Object, Boolean> scannedObjects = new IdentityHashMap<>();
+        for (FieldElement field : originalRoots) {
+            assert field.isStatic();
+            if (field.getUsageCount() > 0 && field.getJavaField().kind() == Kind.Object) {
+                Object value = field.getJavaField().getValue(null).asObject();
+                System.out.printf("Root field %s: %s\n", field, value);
+                scanField(scannedObjects, field, value);
+            }
+        }
+    }
+
+    private void scanField(Map<Object, Boolean> scannedObjects, FieldElement field, Object value) {
+        if (value != null && field.getUsageCount() > 0) {
+            field.registerNewValue(this, value);
+            scan(scannedObjects, value);
+        }
+    }
+
+    private void scan(Map<Object, Boolean> scannedObjects, Object value) {
+        assert value != null;
+        if (scannedObjects.containsKey(value)) {
+            return;
+        }
+
+        scannedObjects.put(value, Boolean.TRUE);
+        ResolvedJavaType type = getMetaAccess().getResolvedJavaType(value.getClass());
+        scan(scannedObjects, value, type);
+    }
+
+    private void scan(Map<Object, Boolean> scannedObjects, Object value, ResolvedJavaType type) {
+        if (type.superType() != null) {
+            scan(scannedObjects, value, type.superType());
+        }
+
+        ResolvedJavaField[] declaredFields = type.declaredFields();
+        for (ResolvedJavaField field : declaredFields) {
+            if (field.kind() == Kind.Object) {
+                FieldElement fieldElement = getProcessedField(field);
+                Object fieldValue = field.getValue(Constant.forObject(value)).asObject();
+                scanField(scannedObjects, fieldElement, fieldValue);
+            }
+        }
+
+    }
+
+    public synchronized int[] printState() {
+
+        int nativeMethodCount = 0;
+        for (MethodElement methodElement : methodMap.values()) {
+            if (methodElement.hasGraph()) {
+                if (Modifier.isNative(methodElement.getResolvedJavaMethod().accessFlags())) {
+                    System.out.println("Included native method: " + methodElement.getResolvedJavaMethod());
+                    nativeMethodCount++;
+                }
+            }
+        }
+
+        int methodCount = 0;
+        for (MethodElement methodElement : methodMap.values()) {
+            if (methodElement.hasGraph()) {
+                if (!Modifier.isNative(methodElement.getResolvedJavaMethod().accessFlags())) {
+                    System.out.println("Included method: " + methodElement.getResolvedJavaMethod());
+                    methodCount++;
+                }
+            }
+        }
+
+        Set<ResolvedJavaType> includedTypes = new HashSet<>();
+        int fieldCount = 0;
+        for (FieldElement fieldElement : fieldMap.values()) {
+            if (fieldElement.getUsageCount() > 0) {
+                System.out.print("Included field: " + fieldElement.getJavaField() + " / ");
+                fieldElement.printSeenTypes();
+                System.out.println();
+                fieldCount++;
+                includedTypes.add(fieldElement.getJavaField().holder());
+            }
+        }
+
+        for (ResolvedJavaType type : includedTypes) {
+            System.out.println("Included type: " + type);
+        }
+
+        System.out.println("Number of included native methods: " + nativeMethodCount);
+        System.out.println("Number of included method: " + methodCount);
+        System.out.println("Number of included fields: " + fieldCount);
+        System.out.println("Number of included types: " + includedTypes.size());
+        return new int[]{nativeMethodCount, methodCount, fieldCount, includedTypes.size()};
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BootImageClassLoader.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,74 @@
+/*
+ * 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.boot;
+
+import java.io.*;
+
+public class BootImageClassLoader extends ClassLoader {
+
+    @Override
+    protected java.lang.Class< ? > loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        synchronized (getClassLoadingLock(name)) {
+            Class< ? > result = findLoadedClass(name);
+            if (result == null) {
+                result = super.loadClass(name, resolve);
+                assert result.getName().equals(name);
+                return duplicate(result);
+            }
+            return result;
+        }
+    }
+
+    private Class< ? > duplicate(Class< ? > result) {
+        // This is a class in the bootclasspath => share.
+        if (result.getClassLoader() == null) {
+            return result;
+        }
+
+        // Duplicate class definition.
+        InputStream inputStream = result.getClassLoader().getResourceAsStream(result.getName().replace('.', '/').concat(".class"));
+        try {
+            byte[] byteCodes = new byte[inputStream.available()];
+            inputStream.read(byteCodes);
+            return this.defineClass(result.getName(), byteCodes, 0, byteCodes.length);
+        } catch (IOException e) {
+            throw new RuntimeException("Could not access class bytes for " + result.getName());
+        }
+    }
+
+    public Class< ? > convert(Class< ? > clazz) {
+        synchronized (getClassLoadingLock(clazz.getCanonicalName())) {
+            // This class has this class loader => no conversion necessary.
+            if (clazz.getClassLoader() == this) {
+                return clazz;
+            }
+
+            Class< ? > thisClazz = findLoadedClass(clazz.getName());
+            if (thisClazz != null) {
+                return thisClazz;
+            }
+
+            return duplicate(clazz);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BootImageGenerator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,60 @@
+/*
+ * 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.boot;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.meta.*;
+
+
+public class BootImageGenerator {
+
+    private final BootImageClassLoader classLoader = new BootImageClassLoader();
+    private final MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+    private final BigBang bigbang = new BigBang(metaAccess);
+
+    public void addEntryMethod(Class<?> clazz, String name, Class<?> ... parameterTypes) {
+        Class<?> convertedClass = classLoader.convert(clazz);
+        Method method;
+        try {
+            method = convertedClass.getDeclaredMethod(name, parameterTypes);
+        } catch (NoSuchMethodException | SecurityException e) {
+            throw new RuntimeException("Could not find method " + name + " with parameter types " + parameterTypes + " in class " + convertedClass.getCanonicalName());
+        }
+        System.out.printf("Adding method %s.%s to the boot image\n", method.getDeclaringClass().getName(), method.getName());
+        addEntryMethod(metaAccess.getResolvedJavaMethod(method));
+    }
+
+
+    private void addEntryMethod(ResolvedJavaMethod javaMethod) {
+        MethodElement methodElement = bigbang.getProcessedMethod(javaMethod);
+        methodElement.postParseGraph(bigbang);
+        bigbang.finish();
+    }
+
+    public BigBang getBigBang() {
+        return bigbang;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/UniverseExpansionOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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.boot;
+
+
+public abstract class UniverseExpansionOp implements Runnable {
+
+    public void post(BigBang store) {
+        store.postOperation(this);
+    }
+
+    @Override
+    public void run() {
+        expand();
+    }
+
+    protected abstract void expand();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/ArrayTypeElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,69 @@
+/*
+ * 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.boot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+
+public class ArrayTypeElement extends Element {
+
+    private ResolvedJavaType javaType;
+
+    public ArrayTypeElement(ResolvedJavaType javaType) {
+        super(javaType.componentType());
+        this.javaType = javaType;
+    }
+
+    @Override
+    public String toString() {
+        return "arrayTypeElement: " + javaType;
+    }
+
+    @Override
+    protected void propagateTypesToUsage(BigBang bb, Node use, Set<ResolvedJavaType> set, Element element) {
+        LoadIndexedNode load = (LoadIndexedNode) use;
+        ResolvedJavaType type = load.array().objectStamp().type();
+        if (type == null) {
+            System.out.println("FATAL error: Array access without type!");
+            System.out.println(load.array());
+            System.out.println(((StructuredGraph) load.graph()).method());
+            System.exit(-1);
+        }
+        ResolvedJavaType componentType = type.componentType();
+        Set<ResolvedJavaType> newSet = new HashSet<>();
+        for (ResolvedJavaType myType : set) {
+            if (myType.isSubtypeOf(componentType)) {
+                newSet.add(myType);
+            }
+        }
+        if (newSet.size() > 0) {
+            super.propagateTypesToUsage(bb, use, newSet, element);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/CastElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,61 @@
+/*
+ * 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.boot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.java.*;
+
+
+public class CastElement extends Element {
+
+    private CheckCastNode checkCastNode;
+
+    public CastElement(CheckCastNode checkCastNode) {
+        super(checkCastNode.targetClass());
+        this.checkCastNode = checkCastNode;
+        this.usages.add(checkCastNode);
+    }
+
+    @Override
+    protected synchronized void unionTypes(BigBang bb, Node sourceNode, Set<ResolvedJavaType> newSeenTypes) {
+        Set<ResolvedJavaType> newSet = new HashSet<>();
+        // Filter through checkcast.
+        for (ResolvedJavaType type : newSeenTypes) {
+            if (type.isSubtypeOf(checkCastNode.targetClass())) {
+                newSet.add(type);
+            } else {
+                System.out.println("filtering " + type + " vs " + checkCastNode.targetClass());
+            }
+        }
+        super.unionTypes(bb, sourceNode, newSet);
+    }
+
+    @Override
+    public String toString() {
+        return "cast " + checkCastNode.targetClass();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/Element.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2011, 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.boot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.graph.*;
+
+
+public class Element {
+
+    public static final Element BLACK_HOLE = new Element(null);
+
+    protected List<Node> usages = new ArrayList<>(4);
+    protected Set<ResolvedJavaType> seenTypes = new HashSet<>();
+    private ResolvedJavaType declaredType;
+
+    protected Element(ResolvedJavaType declaredType) {
+        this.declaredType = declaredType;
+    }
+
+    public void postUnionTypes(final BigBang bb, final Node sourceNode, final Set<ResolvedJavaType> newSeenTypes) {
+        new UniverseExpansionOp() {
+            @Override
+            protected void expand() {
+                unionTypes(bb, sourceNode, newSeenTypes);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Add new seen types %s from source node %s to element %s", newSeenTypes, sourceNode, Element.this);
+            }
+        }.post(bb);
+    }
+
+    public void postAddUsage(final BigBang bb, final Node usage) {
+        new UniverseExpansionOp() {
+            @Override
+            protected void expand() {
+                addUsage(bb, usage);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Add usage %s to element %s", usage, Element.this);
+            }
+        }.post(bb);
+    }
+
+    protected synchronized void unionTypes(BigBang bb, @SuppressWarnings("unused") Node sourceNode, Set<ResolvedJavaType> newSeenTypes) {
+        if (!seenTypes.containsAll(newSeenTypes)) {
+            if (declaredType != null) {
+                for (ResolvedJavaType seenType : newSeenTypes) {
+                    if (!seenType.isSubtypeOf(declaredType)) {
+                        System.out.println("Wrong type found " + seenType + " where declared type of element " + this + " is " + declaredType);
+                        System.exit(-1);
+                    }
+                }
+            }
+            seenTypes.addAll(newSeenTypes);
+            propagateTypes(bb, newSeenTypes);
+        }
+    }
+
+    protected synchronized void propagateTypes(BigBang bb, Set<ResolvedJavaType> newSeenTypes) {
+        for (Node n : usages) {
+            propagateTypes(bb, n, newSeenTypes);
+        }
+    }
+
+    public synchronized int getUsageCount() {
+        return usages.size();
+    }
+
+    protected synchronized void addUsage(BigBang bb, Node usage) {
+        if (!usages.contains(usage)) {
+            usages.add(usage);
+            propagateTypes(bb, usage, seenTypes);
+        }
+    }
+
+    public void propagateTypes(BigBang bb, Node n, Set<ResolvedJavaType> types) {
+        if (types.size() != 0) {
+            Set<ResolvedJavaType> newSet = new HashSet<>(types);
+            for (Node use : n.usages()) {
+                Element element = bb.getSinkElement(use, n);
+                assert element != null;
+                if (element != BLACK_HOLE) {
+                    propagateTypesToUsage(bb, n, newSet, element);
+                }
+            }
+        }
+    }
+
+    protected void propagateTypesToUsage(BigBang bb, Node use, Set<ResolvedJavaType> newSet, Element element) {
+        element.postUnionTypes(bb, use, newSet);
+    }
+
+
+    public synchronized void printSeenTypes() {
+        for (ResolvedJavaType type : seenTypes) {
+            System.out.print(type.name() + " ");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/FieldElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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.boot.meta;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+
+
+public class FieldElement extends Element {
+
+    protected ResolvedJavaField javaField;
+
+    public FieldElement(ResolvedJavaField javaField) {
+        super(javaField.type().resolve(javaField.holder()));
+        this.javaField = javaField;
+    }
+
+    public boolean isStatic() {
+        return Modifier.isStatic(javaField.accessFlags());
+    }
+
+    public ResolvedJavaField getJavaField() {
+        return javaField;
+    }
+
+    @Override
+    public String toString() {
+        return "Field[" + javaField + "]";
+    }
+
+    public synchronized void registerNewValue(BigBang bb, Object value) {
+        if (value != null) {
+            Class<?> clazz = value.getClass();
+            ResolvedJavaType resolvedType = bb.getMetaAccess().getResolvedJavaType(clazz);
+            if (seenTypes.add(resolvedType)) {
+                Set<ResolvedJavaType> newSeenTypes = new HashSet<>();
+                newSeenTypes.add(resolvedType);
+                super.propagateTypes(bb, newSeenTypes);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/InvokeElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,117 @@
+/*
+ * 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.boot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+
+public class InvokeElement extends Element {
+
+    private MethodCallTargetNode methodCallTarget;
+    private Set<ResolvedJavaMethod> concreteTargets = new HashSet<>();
+    private Set<ResolvedJavaType>[] parameterTypes;
+
+    @SuppressWarnings("unchecked")
+    public InvokeElement(MethodCallTargetNode methodCallTarget) {
+        super(methodCallTarget.isStatic() ? null : methodCallTarget.targetMethod().holder());
+        this.methodCallTarget = methodCallTarget;
+        parameterTypes = new Set[methodCallTarget.arguments().size()];
+    }
+
+    @Override
+    protected synchronized void unionTypes(BigBang bb, Node sourceNode, Set<ResolvedJavaType> newSeenTypes) {
+
+        System.out.println("union invoke element " + this + " new types = " + newSeenTypes + " sourceNode= " + sourceNode);
+        int index = 0;
+        for (Node arg : methodCallTarget.arguments()) {
+            if (arg == sourceNode) {
+                System.out.println("source node " + sourceNode + " is at index " + index + " stamp=" + ((ValueNode) sourceNode).stamp());
+                unionTypes(bb, sourceNode, newSeenTypes, index);
+            }
+            ++index;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Invoke[bci=" + methodCallTarget.invoke().stateAfter().method() + "," + methodCallTarget.targetMethod() + "]";
+    }
+
+    public synchronized void expandStaticMethod(BigBang bb) {
+        if (methodCallTarget.isStatic()) {
+            ResolvedJavaMethod method = methodCallTarget.targetMethod();
+            concreteTargets.add(method);
+            MethodElement processedMethod = bb.getProcessedMethod(method);
+            processedMethod.postParseGraph(bb);
+        }
+    }
+
+    private void unionTypes(BigBang bb, @SuppressWarnings("unused") Node sourceNode, Set<ResolvedJavaType> newSeenTypes, int index) {
+        if (index == 0 && !methodCallTarget.isStatic()) {
+            for (ResolvedJavaType type : newSeenTypes) {
+                if (seenTypes.add(type)) {
+                    // There is a new receiver type!
+                    ResolvedJavaMethod method = type.resolveMethodImpl(methodCallTarget.targetMethod());
+                    System.out.println("resolved method " + method + " for type " + type + " and method " + methodCallTarget.targetMethod());
+                    if (method == null) {
+                        System.out.println("!!! type = " + type + " / " + methodCallTarget.targetMethod());
+                    }
+                    if (!concreteTargets.contains(method)) {
+                        concreteTargets.add(method);
+                        // New concrete method.
+                        MethodElement processedMethod = bb.getProcessedMethod(method);
+                        processedMethod.postParseGraph(bb);
+                        // Propagate types that were previously found for the parameters.
+                        for (int i = 0; i < parameterTypes.length; ++i) {
+                            if (parameterTypes[i] != null) {
+                                HashSet<ResolvedJavaType> newSeenTypesTemp = new HashSet<>(parameterTypes[i]);
+                                bb.getProcessedMethod(method).getParameter(i).postUnionTypes(bb, null, newSeenTypesTemp);
+                            }
+                        }
+                    }
+
+                    // Register new type for receiver.
+                    HashSet<ResolvedJavaType> newSeenTypesTemp = new HashSet<>();
+                    newSeenTypesTemp.add(type);
+                    bb.getProcessedMethod(method).getParameter(index).postUnionTypes(bb, null, newSeenTypesTemp);
+                }
+            }
+        } else {
+            if (parameterTypes[index] == null) {
+                parameterTypes[index] = new HashSet<>();
+            }
+            if (parameterTypes[index].addAll(newSeenTypes)) {
+                for (ResolvedJavaMethod method : concreteTargets) {
+                    HashSet<ResolvedJavaType> newSeenTypesTemp = new HashSet<>(newSeenTypes);
+                    bb.getProcessedMethod(method).getParameter(index).postUnionTypes(bb, null, newSeenTypesTemp);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/MethodElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,130 @@
+/*
+ * 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.boot.meta;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.java.GraphBuilderConfiguration.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+
+public class MethodElement extends Element {
+
+    private ParameterElement[] parameters;
+    private Graph graph;
+    private ResolvedJavaMethod resolvedJavaMethod;
+
+    public MethodElement(ResolvedJavaMethod javaMethod) {
+        super(javaMethod.signature().returnType(javaMethod.holder()).resolve(javaMethod.holder()));
+        assert javaMethod != null;
+        this.resolvedJavaMethod = javaMethod;
+        int parameterCount = resolvedJavaMethod.signature().argumentCount(!Modifier.isStatic(resolvedJavaMethod.accessFlags()));
+        parameters = new ParameterElement[parameterCount];
+        for (int i = 0; i < parameters.length; ++i) {
+            parameters[i] = new ParameterElement(resolvedJavaMethod, i);
+        }
+    }
+
+    public ParameterElement getParameter(int index) {
+        return parameters[index];
+    }
+
+    public synchronized boolean hasGraph() {
+        return graph != null;
+    }
+
+    public void postParseGraph(final BigBang bb) {
+        synchronized (this) {
+            if (graph != null) {
+                return;
+            }
+        }
+        new UniverseExpansionOp() {
+            @Override
+            protected void expand() {
+                parseGraph(bb);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Parsing method %s", resolvedJavaMethod);
+            }
+        }.post(bb);
+    }
+
+    protected void parseGraph(final BigBang bb) {
+        StructuredGraph newGraph = null;
+        synchronized (this) {
+            if (graph != null) {
+                // Graph already exists => quit operation.
+                return;
+            }
+            newGraph = new StructuredGraph(resolvedJavaMethod);
+            this.graph = newGraph;
+        }
+
+        if (Modifier.isNative(resolvedJavaMethod.accessFlags())) {
+            System.out.println("NATIVE METHOD " + resolvedJavaMethod);
+            return;
+        }
+
+        System.out.println("parsing graph " + resolvedJavaMethod + ", locals=" + resolvedJavaMethod.maxLocals());
+        GraphBuilderConfiguration config = new GraphBuilderConfiguration(ResolvePolicy.Eager, null);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(bb.getMetaAccess(), config, OptimisticOptimizations.NONE);
+        graphBuilderPhase.apply(newGraph);
+        new PhiStampPhase().apply(newGraph);
+
+        for (MethodCallTargetNode callTargetNode : newGraph.getNodes(MethodCallTargetNode.class)) {
+            bb.registerSourceCallTargetNode(callTargetNode);
+        }
+
+        for (Node node : newGraph.getNodes()) {
+            bb.registerSourceNode(node);
+        }
+
+        for (NewInstanceNode newInstance : newGraph.getNodes(NewInstanceNode.class)) {
+            Set<ResolvedJavaType> types = new HashSet<>();
+            types.add(newInstance.instanceClass());
+            System.out.println("propagate new instance " + newInstance + ", " + newInstance.instanceClass());
+            for (Node use : newInstance.usages()) {
+                Element element = bb.getSinkElement(use, newInstance);
+                assert element != null;
+                if (element != BLACK_HOLE) {
+                    element.postUnionTypes(bb, newInstance, types);
+                }
+            }
+        }
+    }
+
+    public ResolvedJavaMethod getResolvedJavaMethod() {
+        return resolvedJavaMethod;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/ParameterElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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.boot.meta;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+
+
+public class ParameterElement extends Element {
+
+    private int index;
+    private ResolvedJavaMethod method;
+
+    public ParameterElement(ResolvedJavaMethod method, int index) {
+        super(calculateDeclaredType(method, index));
+        this.method = method;
+        this.index = index;
+    }
+
+    private static ResolvedJavaType calculateDeclaredType(ResolvedJavaMethod m, int i) {
+        if (Modifier.isStatic(m.accessFlags())) {
+            return m.signature().argumentTypeAt(i, m.holder()).resolve(m.holder());
+        } else {
+            if (i == 0) {
+                return m.holder();
+            }
+            return m.signature().argumentTypeAt(i - 1, m.holder()).resolve(m.holder());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "[Parameter, index= " + index + " of method " + method + "]";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/PhiElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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.boot.meta;
+
+import com.oracle.graal.nodes.*;
+
+
+public class PhiElement extends Element {
+
+    private PhiNode phi;
+
+    public PhiElement(PhiNode phi) {
+        super(null);
+        this.phi = phi;
+        usages.add(phi);
+    }
+
+    @Override
+    public String toString() {
+        return "phi " + phi;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/ProxyElement.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,42 @@
+/*
+ * 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.boot.meta;
+
+import com.oracle.graal.nodes.*;
+
+
+public class ProxyElement extends Element {
+
+    private ValueProxyNode proxy;
+
+    public ProxyElement(ValueProxyNode proxy) {
+        super(null);
+        this.proxy = proxy;
+        usages.add(proxy);
+    }
+
+    @Override
+    public String toString() {
+        return "value proxy " + proxy;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeLookupSwitch.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009, 2011, 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.bytecode;
+
+/**
+ * A utility for processing {@link Bytecodes#LOOKUPSWITCH} bytecodes.
+ */
+public class BytecodeLookupSwitch extends BytecodeSwitch {
+    private static final int OFFSET_TO_NUMBER_PAIRS = 4;
+    private static final int OFFSET_TO_FIRST_PAIR_MATCH = 8;
+    private static final int OFFSET_TO_FIRST_PAIR_OFFSET = 12;
+    private static final int PAIR_SIZE = 8;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeLookupSwitch(BytecodeStream stream, int bci) {
+        super(stream, bci);
+    }
+
+    @Override
+    public int offsetAt(int i) {
+        return stream.readInt(alignedBci + OFFSET_TO_FIRST_PAIR_OFFSET + PAIR_SIZE * i);
+    }
+
+    @Override
+    public int keyAt(int i) {
+        return stream.readInt(alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * i);
+    }
+
+    @Override
+    public int numberOfCases() {
+        return stream.readInt(alignedBci + OFFSET_TO_NUMBER_PAIRS);
+    }
+
+    @Override
+    public int size() {
+        return alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * numberOfCases() - bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeStream.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2009, 2011, 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.bytecode;
+
+
+/**
+ * A utility class that makes iterating over bytecodes and reading operands
+ * simpler and less error prone. For example, it handles the {@link Bytecodes#WIDE} instruction
+ * and wide variants of instructions internally.
+ */
+public final class BytecodeStream {
+
+    private final byte[] code;
+    private int opcode;
+    private int curBCI;
+    private int nextBCI;
+
+    /**
+     * Creates a new {@code BytecodeStream} for the specified bytecode.
+     * @param code the array of bytes that contains the bytecode
+     */
+    public BytecodeStream(byte[] code) {
+        assert code != null;
+        this.code = code;
+        setBCI(0);
+    }
+
+    /**
+     * Advances to the next bytecode.
+     */
+    public void next() {
+        setBCI(nextBCI);
+    }
+
+    /**
+     * Gets the next bytecode index (no side-effects).
+     * @return the next bytecode index
+     */
+    public int nextBCI() {
+        return nextBCI;
+    }
+
+    /**
+     * Gets the current bytecode index.
+     * @return the current bytecode index
+     */
+    public int currentBCI() {
+        return curBCI;
+    }
+
+    /**
+     * Gets the bytecode index of the end of the code.
+     * @return the index of the end of the code
+     */
+    public int endBCI() {
+        return code.length;
+    }
+
+    /**
+     * Gets the current opcode. This method will never return the
+     * {@link Bytecodes#WIDE WIDE} opcode, but will instead
+     * return the opcode that is modified by the {@code WIDE} opcode.
+     * @return the current opcode; {@link Bytecodes#END} if at or beyond the end of the code
+     */
+    public int currentBC() {
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beU1(code, curBCI + 1);
+        } else {
+            return opcode;
+        }
+    }
+
+    /**
+     * Reads the index of a local variable for one of the load or store instructions.
+     * The WIDE modifier is handled internally.
+     * @return the index of the local variable
+     */
+    public int readLocalIndex() {
+        // read local variable index for load/store
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beU2(code, curBCI + 2);
+        }
+        return Bytes.beU1(code, curBCI + 1);
+    }
+
+    /**
+     * Read the delta for an {@link Bytecodes#IINC} bytecode.
+     * @return the delta for the {@code IINC}
+     */
+    public int readIncrement() {
+        // read the delta for the iinc bytecode
+        if (opcode == Bytecodes.WIDE) {
+            return Bytes.beS2(code, curBCI + 4);
+        }
+        return Bytes.beS1(code, curBCI + 2);
+    }
+
+    /**
+     * Read the destination of a {@link Bytecodes#GOTO} or {@code IF} instructions.
+     * @return the destination bytecode index
+     */
+    public int readBranchDest() {
+        // reads the destination for a branch bytecode
+        if (opcode == Bytecodes.GOTO_W || opcode == Bytecodes.JSR_W) {
+            return curBCI + Bytes.beS4(code, curBCI + 1);
+        } else {
+            return curBCI + Bytes.beS2(code, curBCI + 1);
+        }
+    }
+
+    /**
+     * Read a signed 4-byte integer from the bytecode stream at the specified bytecode index.
+     * @param bci the bytecode index
+     * @return the integer value
+     */
+    public int readInt(int bci) {
+        // reads a 4-byte signed value
+        return Bytes.beS4(code, bci);
+    }
+
+    /**
+     * Reads an unsigned, 1-byte value from the bytecode stream at the specified bytecode index.
+     * @param bci the bytecode index
+     * @return the byte
+     */
+    public int readUByte(int bci) {
+        return Bytes.beU1(code, bci);
+    }
+
+    /**
+     * Reads a constant pool index for the current instruction.
+     * @return the constant pool index
+     */
+    public char readCPI() {
+        if (opcode == Bytecodes.LDC) {
+            return (char) Bytes.beU1(code, curBCI + 1);
+        }
+        return (char) Bytes.beU2(code, curBCI + 1);
+    }
+
+    /**
+     * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH).
+     * @return the byte
+     */
+    public byte readByte() {
+        return code[curBCI + 1];
+    }
+
+    /**
+     * Reads a signed, 2-byte short for the current instruction (e.g. SIPUSH).
+     * @return the short value
+     */
+    public short readShort() {
+        return (short) Bytes.beS2(code, curBCI + 1);
+    }
+
+    /**
+     * Sets the bytecode index to the specified value.
+     * If {@code bci} is beyond the end of the array, {@link #currentBC} will return
+     * {@link Bytecodes#END} and other methods may throw {@link ArrayIndexOutOfBoundsException}.
+     * @param bci the new bytecode index
+     */
+    public void setBCI(int bci) {
+        curBCI = bci;
+        if (curBCI < code.length) {
+            opcode = Bytes.beU1(code, bci);
+            assert opcode < Bytecodes.BREAKPOINT : "illegal bytecode";
+            nextBCI = bci + lengthOf();
+        } else {
+            opcode = Bytecodes.END;
+            nextBCI = curBCI;
+        }
+    }
+
+    /**
+     * Gets the length of the current bytecode.
+     */
+    private int lengthOf() {
+        int length = Bytecodes.lengthOf(opcode);
+        if (length == 0) {
+            switch (opcode) {
+                case Bytecodes.TABLESWITCH: {
+                    return new BytecodeTableSwitch(this, curBCI).size();
+                }
+                case Bytecodes.LOOKUPSWITCH: {
+                    return new BytecodeLookupSwitch(this, curBCI).size();
+                }
+                case Bytecodes.WIDE: {
+                    int opc = Bytes.beU1(code, curBCI + 1);
+                    if (opc == Bytecodes.RET) {
+                        return 4;
+                    } else if (opc == Bytecodes.IINC) {
+                        return 6;
+                    } else {
+                        return 4; // a load or store bytecode
+                    }
+                }
+                default:
+                    throw new Error("unknown variable-length bytecode: " + opcode);
+            }
+        }
+        return length;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeSwitch.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2009, 2011, 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.bytecode;
+
+/**
+ * An abstract class that provides the state and methods common to {@link Bytecodes#LOOKUPSWITCH}
+ * and {@link Bytecodes#TABLESWITCH} instructions.
+ */
+public abstract class BytecodeSwitch {
+    /**
+     * The {@link BytecodeStream} containing the bytecode array.
+     */
+    protected final BytecodeStream stream;
+    /**
+     * Index of start of switch instruction.
+     */
+    protected final int bci;
+    /**
+     * Index of the start of the additional data for the switch instruction, aligned to a multiple of four from the method start.
+     */
+    protected final int alignedBci;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeSwitch(BytecodeStream stream, int bci) {
+        this.stream = stream;
+        this.bci = bci;
+        this.alignedBci = (bci + 4) & 0xfffffffc;
+    }
+
+    /**
+     * Gets the current bytecode index.
+     * @return the current bytecode index
+     */
+    public int bci() {
+        return bci;
+    }
+
+    /**
+     * Gets the index of the instruction denoted by the {@code i}'th switch target.
+     * @param i index of the switch target
+     * @return the index of the instruction denoted by the {@code i}'th switch target
+     */
+    public int targetAt(int i) {
+        return bci + offsetAt(i);
+    }
+
+    /**
+     * Gets the index of the instruction for the default switch target.
+     * @return the index of the instruction for the default switch target
+     */
+    public int defaultTarget() {
+        return bci + defaultOffset();
+    }
+
+    /**
+     * Gets the offset from the start of the switch instruction to the default switch target.
+     * @return the offset to the default switch target
+     */
+    public int defaultOffset() {
+        return stream.readInt(alignedBci);
+    }
+
+    /**
+     * Gets the key at {@code i}'th switch target index.
+     * @param i the switch target index
+     * @return the key at {@code i}'th switch target index
+     */
+    public abstract int keyAt(int i);
+
+    /**
+     * Gets the offset from the start of the switch instruction for the {@code i}'th switch target.
+     * @param i the switch target index
+     * @return the offset to the {@code i}'th switch target
+     */
+    public abstract int offsetAt(int i);
+
+    /**
+     * Gets the number of switch targets.
+     * @return the number of switch targets
+     */
+    public abstract int numberOfCases();
+
+    /**
+     * Gets the total size in bytes of the switch instruction.
+     * @return the total size in bytes of the switch instruction
+     */
+    public abstract int size();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/BytecodeTableSwitch.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009, 2011, 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.bytecode;
+
+/**
+ * A utility for processing {@link Bytecodes#TABLESWITCH} bytecodes.
+ */
+public class BytecodeTableSwitch extends BytecodeSwitch {
+    private static final int OFFSET_TO_LOW_KEY = 4;
+    private static final int OFFSET_TO_HIGH_KEY = 8;
+    private static final int OFFSET_TO_FIRST_JUMP_OFFSET = 12;
+    private static final int JUMP_OFFSET_SIZE = 4;
+
+    /**
+     * Constructor for a {@link BytecodeStream}.
+     * @param stream the {@code BytecodeStream} containing the switch instruction
+     * @param bci the index in the stream of the switch instruction
+     */
+    public BytecodeTableSwitch(BytecodeStream stream, int bci) {
+        super(stream, bci);
+    }
+
+    /**
+     * Gets the low key of the table switch.
+     * @return the low key
+     */
+    public int lowKey() {
+        return stream.readInt(alignedBci + OFFSET_TO_LOW_KEY);
+    }
+
+    /**
+     * Gets the high key of the table switch.
+     * @return the high key
+     */
+    public int highKey() {
+        return stream.readInt(alignedBci + OFFSET_TO_HIGH_KEY);
+    }
+
+    @Override
+    public int keyAt(int i) {
+        return lowKey() + i;
+    }
+
+    @Override
+    public int offsetAt(int i) {
+        return stream.readInt(alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * i);
+    }
+
+    @Override
+    public int numberOfCases() {
+        return highKey() - lowKey() + 1;
+    }
+
+    @Override
+    public int size() {
+        return alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * numberOfCases() - bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytecodes.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,940 @@
+/*
+ * Copyright (c) 2009, 2011, 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.bytecode;
+
+import static com.oracle.graal.bytecode.Bytecodes.Flags.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.regex.*;
+
+/**
+ * The definitions of the bytecodes that are valid input to the compiler and
+ * related utility methods. This comprises two groups: the standard Java
+ * bytecodes defined by <a href=
+ * "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html">
+ * Java Virtual Machine Specification</a>, and a set of <i>extended</i>
+ * bytecodes that support low-level programming, for example, memory barriers.
+ *
+ * The extended bytecodes are one or three bytes in size. The one-byte bytecodes
+ * follow the values in the standard set, with no gap. The three-byte extended
+ * bytecodes share a common first byte and carry additional instruction-specific
+ * information in the second and third bytes.
+ */
+public class Bytecodes {
+    public static final int NOP                  =   0; // 0x00
+    public static final int ACONST_NULL          =   1; // 0x01
+    public static final int ICONST_M1            =   2; // 0x02
+    public static final int ICONST_0             =   3; // 0x03
+    public static final int ICONST_1             =   4; // 0x04
+    public static final int ICONST_2             =   5; // 0x05
+    public static final int ICONST_3             =   6; // 0x06
+    public static final int ICONST_4             =   7; // 0x07
+    public static final int ICONST_5             =   8; // 0x08
+    public static final int LCONST_0             =   9; // 0x09
+    public static final int LCONST_1             =  10; // 0x0A
+    public static final int FCONST_0             =  11; // 0x0B
+    public static final int FCONST_1             =  12; // 0x0C
+    public static final int FCONST_2             =  13; // 0x0D
+    public static final int DCONST_0             =  14; // 0x0E
+    public static final int DCONST_1             =  15; // 0x0F
+    public static final int BIPUSH               =  16; // 0x10
+    public static final int SIPUSH               =  17; // 0x11
+    public static final int LDC                  =  18; // 0x12
+    public static final int LDC_W                =  19; // 0x13
+    public static final int LDC2_W               =  20; // 0x14
+    public static final int ILOAD                =  21; // 0x15
+    public static final int LLOAD                =  22; // 0x16
+    public static final int FLOAD                =  23; // 0x17
+    public static final int DLOAD                =  24; // 0x18
+    public static final int ALOAD                =  25; // 0x19
+    public static final int ILOAD_0              =  26; // 0x1A
+    public static final int ILOAD_1              =  27; // 0x1B
+    public static final int ILOAD_2              =  28; // 0x1C
+    public static final int ILOAD_3              =  29; // 0x1D
+    public static final int LLOAD_0              =  30; // 0x1E
+    public static final int LLOAD_1              =  31; // 0x1F
+    public static final int LLOAD_2              =  32; // 0x20
+    public static final int LLOAD_3              =  33; // 0x21
+    public static final int FLOAD_0              =  34; // 0x22
+    public static final int FLOAD_1              =  35; // 0x23
+    public static final int FLOAD_2              =  36; // 0x24
+    public static final int FLOAD_3              =  37; // 0x25
+    public static final int DLOAD_0              =  38; // 0x26
+    public static final int DLOAD_1              =  39; // 0x27
+    public static final int DLOAD_2              =  40; // 0x28
+    public static final int DLOAD_3              =  41; // 0x29
+    public static final int ALOAD_0              =  42; // 0x2A
+    public static final int ALOAD_1              =  43; // 0x2B
+    public static final int ALOAD_2              =  44; // 0x2C
+    public static final int ALOAD_3              =  45; // 0x2D
+    public static final int IALOAD               =  46; // 0x2E
+    public static final int LALOAD               =  47; // 0x2F
+    public static final int FALOAD               =  48; // 0x30
+    public static final int DALOAD               =  49; // 0x31
+    public static final int AALOAD               =  50; // 0x32
+    public static final int BALOAD               =  51; // 0x33
+    public static final int CALOAD               =  52; // 0x34
+    public static final int SALOAD               =  53; // 0x35
+    public static final int ISTORE               =  54; // 0x36
+    public static final int LSTORE               =  55; // 0x37
+    public static final int FSTORE               =  56; // 0x38
+    public static final int DSTORE               =  57; // 0x39
+    public static final int ASTORE               =  58; // 0x3A
+    public static final int ISTORE_0             =  59; // 0x3B
+    public static final int ISTORE_1             =  60; // 0x3C
+    public static final int ISTORE_2             =  61; // 0x3D
+    public static final int ISTORE_3             =  62; // 0x3E
+    public static final int LSTORE_0             =  63; // 0x3F
+    public static final int LSTORE_1             =  64; // 0x40
+    public static final int LSTORE_2             =  65; // 0x41
+    public static final int LSTORE_3             =  66; // 0x42
+    public static final int FSTORE_0             =  67; // 0x43
+    public static final int FSTORE_1             =  68; // 0x44
+    public static final int FSTORE_2             =  69; // 0x45
+    public static final int FSTORE_3             =  70; // 0x46
+    public static final int DSTORE_0             =  71; // 0x47
+    public static final int DSTORE_1             =  72; // 0x48
+    public static final int DSTORE_2             =  73; // 0x49
+    public static final int DSTORE_3             =  74; // 0x4A
+    public static final int ASTORE_0             =  75; // 0x4B
+    public static final int ASTORE_1             =  76; // 0x4C
+    public static final int ASTORE_2             =  77; // 0x4D
+    public static final int ASTORE_3             =  78; // 0x4E
+    public static final int IASTORE              =  79; // 0x4F
+    public static final int LASTORE              =  80; // 0x50
+    public static final int FASTORE              =  81; // 0x51
+    public static final int DASTORE              =  82; // 0x52
+    public static final int AASTORE              =  83; // 0x53
+    public static final int BASTORE              =  84; // 0x54
+    public static final int CASTORE              =  85; // 0x55
+    public static final int SASTORE              =  86; // 0x56
+    public static final int POP                  =  87; // 0x57
+    public static final int POP2                 =  88; // 0x58
+    public static final int DUP                  =  89; // 0x59
+    public static final int DUP_X1               =  90; // 0x5A
+    public static final int DUP_X2               =  91; // 0x5B
+    public static final int DUP2                 =  92; // 0x5C
+    public static final int DUP2_X1              =  93; // 0x5D
+    public static final int DUP2_X2              =  94; // 0x5E
+    public static final int SWAP                 =  95; // 0x5F
+    public static final int IADD                 =  96; // 0x60
+    public static final int LADD                 =  97; // 0x61
+    public static final int FADD                 =  98; // 0x62
+    public static final int DADD                 =  99; // 0x63
+    public static final int ISUB                 = 100; // 0x64
+    public static final int LSUB                 = 101; // 0x65
+    public static final int FSUB                 = 102; // 0x66
+    public static final int DSUB                 = 103; // 0x67
+    public static final int IMUL                 = 104; // 0x68
+    public static final int LMUL                 = 105; // 0x69
+    public static final int FMUL                 = 106; // 0x6A
+    public static final int DMUL                 = 107; // 0x6B
+    public static final int IDIV                 = 108; // 0x6C
+    public static final int LDIV                 = 109; // 0x6D
+    public static final int FDIV                 = 110; // 0x6E
+    public static final int DDIV                 = 111; // 0x6F
+    public static final int IREM                 = 112; // 0x70
+    public static final int LREM                 = 113; // 0x71
+    public static final int FREM                 = 114; // 0x72
+    public static final int DREM                 = 115; // 0x73
+    public static final int INEG                 = 116; // 0x74
+    public static final int LNEG                 = 117; // 0x75
+    public static final int FNEG                 = 118; // 0x76
+    public static final int DNEG                 = 119; // 0x77
+    public static final int ISHL                 = 120; // 0x78
+    public static final int LSHL                 = 121; // 0x79
+    public static final int ISHR                 = 122; // 0x7A
+    public static final int LSHR                 = 123; // 0x7B
+    public static final int IUSHR                = 124; // 0x7C
+    public static final int LUSHR                = 125; // 0x7D
+    public static final int IAND                 = 126; // 0x7E
+    public static final int LAND                 = 127; // 0x7F
+    public static final int IOR                  = 128; // 0x80
+    public static final int LOR                  = 129; // 0x81
+    public static final int IXOR                 = 130; // 0x82
+    public static final int LXOR                 = 131; // 0x83
+    public static final int IINC                 = 132; // 0x84
+    public static final int I2L                  = 133; // 0x85
+    public static final int I2F                  = 134; // 0x86
+    public static final int I2D                  = 135; // 0x87
+    public static final int L2I                  = 136; // 0x88
+    public static final int L2F                  = 137; // 0x89
+    public static final int L2D                  = 138; // 0x8A
+    public static final int F2I                  = 139; // 0x8B
+    public static final int F2L                  = 140; // 0x8C
+    public static final int F2D                  = 141; // 0x8D
+    public static final int D2I                  = 142; // 0x8E
+    public static final int D2L                  = 143; // 0x8F
+    public static final int D2F                  = 144; // 0x90
+    public static final int I2B                  = 145; // 0x91
+    public static final int I2C                  = 146; // 0x92
+    public static final int I2S                  = 147; // 0x93
+    public static final int LCMP                 = 148; // 0x94
+    public static final int FCMPL                = 149; // 0x95
+    public static final int FCMPG                = 150; // 0x96
+    public static final int DCMPL                = 151; // 0x97
+    public static final int DCMPG                = 152; // 0x98
+    public static final int IFEQ                 = 153; // 0x99
+    public static final int IFNE                 = 154; // 0x9A
+    public static final int IFLT                 = 155; // 0x9B
+    public static final int IFGE                 = 156; // 0x9C
+    public static final int IFGT                 = 157; // 0x9D
+    public static final int IFLE                 = 158; // 0x9E
+    public static final int IF_ICMPEQ            = 159; // 0x9F
+    public static final int IF_ICMPNE            = 160; // 0xA0
+    public static final int IF_ICMPLT            = 161; // 0xA1
+    public static final int IF_ICMPGE            = 162; // 0xA2
+    public static final int IF_ICMPGT            = 163; // 0xA3
+    public static final int IF_ICMPLE            = 164; // 0xA4
+    public static final int IF_ACMPEQ            = 165; // 0xA5
+    public static final int IF_ACMPNE            = 166; // 0xA6
+    public static final int GOTO                 = 167; // 0xA7
+    public static final int JSR                  = 168; // 0xA8
+    public static final int RET                  = 169; // 0xA9
+    public static final int TABLESWITCH          = 170; // 0xAA
+    public static final int LOOKUPSWITCH         = 171; // 0xAB
+    public static final int IRETURN              = 172; // 0xAC
+    public static final int LRETURN              = 173; // 0xAD
+    public static final int FRETURN              = 174; // 0xAE
+    public static final int DRETURN              = 175; // 0xAF
+    public static final int ARETURN              = 176; // 0xB0
+    public static final int RETURN               = 177; // 0xB1
+    public static final int GETSTATIC            = 178; // 0xB2
+    public static final int PUTSTATIC            = 179; // 0xB3
+    public static final int GETFIELD             = 180; // 0xB4
+    public static final int PUTFIELD             = 181; // 0xB5
+    public static final int INVOKEVIRTUAL        = 182; // 0xB6
+    public static final int INVOKESPECIAL        = 183; // 0xB7
+    public static final int INVOKESTATIC         = 184; // 0xB8
+    public static final int INVOKEINTERFACE      = 185; // 0xB9
+    public static final int XXXUNUSEDXXX         = 186; // 0xBA
+    public static final int NEW                  = 187; // 0xBB
+    public static final int NEWARRAY             = 188; // 0xBC
+    public static final int ANEWARRAY            = 189; // 0xBD
+    public static final int ARRAYLENGTH          = 190; // 0xBE
+    public static final int ATHROW               = 191; // 0xBF
+    public static final int CHECKCAST            = 192; // 0xC0
+    public static final int INSTANCEOF           = 193; // 0xC1
+    public static final int MONITORENTER         = 194; // 0xC2
+    public static final int MONITOREXIT          = 195; // 0xC3
+    public static final int WIDE                 = 196; // 0xC4
+    public static final int MULTIANEWARRAY       = 197; // 0xC5
+    public static final int IFNULL               = 198; // 0xC6
+    public static final int IFNONNULL            = 199; // 0xC7
+    public static final int GOTO_W               = 200; // 0xC8
+    public static final int JSR_W                = 201; // 0xC9
+    public static final int BREAKPOINT           = 202; // 0xCA
+
+    public static final int ILLEGAL = 255;
+    public static final int END = 256;
+
+    /**
+     * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
+     * <pre>
+     *     for (int opcode = 0; opcode <= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
+     *         //
+     *     }
+     * </pre>
+     */
+    public static final int LAST_JVM_OPCODE = JSR_W;
+
+    /**
+     * A collection of flags describing various bytecode attributes.
+     */
+    static class Flags {
+
+        /**
+         * Denotes an instruction that ends a basic block and does not let control flow fall through to its lexical successor.
+         */
+        static final int STOP = 0x00000001;
+
+        /**
+         * Denotes an instruction that ends a basic block and may let control flow fall through to its lexical successor.
+         * In practice this means it is a conditional branch.
+         */
+        static final int FALL_THROUGH = 0x00000002;
+
+        /**
+         * Denotes an instruction that has a 2 or 4 byte operand that is an offset to another instruction in the same method.
+         * This does not include the {@link Bytecodes#TABLESWITCH} or {@link Bytecodes#LOOKUPSWITCH} instructions.
+         */
+        static final int BRANCH = 0x00000004;
+
+        /**
+         * Denotes an instruction that reads the value of a static or instance field.
+         */
+        static final int FIELD_READ = 0x00000008;
+
+        /**
+         * Denotes an instruction that writes the value of a static or instance field.
+         */
+        static final int FIELD_WRITE = 0x00000010;
+
+        /**
+         * Denotes an instruction that is not defined in the JVM specification.
+         */
+        static final int EXTENSION = 0x00000020;
+
+        /**
+         * Denotes an instruction that can cause a trap.
+         */
+        static final int TRAP        = 0x00000080;
+        /**
+         * Denotes an instruction that is commutative.
+         */
+        static final int COMMUTATIVE = 0x00000100;
+        /**
+         * Denotes an instruction that is associative.
+         */
+        static final int ASSOCIATIVE = 0x00000200;
+        /**
+         * Denotes an instruction that loads an operand.
+         */
+        static final int LOAD        = 0x00000400;
+        /**
+         * Denotes an instruction that stores an operand.
+         */
+        static final int STORE       = 0x00000800;
+        /**
+         * Denotes the 4 INVOKE* instructions.
+         */
+        static final int INVOKE       = 0x00001000;
+    }
+
+    // Performs a sanity check that none of the flags overlap.
+    static {
+        int allFlags = 0;
+        try {
+            for (Field field : Flags.class.getDeclaredFields()) {
+                int flagsFilter = Modifier.FINAL | Modifier.STATIC;
+                if ((field.getModifiers() & flagsFilter) == flagsFilter && !field.isSynthetic()) {
+                    assert field.getType() == int.class : "Field is not int : " + field;
+                    final int flag = field.getInt(null);
+                    assert flag != 0;
+                    assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag";
+                    allFlags |= flag;
+                }
+            }
+        } catch (Exception e) {
+            throw new InternalError(e.toString());
+        }
+    }
+
+    /**
+     * An array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic.
+     * This will include the root instruction for the three-byte extended instructions.
+     */
+    private static final String[] nameArray = new String[256];
+
+    /**
+     * An array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction.
+     */
+    private static final int[] flagsArray = new int[256];
+
+    /**
+     * An array that maps from a bytecode value to the length in bytes for the corresponding instruction.
+     */
+    private static final int[] lengthArray = new int[256];
+
+    /**
+     * An array that maps from a bytecode value to the estimated complexity of the bytecode in terms of generated machine code.
+     */
+    private static final int[] compilationComplexityArray = new int[256];
+
+    // Checkstyle: stop
+    static {
+        def(NOP                 , "nop"             , "b"    , 0);
+        def(ACONST_NULL         , "aconst_null"     , "b"    , 0);
+        def(ICONST_M1           , "iconst_m1"       , "b"    , 0);
+        def(ICONST_0            , "iconst_0"        , "b"    , 0);
+        def(ICONST_1            , "iconst_1"        , "b"    , 0);
+        def(ICONST_2            , "iconst_2"        , "b"    , 0);
+        def(ICONST_3            , "iconst_3"        , "b"    , 0);
+        def(ICONST_4            , "iconst_4"        , "b"    , 0);
+        def(ICONST_5            , "iconst_5"        , "b"    , 0);
+        def(LCONST_0            , "lconst_0"        , "b"    , 0);
+        def(LCONST_1            , "lconst_1"        , "b"    , 0);
+        def(FCONST_0            , "fconst_0"        , "b"    , 0);
+        def(FCONST_1            , "fconst_1"        , "b"    , 0);
+        def(FCONST_2            , "fconst_2"        , "b"    , 0);
+        def(DCONST_0            , "dconst_0"        , "b"    , 0);
+        def(DCONST_1            , "dconst_1"        , "b"    , 0);
+        def(BIPUSH              , "bipush"          , "bc"   , 0);
+        def(SIPUSH              , "sipush"          , "bcc"  , 0);
+        def(LDC                 , "ldc"             , "bi"   , 0, TRAP);
+        def(LDC_W               , "ldc_w"           , "bii"  , 0, TRAP);
+        def(LDC2_W              , "ldc2_w"          , "bii"  , 0, TRAP);
+        def(ILOAD               , "iload"           , "bi"   , 0, LOAD);
+        def(LLOAD               , "lload"           , "bi"   , 0, LOAD);
+        def(FLOAD               , "fload"           , "bi"   , 0, LOAD);
+        def(DLOAD               , "dload"           , "bi"   , 0, LOAD);
+        def(ALOAD               , "aload"           , "bi"   , 0, LOAD);
+        def(ILOAD_0             , "iload_0"         , "b"    , 0, LOAD);
+        def(ILOAD_1             , "iload_1"         , "b"    , 0, LOAD);
+        def(ILOAD_2             , "iload_2"         , "b"    , 0, LOAD);
+        def(ILOAD_3             , "iload_3"         , "b"    , 0, LOAD);
+        def(LLOAD_0             , "lload_0"         , "b"    , 0, LOAD);
+        def(LLOAD_1             , "lload_1"         , "b"    , 0, LOAD);
+        def(LLOAD_2             , "lload_2"         , "b"    , 0, LOAD);
+        def(LLOAD_3             , "lload_3"         , "b"    , 0, LOAD);
+        def(FLOAD_0             , "fload_0"         , "b"    , 0, LOAD);
+        def(FLOAD_1             , "fload_1"         , "b"    , 0, LOAD);
+        def(FLOAD_2             , "fload_2"         , "b"    , 0, LOAD);
+        def(FLOAD_3             , "fload_3"         , "b"    , 0, LOAD);
+        def(DLOAD_0             , "dload_0"         , "b"    , 0, LOAD);
+        def(DLOAD_1             , "dload_1"         , "b"    , 0, LOAD);
+        def(DLOAD_2             , "dload_2"         , "b"    , 0, LOAD);
+        def(DLOAD_3             , "dload_3"         , "b"    , 0, LOAD);
+        def(ALOAD_0             , "aload_0"         , "b"    , 0, LOAD);
+        def(ALOAD_1             , "aload_1"         , "b"    , 0, LOAD);
+        def(ALOAD_2             , "aload_2"         , "b"    , 0, LOAD);
+        def(ALOAD_3             , "aload_3"         , "b"    , 0, LOAD);
+        def(IALOAD              , "iaload"          , "b"    , 0, TRAP);
+        def(LALOAD              , "laload"          , "b"    , 0, TRAP);
+        def(FALOAD              , "faload"          , "b"    , 0, TRAP);
+        def(DALOAD              , "daload"          , "b"    , 0, TRAP);
+        def(AALOAD              , "aaload"          , "b"    , 0, TRAP);
+        def(BALOAD              , "baload"          , "b"    , 0, TRAP);
+        def(CALOAD              , "caload"          , "b"    , 0, TRAP);
+        def(SALOAD              , "saload"          , "b"    , 0, TRAP);
+        def(ISTORE              , "istore"          , "bi"   , 0, STORE);
+        def(LSTORE              , "lstore"          , "bi"   , 0, STORE);
+        def(FSTORE              , "fstore"          , "bi"   , 0, STORE);
+        def(DSTORE              , "dstore"          , "bi"   , 0, STORE);
+        def(ASTORE              , "astore"          , "bi"   , 0, STORE);
+        def(ISTORE_0            , "istore_0"        , "b"    , 0, STORE);
+        def(ISTORE_1            , "istore_1"        , "b"    , 0, STORE);
+        def(ISTORE_2            , "istore_2"        , "b"    , 0, STORE);
+        def(ISTORE_3            , "istore_3"        , "b"    , 0, STORE);
+        def(LSTORE_0            , "lstore_0"        , "b"    , 0, STORE);
+        def(LSTORE_1            , "lstore_1"        , "b"    , 0, STORE);
+        def(LSTORE_2            , "lstore_2"        , "b"    , 0, STORE);
+        def(LSTORE_3            , "lstore_3"        , "b"    , 0, STORE);
+        def(FSTORE_0            , "fstore_0"        , "b"    , 0, STORE);
+        def(FSTORE_1            , "fstore_1"        , "b"    , 0, STORE);
+        def(FSTORE_2            , "fstore_2"        , "b"    , 0, STORE);
+        def(FSTORE_3            , "fstore_3"        , "b"    , 0, STORE);
+        def(DSTORE_0            , "dstore_0"        , "b"    , 0, STORE);
+        def(DSTORE_1            , "dstore_1"        , "b"    , 0, STORE);
+        def(DSTORE_2            , "dstore_2"        , "b"    , 0, STORE);
+        def(DSTORE_3            , "dstore_3"        , "b"    , 0, STORE);
+        def(ASTORE_0            , "astore_0"        , "b"    , 0, STORE);
+        def(ASTORE_1            , "astore_1"        , "b"    , 0, STORE);
+        def(ASTORE_2            , "astore_2"        , "b"    , 0, STORE);
+        def(ASTORE_3            , "astore_3"        , "b"    , 0, STORE);
+        def(IASTORE             , "iastore"         , "b"    , 3, TRAP);
+        def(LASTORE             , "lastore"         , "b"    , 3, TRAP);
+        def(FASTORE             , "fastore"         , "b"    , 3, TRAP);
+        def(DASTORE             , "dastore"         , "b"    , 3, TRAP);
+        def(AASTORE             , "aastore"         , "b"    , 4, TRAP);
+        def(BASTORE             , "bastore"         , "b"    , 3, TRAP);
+        def(CASTORE             , "castore"         , "b"    , 3, TRAP);
+        def(SASTORE             , "sastore"         , "b"    , 3, TRAP);
+        def(POP                 , "pop"             , "b"    , 0);
+        def(POP2                , "pop2"            , "b"    , 0);
+        def(DUP                 , "dup"             , "b"    , 0);
+        def(DUP_X1              , "dup_x1"          , "b"    , 0);
+        def(DUP_X2              , "dup_x2"          , "b"    , 0);
+        def(DUP2                , "dup2"            , "b"    , 0);
+        def(DUP2_X1             , "dup2_x1"         , "b"    , 0);
+        def(DUP2_X2             , "dup2_x2"         , "b"    , 0);
+        def(SWAP                , "swap"            , "b"    , 0);
+        def(IADD                , "iadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LADD                , "ladd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(FADD                , "fadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(DADD                , "dadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(ISUB                , "isub"            , "b"    , 1);
+        def(LSUB                , "lsub"            , "b"    , 1);
+        def(FSUB                , "fsub"            , "b"    , 1);
+        def(DSUB                , "dsub"            , "b"    , 1);
+        def(IMUL                , "imul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LMUL                , "lmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(FMUL                , "fmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(DMUL                , "dmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IDIV                , "idiv"            , "b"    , 1, TRAP);
+        def(LDIV                , "ldiv"            , "b"    , 1, TRAP);
+        def(FDIV                , "fdiv"            , "b"    , 1);
+        def(DDIV                , "ddiv"            , "b"    , 1);
+        def(IREM                , "irem"            , "b"    , 1, TRAP);
+        def(LREM                , "lrem"            , "b"    , 1, TRAP);
+        def(FREM                , "frem"            , "b"    , 1);
+        def(DREM                , "drem"            , "b"    , 1);
+        def(INEG                , "ineg"            , "b"    , 1);
+        def(LNEG                , "lneg"            , "b"    , 1);
+        def(FNEG                , "fneg"            , "b"    , 1);
+        def(DNEG                , "dneg"            , "b"    , 1);
+        def(ISHL                , "ishl"            , "b"    , 1);
+        def(LSHL                , "lshl"            , "b"    , 1);
+        def(ISHR                , "ishr"            , "b"    , 1);
+        def(LSHR                , "lshr"            , "b"    , 1);
+        def(IUSHR               , "iushr"           , "b"    , 1);
+        def(LUSHR               , "lushr"           , "b"    , 1);
+        def(IAND                , "iand"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LAND                , "land"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IOR                 , "ior"             , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LOR                 , "lor"             , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IXOR                , "ixor"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(LXOR                , "lxor"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
+        def(IINC                , "iinc"            , "bic"  , 1, LOAD | STORE);
+        def(I2L                 , "i2l"             , "b"    , 1);
+        def(I2F                 , "i2f"             , "b"    , 1);
+        def(I2D                 , "i2d"             , "b"    , 1);
+        def(L2I                 , "l2i"             , "b"    , 1);
+        def(L2F                 , "l2f"             , "b"    , 1);
+        def(L2D                 , "l2d"             , "b"    , 1);
+        def(F2I                 , "f2i"             , "b"    , 1);
+        def(F2L                 , "f2l"             , "b"    , 1);
+        def(F2D                 , "f2d"             , "b"    , 1);
+        def(D2I                 , "d2i"             , "b"    , 1);
+        def(D2L                 , "d2l"             , "b"    , 1);
+        def(D2F                 , "d2f"             , "b"    , 1);
+        def(I2B                 , "i2b"             , "b"    , 1);
+        def(I2C                 , "i2c"             , "b"    , 1);
+        def(I2S                 , "i2s"             , "b"    , 1);
+        def(LCMP                , "lcmp"            , "b"    , 1);
+        def(FCMPL               , "fcmpl"           , "b"    , 1);
+        def(FCMPG               , "fcmpg"           , "b"    , 1);
+        def(DCMPL               , "dcmpl"           , "b"    , 1);
+        def(DCMPG               , "dcmpg"           , "b"    , 1);
+        def(IFEQ                , "ifeq"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFNE                , "ifne"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFLT                , "iflt"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFGE                , "ifge"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFGT                , "ifgt"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFLE                , "ifle"            , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPNE           , "if_icmpne"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ICMPLT           , "if_icmplt"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPGE           , "if_icmpge"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ICMPLE           , "if_icmple"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(IF_ACMPNE           , "if_acmpne"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
+        def(GOTO                , "goto"            , "boo"  , 1, STOP | BRANCH);
+        def(JSR                 , "jsr"             , "boo"  , 0, STOP | BRANCH);
+        def(RET                 , "ret"             , "bi"   , 0, STOP);
+        def(TABLESWITCH         , "tableswitch"     , ""     , 4, STOP);
+        def(LOOKUPSWITCH        , "lookupswitch"    , ""     , 4, STOP);
+        def(IRETURN             , "ireturn"         , "b"    , 1, TRAP | STOP);
+        def(LRETURN             , "lreturn"         , "b"    , 1, TRAP | STOP);
+        def(FRETURN             , "freturn"         , "b"    , 1, TRAP | STOP);
+        def(DRETURN             , "dreturn"         , "b"    , 1, TRAP | STOP);
+        def(ARETURN             , "areturn"         , "b"    , 1, TRAP | STOP);
+        def(RETURN              , "return"          , "b"    , 1, TRAP | STOP);
+        def(GETSTATIC           , "getstatic"       , "bjj"  , 2, TRAP | FIELD_READ);
+        def(PUTSTATIC           , "putstatic"       , "bjj"  , 2, TRAP | FIELD_WRITE);
+        def(GETFIELD            , "getfield"        , "bjj"  , 2, TRAP | FIELD_READ);
+        def(PUTFIELD            , "putfield"        , "bjj"  , 2, TRAP | FIELD_WRITE);
+        def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , 7, TRAP | INVOKE);
+        def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , 5, TRAP | INVOKE);
+        def(INVOKESTATIC        , "invokestatic"    , "bjj"  , 5, TRAP | INVOKE);
+        def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", 7, TRAP | INVOKE);
+        def(XXXUNUSEDXXX        , "xxxunusedxxx"    , ""     , 0);
+        def(NEW                 , "new"             , "bii"  , 6, TRAP);
+        def(NEWARRAY            , "newarray"        , "bc"   , 6, TRAP);
+        def(ANEWARRAY           , "anewarray"       , "bii"  , 6, TRAP);
+        def(ARRAYLENGTH         , "arraylength"     , "b"    , 2, TRAP);
+        def(ATHROW              , "athrow"          , "b"    , 5, TRAP | STOP);
+        def(CHECKCAST           , "checkcast"       , "bii"  , 3, TRAP);
+        def(INSTANCEOF          , "instanceof"      , "bii"  , 4, TRAP);
+        def(MONITORENTER        , "monitorenter"    , "b"    , 5, TRAP);
+        def(MONITOREXIT         , "monitorexit"     , "b"    , 5, TRAP);
+        def(WIDE                , "wide"            , ""     , 0);
+        def(MULTIANEWARRAY      , "multianewarray"  , "biic" , 6, TRAP);
+        def(IFNULL              , "ifnull"          , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(IFNONNULL           , "ifnonnull"       , "boo"  , 2, FALL_THROUGH | BRANCH);
+        def(GOTO_W              , "goto_w"          , "boooo", 1, STOP | BRANCH);
+        def(JSR_W               , "jsr_w"           , "boooo", 0, STOP | BRANCH);
+        def(BREAKPOINT          , "breakpoint"      , "b"    , 0, TRAP);
+    }
+    // Checkstyle: resume
+
+    /**
+     * Determines if an opcode is commutative.
+     * @param opcode the opcode to check
+     * @return {@code true} iff commutative
+     */
+    public static boolean isCommutative(int opcode) {
+        return (flagsArray[opcode & 0xff] & COMMUTATIVE) != 0;
+    }
+
+    /**
+     * Gets the length of an instruction denoted by a given opcode.
+     *
+     * @param opcode an instruction opcode
+     * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a
+     *         variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned.
+     */
+    public static int lengthOf(int opcode) {
+        return lengthArray[opcode & 0xff];
+    }
+
+    /**
+     * Gets the compilation complexity for a given opcode.
+     * @param opcode an opcode
+     * @return a value >= 0
+     */
+    public static int compilationComplexity(int opcode) {
+        return compilationComplexityArray[opcode & 0xff];
+    }
+
+    /**
+     * Gets the lower-case mnemonic for a given opcode.
+     *
+     * @param opcode an opcode
+     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode
+     */
+    public static String nameOf(int opcode) throws IllegalArgumentException {
+        String name = nameArray[opcode & 0xff];
+        if (name == null) {
+            return "<illegal opcode: " + opcode + ">";
+        }
+        return name;
+    }
+
+    /**
+     * Allocation-free version of {@linkplain #nameOf(int)}.
+     * @param opcode an opcode.
+     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode.
+     */
+    public static String baseNameOf(int opcode) {
+        String name = nameArray[opcode & 0xff];
+        if (name == null) {
+            return "<illegal opcode>";
+        }
+        return name;
+    }
+
+    /**
+     * Gets the opcode corresponding to a given mnemonic.
+     *
+     * @param name an opcode mnemonic
+     * @return the opcode corresponding to {@code mnemonic}
+     * @throws IllegalArgumentException if {@code name} does not denote a valid opcode
+     */
+    public static int valueOf(String name) {
+        for (int opcode = 0; opcode < nameArray.length; ++opcode) {
+            if (name.equalsIgnoreCase(nameArray[opcode])) {
+                return opcode;
+            }
+        }
+        throw new IllegalArgumentException("No opcode for " + name);
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that can cause an implicit exception.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise
+     */
+    public static boolean canTrap(int opcode) {
+        return (flagsArray[opcode & 0xff] & TRAP) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise
+     */
+    public static boolean isLoad(int opcode) {
+        return (flagsArray[opcode & 0xff] & LOAD) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall
+     * through to its lexical successor.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} properly ends a basic block
+     */
+    public static boolean isStop(int opcode) {
+        return (flagsArray[opcode & 0xff] & STOP) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that stores a value to a local variable
+     * after popping it from the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
+     */
+    public static boolean isInvoke(int opcode) {
+        return (flagsArray[opcode & 0xff] & INVOKE) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an instruction that stores a value to a local variable
+     * after popping it from the operand stack.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
+     */
+    public static boolean isStore(int opcode) {
+        return (flagsArray[opcode & 0xff] & STORE) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is an instruction that delimits a basic block.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} delimits a basic block
+     */
+    public static boolean isBlockEnd(int opcode) {
+        return (flagsArray[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another
+     * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} is a branch instruction with a single operand
+     */
+    public static boolean isBranch(int opcode) {
+        return (flagsArray[opcode & 0xff] & BRANCH) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes a conditional branch.
+     * @param opcode
+     * @return {@code true} iff {@code opcode} is a conditional branch
+     */
+    public static boolean isConditionalBranch(int opcode) {
+        return (flagsArray[opcode & 0xff] & FALL_THROUGH) != 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes a standard bytecode. A standard bytecode is
+     * defined in the JVM specification.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} iff {@code opcode} is a standard bytecode
+     */
+    public static boolean isStandard(int opcode) {
+        return (flagsArray[opcode & 0xff] & EXTENSION) == 0;
+    }
+
+    /**
+     * Determines if a given opcode denotes an extended bytecode.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} if {@code opcode} is an extended bytecode
+     */
+    public static boolean isExtended(int opcode) {
+        return (flagsArray[opcode & 0xff] & EXTENSION) != 0;
+    }
+
+    /**
+     * Determines if a given opcode is a three-byte extended bytecode.
+     *
+     * @param opcode an opcode to test
+     * @return {@code true} if {@code (opcode & ~0xff) != 0}
+     */
+    public static boolean isThreeByteExtended(int opcode) {
+        return (opcode & ~0xff) != 0;
+    }
+
+    /**
+     * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an
+     * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned
+     * instead.
+     *
+     * @param op an opcode
+     * @return the arithmetic operator name
+     */
+    public static String operator(int op) {
+        // Checkstyle: stop
+        switch (op) {
+            // arithmetic ops
+            case IADD : // fall through
+            case LADD : // fall through
+            case FADD : // fall through
+            case DADD : return "+";
+            case ISUB : // fall through
+            case LSUB : // fall through
+            case FSUB : // fall through
+            case DSUB : return "-";
+            case IMUL : // fall through
+            case LMUL : // fall through
+            case FMUL : // fall through
+            case DMUL : return "*";
+            case IDIV : // fall through
+            case LDIV : // fall through
+            case FDIV : // fall through
+            case DDIV : return "/";
+            case IREM : // fall through
+            case LREM : // fall through
+            case FREM : // fall through
+            case DREM : return "%";
+            // shift ops
+            case ISHL : // fall through
+            case LSHL : return "<<";
+            case ISHR : // fall through
+            case LSHR : return ">>";
+            case IUSHR: // fall through
+            case LUSHR: return ">>>";
+            // logic ops
+            case IAND : // fall through
+            case LAND : return "&";
+            case IOR  : // fall through
+            case LOR  : return "|";
+            case IXOR : // fall through
+            case LXOR : return "^";
+        }
+        // Checkstyle: resume
+        return nameOf(op);
+    }
+
+    /**
+     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
+     *
+     * @param name instruction name (should be lower case)
+     * @param format encodes the length of the instruction
+     * @param flagsArray the set of {@link Flags} associated with the instruction
+     */
+    private static void def(int opcode, String name, String format, int compilationComplexity) {
+        def(opcode, name, format, compilationComplexity, 0);
+    }
+
+    /**
+     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
+     *
+     * @param name instruction name (lower case)
+     * @param format encodes the length of the instruction
+     * @param flags the set of {@link Flags} associated with the instruction
+     */
+    private static void def(int opcode, String name, String format, int compilationComplexity, int flags) {
+        assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode];
+        nameArray[opcode] = name;
+        int instructionLength = format.length();
+        lengthArray[opcode] = instructionLength;
+        compilationComplexityArray[opcode] = compilationComplexity;
+        Bytecodes.flagsArray[opcode] = flags;
+
+        assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch";
+    }
+
+    /**
+     * Utility for ensuring that the extended opcodes are contiguous and follow on directly
+     * from the standard JVM opcodes. If these conditions do not hold for the input source
+     * file, then it is modified 'in situ' to fix the problem.
+     *
+     * @param args {@code args[0]} is the path to this source file
+     */
+    public static void main(String[] args) throws Exception {
+        Method findWorkspaceDirectory = Class.forName("com.sun.max.ide.JavaProject").getDeclaredMethod("findWorkspaceDirectory");
+        File base = new File((File) findWorkspaceDirectory.invoke(null), "com.oracle.max.cri/src");
+        File file = new File(base, Bytecodes.class.getName().replace('.', File.separatorChar) + ".java").getAbsoluteFile();
+
+        Pattern opcodeDecl = Pattern.compile("(\\s*public static final int )(\\w+)(\\s*=\\s*)(\\d+)(;.*)");
+
+        BufferedReader br = new BufferedReader(new FileReader(file));
+        CharArrayWriter buffer = new CharArrayWriter((int) file.length());
+        PrintWriter out = new PrintWriter(buffer);
+        String line;
+        int lastExtendedOpcode = BREAKPOINT;
+        boolean modified = false;
+        int section = 0;
+        while ((line = br.readLine()) != null) {
+            if (section == 0) {
+                if (line.equals("    // Start extended bytecodes")) {
+                    section = 1;
+                }
+            } else if (section == 1) {
+                if (line.equals("    // End extended bytecodes")) {
+                    section = 2;
+                } else {
+                    Matcher matcher = opcodeDecl.matcher(line);
+                    if (matcher.matches()) {
+                        String name = matcher.group(2);
+                        String value = matcher.group(4);
+                        int opcode = Integer.parseInt(value);
+                        if (nameArray[opcode] == null || !nameArray[opcode].equalsIgnoreCase(name)) {
+                            throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + nameArray[opcode]);
+                        }
+                        if (opcode != lastExtendedOpcode + 1) {
+                            System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")");
+                            opcode = lastExtendedOpcode + 1;
+                            line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4));
+                            modified = true;
+                        }
+
+                        if (opcode >= 256) {
+                            throw new RuntimeException("Exceeded maximum opcode value with " + name);
+                        }
+
+                        lastExtendedOpcode = opcode;
+                    }
+                }
+            }
+
+            out.println(line);
+        }
+        if (section == 0) {
+            throw new RuntimeException("Did not find line starting extended bytecode declarations:\n\n    // Start extended bytecodes");
+        } else if (section == 1) {
+            throw new RuntimeException("Did not find line ending extended bytecode declarations:\n\n    // End extended bytecodes");
+        }
+
+        if (modified) {
+            out.flush();
+            FileWriter fileWriter = new FileWriter(file);
+            fileWriter.write(buffer.toCharArray());
+            fileWriter.close();
+
+            System.out.println("Modified: " + file);
+        }
+
+
+        // Uncomment to print out visitor method declarations:
+//        for (int opcode = 0; opcode < flags.length; ++opcode) {
+//            if (isExtension(opcode)) {
+//                String visitorParams = length(opcode) == 1 ? "" : "int index";
+//                System.out.println("@Override");
+//                System.out.println("protected void " + name(opcode) + "(" + visitorParams + ") {");
+//                System.out.println("}");
+//                System.out.println();
+//            }
+//        }
+
+        // Uncomment to print out visitor method declarations:
+//        for (int opcode = 0; opcode < flags.length; ++opcode) {
+//            if (isExtension(opcode)) {
+//                System.out.println("case " + name(opcode).toUpperCase() + ": {");
+//                String arg = "";
+//                int length = length(opcode);
+//                if (length == 2) {
+//                    arg = "readUnsigned1()";
+//                } else if (length == 3) {
+//                    arg = "readUnsigned2()";
+//                }
+//                System.out.println("    bytecodeVisitor." + name(opcode) + "(" + arg + ");");
+//                System.out.println("    break;");
+//                System.out.println("}");
+//            }
+//        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.bytecode/src/com/oracle/graal/bytecode/Bytes.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009, 2011, 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.bytecode;
+
+/**
+ * A collection of utility methods for dealing with bytes, particularly in byte arrays.
+ */
+public class Bytes {
+    /**
+     * Gets a signed 1-byte value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 1-byte value at index {@code bci} in array {@code data}
+     */
+    public static int beS1(byte[] data, int bci) {
+        return data[bci];
+    }
+
+    /**
+     * Gets a signed 2-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 2-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beS2(byte[] data, int bci) {
+        return (data[bci] << 8) | (data[bci + 1] & 0xff);
+    }
+
+    /**
+     * Gets an unsigned 1-byte value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the unsigned 1-byte value at index {@code bci} in array {@code data}
+     */
+    public static int beU1(byte[] data, int bci) {
+        return data[bci] & 0xff;
+    }
+
+    /**
+     * Gets an unsigned 2-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the unsigned 2-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beU2(byte[] data, int bci) {
+        return ((data[bci] & 0xff) << 8) | (data[bci + 1] & 0xff);
+    }
+
+    /**
+     * Gets a signed 4-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @return the signed 4-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beS4(byte[] data, int bci) {
+        return (data[bci] << 24) | ((data[bci + 1] & 0xff) << 16) | ((data[bci + 2] & 0xff) << 8) | (data[bci + 3] & 0xff);
+    }
+
+    /**
+     * Gets either a signed 2-byte or a signed 4-byte big-endian value.
+     * @param data the array containing the data
+     * @param bci the start index of the value to retrieve
+     * @param fourByte if true, this method will return a 4-byte value
+     * @return the signed 2 or 4-byte, big-endian, value at index {@code bci} in array {@code data}
+     */
+    public static int beSVar(byte[] data, int bci, boolean fourByte) {
+        if (fourByte) {
+            return beS4(data, bci);
+        } else {
+            return beS2(data, bci);
+        }
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -27,6 +27,8 @@
 import java.util.concurrent.*;
 
 import com.oracle.graal.alloc.simple.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.phases.*;
@@ -40,8 +42,6 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 
 public class GraalCompiler {
@@ -49,12 +49,12 @@
     /**
      * The target that this compiler has been configured for.
      */
-    public final CiTarget target;
+    public final TargetDescription target;
 
     /**
      * The runtime that this compiler has been configured for.
      */
-    public final GraalRuntime runtime;
+    public final ExtendedRiRuntime runtime;
 
     /**
      * The XIR generator that lowers Java operations to machine operations.
@@ -66,7 +66,7 @@
      */
     public final Backend backend;
 
-    public GraalCompiler(GraalRuntime runtime, CiTarget target, Backend backend, RiXirGenerator xirGen) {
+    public GraalCompiler(ExtendedRiRuntime runtime, TargetDescription target, Backend backend, RiXirGenerator xirGen) {
         this.runtime = runtime;
         this.target = target;
         this.xir = xirGen;
@@ -74,15 +74,15 @@
     }
 
 
-    public CiTargetMethod compileMethod(final RiResolvedMethod method, final StructuredGraph graph, int osrBCI, final RiGraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts) {
+    public CompilationResult compileMethod(final ResolvedJavaMethod method, final StructuredGraph graph, int osrBCI, final RiGraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts) {
         assert (method.accessFlags() & Modifier.NATIVE) == 0 : "compiling native methods is not supported";
         if (osrBCI != -1) {
-            throw new CiBailout("No OSR supported");
+            throw new BailoutException("No OSR supported");
         }
 
-        return Debug.scope("GraalCompiler", new Object[] {graph, method, this}, new Callable<CiTargetMethod>() {
-            public CiTargetMethod call() {
-                final CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null;
+        return Debug.scope("GraalCompiler", new Object[] {graph, method, this}, new Callable<CompilationResult>() {
+            public CompilationResult call() {
+                final Assumptions assumptions = GraalOptions.OptAssumptions ? new Assumptions() : null;
                 final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() {
                     public LIR call() {
                         return emitHIR(graph, assumptions, cache, plan, optimisticOpts);
@@ -90,11 +90,11 @@
                 });
                 final FrameMap frameMap = Debug.scope("BackEnd", lir, new Callable<FrameMap>() {
                     public FrameMap call() {
-                        return emitLIR(lir, graph, method);
+                        return emitLIR(lir, graph, method, assumptions);
                     }
                 });
-                return Debug.scope("CodeGen", frameMap, new Callable<CiTargetMethod>() {
-                    public CiTargetMethod call() {
+                return Debug.scope("CodeGen", frameMap, new Callable<CompilationResult>() {
+                    public CompilationResult call() {
                         return emitCode(assumptions, method, lir, frameMap);
                     }
                 });
@@ -105,7 +105,7 @@
     /**
      * Builds the graph, optimizes it.
      */
-    public LIR emitHIR(StructuredGraph graph, CiAssumptions assumptions, RiGraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
+    public LIR emitHIR(StructuredGraph graph, Assumptions assumptions, RiGraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
 
         if (graph.start().next() == null) {
             plan.runPhases(PhasePosition.AFTER_PARSING, graph);
@@ -134,69 +134,81 @@
 
         if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
             new InliningPhase(target, runtime, null, assumptions, cache, plan, optimisticOpts).apply(graph);
-            new DeadCodeEliminationPhase().apply(graph);
             new PhiStampPhase().apply(graph);
+
             if (GraalOptions.PropagateTypes) {
                 new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph);
             }
 
+            if (GraalOptions.CheckCastElimination) {
+                new CheckCastEliminationPhase().apply(graph);
+            }
+
             if (GraalOptions.OptCanonicalizer) {
                 new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
             }
         }
 
+        new ConvertUnreachedToGuardPhase(optimisticOpts).apply(graph);
 
         plan.runPhases(PhasePosition.HIGH_LEVEL, graph);
 
+        if (GraalOptions.FullUnroll) {
+            new LoopFullUnrollPhase(runtime).apply(graph);
+        }
+
         if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) {
             new EscapeAnalysisPhase(target, runtime, assumptions, cache, plan, optimisticOpts).apply(graph);
             new PhiStampPhase().apply(graph);
-            if (GraalOptions.OptCanonicalizer) {
-                new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
-            }
+        }
+        if (GraalOptions.OptLoopTransform) {
+            new LoopTransformHighPhase().apply(graph);
+        }
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+        }
+
+        new LoweringPhase(runtime, assumptions).apply(graph);
+
+        if (GraalOptions.CullFrameStates) {
+            new CullFrameStatesPhase().apply(graph);
         }
-        if (GraalOptions.OptLoops) {
-            if (GraalOptions.OptLoopTransform) {
-                new LoopTransformPhase().apply(graph);
-            }
+        new FloatingReadPhase().apply(graph);
+        if (GraalOptions.OptGVN) {
+            new GlobalValueNumberingPhase().apply(graph);
+        }
+        if (GraalOptions.OptReadElimination) {
+            new ReadEliminationPhase().apply(graph);
+        }
+
+        if (GraalOptions.PropagateTypes) {
+            new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph);
+        }
+
+        if (GraalOptions.CheckCastElimination) {
+            new CheckCastEliminationPhase().apply(graph);
+        }
+
+        if (GraalOptions.OptLoopTransform) {
+            new LoopTransformLowPhase().apply(graph);
         }
         new RemoveValueProxyPhase().apply(graph);
         if (GraalOptions.OptCanonicalizer) {
             new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
         }
-        if (GraalOptions.OptGVN) {
-            new GlobalValueNumberingPhase().apply(graph);
+        if (GraalOptions.CheckCastElimination) {
+            new CheckCastEliminationPhase().apply(graph);
         }
 
-        graph.mark();
-        new LoweringPhase(runtime).apply(graph);
-        new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph);
-
-        if (GraalOptions.Lower) {
-            new FloatingReadPhase().apply(graph);
-            if (GraalOptions.OptGVN) {
-                new GlobalValueNumberingPhase().apply(graph);
-            }
-            if (GraalOptions.OptReadElimination) {
-                new ReadEliminationPhase().apply(graph);
-            }
-        }
-
-        if (GraalOptions.PropagateTypes) {
-            new PropagateTypeCachePhase(target, runtime, assumptions).apply(graph);
-        }
-        if (GraalOptions.OptCanonicalizer) {
-            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
-        }
-        if (GraalOptions.OptGVN) {
-            new GlobalValueNumberingPhase().apply(graph);
-        }
-        new DeadCodeEliminationPhase().apply(graph);
 
         plan.runPhases(PhasePosition.MID_LEVEL, graph);
 
         plan.runPhases(PhasePosition.LOW_LEVEL, graph);
 
+        new DeadCodeEliminationPhase().apply(graph);
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+        }
         // Add safepoints to loops
         if (GraalOptions.GenLoopSafepoints) {
             new LoopSafepointInsertionPhase().apply(graph);
@@ -232,9 +244,9 @@
         });
     }
 
-    public FrameMap emitLIR(final LIR lir, StructuredGraph graph, final RiResolvedMethod method) {
+    public FrameMap emitLIR(final LIR lir, StructuredGraph graph, final ResolvedJavaMethod method, Assumptions assumptions) {
         final FrameMap frameMap = backend.newFrameMap(runtime.getRegisterConfig(method));
-        final LIRGenerator lirGenerator = backend.newLIRGenerator(graph, frameMap, method, lir, xir);
+        final LIRGenerator lirGenerator = backend.newLIRGenerator(graph, frameMap, method, lir, xir, assumptions);
 
         Debug.scope("LIRGen", lirGenerator, new Runnable() {
             public void run() {
@@ -259,10 +271,10 @@
         return frameMap;
     }
 
-    public CiTargetMethod emitCode(CiAssumptions assumptions, RiResolvedMethod method, LIR lir, FrameMap frameMap) {
+    public CompilationResult emitCode(Assumptions assumptions, ResolvedJavaMethod method, LIR lir, FrameMap frameMap) {
         TargetMethodAssembler tasm = backend.newAssembler(frameMap, lir);
         backend.emitCode(tasm, method, lir);
-        CiTargetMethod targetMethod = tasm.finishTargetMethod(method, false);
+        CompilationResult targetMethod = tasm.finishTargetMethod(method, false);
         if (assumptions != null && !assumptions.isEmpty()) {
             targetMethod.setAssumptions(assumptions);
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler;
 
+import com.oracle.max.criutils.TTY.Filter;
+
 /**
  * This class encapsulates options that control the behavior of the Graal compiler.
  * The help message for each option is specified by a {@linkplain #helpMap help map}.
@@ -35,7 +37,6 @@
     // Checkstyle: resume
 
     public static int     Threads                            = 4;
-    public static boolean Lower                              = true;
 
     // inlining settings
     public static boolean Inline                             = true;
@@ -99,7 +100,11 @@
     public static float   MinimumUsageProbability            = 0.95f;
 
     //loop transform settings
-    public static float   MinimumPeelProbability             = 0.25f;
+    public static float   MinimumPeelProbability             = 0.35f;
+    public static boolean ReassociateInvariants              = true;
+    public static boolean FullUnroll                         = true;
+    public static int     FullUnrollMaxNodes                 = 150; // TODO (gd) tune
+    public static boolean LoopUnswitch                       = ____;
 
     // debugging settings
     public static int     MethodEndBreakpointGuards          = 0;
@@ -162,6 +167,8 @@
 
     // Code generator settings
     public static boolean PropagateTypes                     = ____;
+    public static boolean CheckCastElimination               = true;
+    public static boolean CullFrameStates                    = ____;
     public static boolean UseProfilingInformation            = true;
            static boolean RemoveNeverExecutedCode            = true;
            static boolean UseExceptionProbability            = true;
@@ -180,6 +187,7 @@
     // Translating tableswitch instructions
     public static int     SequentialSwitchLimit              = 4;
     public static int     RangeTestsSwitchDensity            = 5;
+    public static double  MinTableSwitchDensity              = 0.5;
 
     public static boolean DetailedAsserts                    = ____;
 
@@ -197,7 +205,6 @@
     public static boolean OptReadElimination                 = true;
     public static boolean OptGVN                             = true;
     public static boolean OptCanonicalizer                   = true;
-    public static boolean OptLoops                           = true;
     public static boolean ScheduleOutOfLoops                 = true;
     public static boolean OptReorderLoops                    = true;
     public static boolean OptEliminateGuards                 = true;
@@ -207,6 +214,15 @@
     public static boolean OptSafepointElimination            = true;
 
     /**
+     * Insert a counter in the method prologue to track the most frequently called methods that were compiled by Graal.
+     */
+    public static boolean MethodEntryCounters               = false;
+    /**
+     * Number of caller program counters to distinguish when counting methods.
+     */
+    public static int     MethodEntryCountersCallers        = 20;
+
+    /**
      * Flag to turn on SSA-based register allocation, which is currently under development.
      */
     public static boolean AllocSSA                           = false;
@@ -216,6 +232,51 @@
      */
     public static boolean PrintFlags                           = false;
 
+    /**
+     * Counts the various paths taken through a compiled checkcast.
+     */
+    public static boolean CheckcastCounters = false;
+
+    /**
+     * If the probability that a checkcast will hit one the profiled types (up to {@link #CheckcastMaxHints})
+     * is below this value, the checkcast will be compiled without hints.
+     */
+    public static double CheckcastMinHintHitProbability = 0.5;
+
+    /**
+     * The maximum number of hint types that will be used when compiling a checkcast for which
+     * profiling information is available. Note that {@link #CheckcastMinHintHitProbability}
+     * also influences whether hints are used.
+     */
+    public static int CheckcastMaxHints = 2;
+
+    /**
+     * @see #CheckcastMinHintHitProbability
+     */
+    public static double InstanceOfMinHintHitProbability = 0.5;
+
+    /**
+     * @see #CheckcastMaxHints
+     */
+    public static int InstanceOfMaxHints = 1;
+
+    /**
+     * Use HIR lowering instead of LIR lowering for certain instructions.
+     * Only instructions in methods whose fully qualified name contains this option will be HIR lowered.
+     */
+    public static String HIRLowerCheckcast = "";
+    public static String HIRLowerNewInstance = "";
+
+    /**
+     * The profiling info cache directory.
+     */
+    public static String PICache = null;
+
+    /**
+     * Filters the methods for which profiling info is loaded from/saved to the {@link #PICache}.
+     */
+    public static String PIFilter = null;
+
     static {
         // turn detailed assertions on when the general assertions are on (misusing the assert keyword for this)
         assert (DetailedAsserts = true) == true;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/OptimisticOptimizations.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/OptimisticOptimizations.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,9 +24,9 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 
 
@@ -45,20 +45,20 @@
 
     private final Set<Optimization> enabledOpts;
 
-    public OptimisticOptimizations(RiResolvedMethod method) {
+    public OptimisticOptimizations(ResolvedJavaMethod method) {
         this.enabledOpts = EnumSet.noneOf(Optimization.class);
 
-        RiProfilingInfo profilingInfo = method.profilingInfo();
-        if (checkDeoptimizations(profilingInfo, RiDeoptReason.UnreachedCode)) {
+        ProfilingInfo profilingInfo = method.profilingInfo();
+        if (checkDeoptimizations(profilingInfo, DeoptimizationReason.UnreachedCode)) {
             enabledOpts.add(Optimization.RemoveNeverExecutedCode);
         }
-        if (checkDeoptimizations(profilingInfo, RiDeoptReason.TypeCheckedInliningViolated)) {
+        if (checkDeoptimizations(profilingInfo, DeoptimizationReason.TypeCheckedInliningViolated)) {
             enabledOpts.add(Optimization.UseTypeCheckedInlining);
         }
-        if (checkDeoptimizations(profilingInfo, RiDeoptReason.OptimizedTypeCheckViolated)) {
+        if (checkDeoptimizations(profilingInfo, DeoptimizationReason.OptimizedTypeCheckViolated)) {
             enabledOpts.add(Optimization.UseTypeCheckHints);
         }
-        if (checkDeoptimizations(profilingInfo, RiDeoptReason.NotCompiledExceptionHandler)) {
+        if (checkDeoptimizations(profilingInfo, DeoptimizationReason.NotCompiledExceptionHandler)) {
             enabledOpts.add(Optimization.UseExceptionProbability);
         }
     }
@@ -67,11 +67,11 @@
         this.enabledOpts = enabledOpts;
     }
 
-    public void log(RiMethod method) {
+    public void log(JavaMethod method) {
         for (Optimization opt: Optimization.values()) {
             if (!enabledOpts.contains(opt)) {
                 if (GraalOptions.PrintDisabledOptimisticOptimizations) {
-                    TTY.println("WARN: deactivated optimistic optimization %s for %s", opt.name(), CiUtil.format("%H.%n(%p)", method));
+                    TTY.println("WARN: deactivated optimistic optimization %s for %s", opt.name(), CodeUtil.format("%H.%n(%p)", method));
                 }
                 disabledOptimisticOptsMetric.increment();
             }
@@ -82,7 +82,7 @@
         return GraalOptions.RemoveNeverExecutedCode && enabledOpts.contains(Optimization.RemoveNeverExecutedCode);
     }
 
-    public boolean useUseTypeCheckHints() {
+    public boolean useTypeCheckHints() {
         return GraalOptions.UseTypeCheckHints && enabledOpts.contains(Optimization.UseTypeCheckHints);
     }
 
@@ -111,7 +111,7 @@
         return false;
     }
 
-    private static boolean checkDeoptimizations(RiProfilingInfo profilingInfo, RiDeoptReason reason) {
+    private static boolean checkDeoptimizations(ProfilingInfo profilingInfo, DeoptimizationReason reason) {
         return profilingInfo.getDeoptimizationCount(reason) < GraalOptions.DeoptsToDisableOptimisticOptimization;
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/ComputeLinearScanOrder.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/ComputeLinearScanOrder.java	Wed Jun 27 17:35:32 2012 +0200
@@ -38,17 +38,17 @@
     List<Block> linearScanOrder; // the resulting list of blocks in correct order
     List<Block> codeEmittingOrder;
 
-    final BitMap visitedBlocks; // used for recursive processing of blocks
-    final BitMap activeBlocks; // used for recursive processing of blocks
-    final BitMap dominatorBlocks; // temporary BitMap used for computation of dominator
+    final BitSet visitedBlocks; // used for recursive processing of blocks
+    final BitSet activeBlocks; // used for recursive processing of blocks
+    final BitSet dominatorBlocks; // temporary BitMap used for computation of dominator
     final int[] forwardBranches; // number of incoming forward branches for each block
     final List<Block> workList; // temporary list (used in markLoops and computeOrder)
     final Block[] loopHeaders;
 
     // accessors for visitedBlocks and activeBlocks
     void initVisited() {
-        activeBlocks.clearAll();
-        visitedBlocks.clearAll();
+        activeBlocks.clear();
+        visitedBlocks.clear();
     }
 
     boolean isVisited(Block b) {
@@ -91,9 +91,9 @@
     public ComputeLinearScanOrder(int maxBlockId, int loopCount, Block startBlock) {
         loopHeaders = new Block[loopCount];
 
-        visitedBlocks = new BitMap(maxBlockId);
-        activeBlocks = new BitMap(maxBlockId);
-        dominatorBlocks = new BitMap(maxBlockId);
+        visitedBlocks = new BitSet(maxBlockId);
+        activeBlocks = new BitSet(maxBlockId);
+        dominatorBlocks = new BitSet(maxBlockId);
         forwardBranches = new int[maxBlockId];
         workList = new ArrayList<>(8);
 
@@ -304,13 +304,21 @@
             Block cur = workList.remove(workList.size() - 1);
             appendBlock(cur);
 
-            int i;
-            int numSux = cur.numberOfSux();
-            // changed loop order to get "intuitive" order of if- and else-blocks
-            for (i = 0; i < numSux; i++) {
-                Block sux = cur.suxAt(i);
-                if (readyForProcessing(sux)) {
-                    sortIntoWorkList(sux);
+            // make the most successor with the highest probability the immediate successor
+            Node endNode = cur.getEndNode();
+            if (endNode instanceof IfNode && ((IfNode) endNode).probability() < 0.5) {
+                assert cur.numberOfSux() == 2;
+                if (readyForProcessing(cur.suxAt(1))) {
+                    sortIntoWorkList(cur.suxAt(1));
+                }
+                if (readyForProcessing(cur.suxAt(0))) {
+                    sortIntoWorkList(cur.suxAt(0));
+                }
+            } else {
+                for (Block sux : cur.getSuccessors()) {
+                    if (readyForProcessing(sux)) {
+                        sortIntoWorkList(sux);
+                    }
                 }
             }
         } while (workList.size() > 0);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/ControlFlowOptimizer.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/ControlFlowOptimizer.java	Wed Jun 27 17:35:32 2012 +0200
@@ -178,6 +178,16 @@
                     }
                 }
             }
+            // TODO(ls) enable this optimization
+//            lastOp = instructions.get(instructions.size() - 1);
+//            if (lastOp instanceof FallThroughOp) {
+//                FallThroughOp fallThrough = (FallThroughOp) lastOp;
+//                if (fallThrough.fallThroughTarget() != null && lastOp.info == null) {
+//                    if (fallThrough.fallThroughTarget().label() == ((StandardOp.LabelOp) code.get(i + 1).lir.get(0)).getLabel()) {
+//                        fallThrough.setFallThroughTarget(null);
+//                    }
+//                }
+//            }
         }
 
         assert verify(code);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,8 +26,9 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.util.*;
 import com.oracle.graal.graph.*;
@@ -399,30 +400,30 @@
     }
 
     /**
-     * The {@linkplain CiRegisterValue register} or {@linkplain Variable variable} for this interval prior to register allocation.
+     * The {@linkplain RegisterValue register} or {@linkplain Variable variable} for this interval prior to register allocation.
      */
-    public final CiValue operand;
+    public final Value operand;
 
     /**
-     * The {@linkplain OperandPool#operandNumber(CiValue) operand number} for this interval's {@linkplain #operand operand}.
+     * The {@linkplain OperandPool#operandNumber(Value) operand number} for this interval's {@linkplain #operand operand}.
      */
     public final int operandNumber;
 
     /**
-     * The {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval.
+     * The {@linkplain RegisterValue register}, {@linkplain StackSlot spill slot} or {@linkplain Address address} assigned to this interval.
      */
-    private CiValue location;
+    private Value location;
 
     /**
      * The stack slot to which all splits of this interval are spilled if necessary.
      */
-    private CiStackSlot spillSlot;
+    private StackSlot spillSlot;
 
     /**
      * The kind of this interval.
      * Only valid if this is a {@linkplain #xxisVariable() variable}.
      */
-    private CiKind kind;
+    private Kind kind;
 
     /**
      * The head of the list of ranges describing this interval. This list is sorted by {@linkplain LIRInstruction#id instruction ids}.
@@ -486,37 +487,37 @@
      */
     private Interval locationHint;
 
-    void assignLocation(CiValue newLocation) {
+    void assignLocation(Value newLocation) {
         if (isRegister(newLocation)) {
             assert this.location == null : "cannot re-assign location for " + this;
-            if (newLocation.kind == CiKind.Illegal && kind != CiKind.Illegal) {
+            if (newLocation.kind == Kind.Illegal && kind != Kind.Illegal) {
                 this.location = asRegister(newLocation).asValue(kind);
                 return;
             }
         } else {
             assert this.location == null || isRegister(this.location) : "cannot re-assign location for " + this;
             assert isStackSlot(newLocation);
-            assert newLocation.kind != CiKind.Illegal;
+            assert newLocation.kind != Kind.Illegal;
             assert newLocation.kind == this.kind;
         }
         this.location = newLocation;
     }
 
     /**
-     * Gets the {@linkplain CiRegisterValue register}, {@linkplain CiStackSlot spill slot} or {@linkplain CiAddress address} assigned to this interval.
+     * Gets the {@linkplain RegisterValue register}, {@linkplain StackSlot spill slot} or {@linkplain Address address} assigned to this interval.
      */
-    public CiValue location() {
+    public Value location() {
         return location;
     }
 
-    public CiKind kind() {
+    public Kind kind() {
         assert !isRegister(operand) : "cannot access type for fixed interval";
         return kind;
     }
 
-    void setKind(CiKind kind) {
-        assert isRegister(operand) || this.kind() == CiKind.Illegal || this.kind() == kind : "overwriting existing type";
-        assert kind == kind.stackKind() || kind == CiKind.Short : "these kinds should have int type registers";
+    void setKind(Kind kind) {
+        assert isRegister(operand) || this.kind() == Kind.Illegal || this.kind() == kind : "overwriting existing type";
+        assert kind == kind.stackKind() || kind == Kind.Short : "these kinds should have int type registers";
         this.kind = kind;
     }
 
@@ -563,11 +564,11 @@
     /**
      * Gets the canonical spill slot for this interval.
      */
-    CiStackSlot spillSlot() {
+    StackSlot spillSlot() {
         return splitParent().spillSlot;
     }
 
-    void setSpillSlot(CiStackSlot slot) {
+    void setSpillSlot(StackSlot slot) {
         assert splitParent().spillSlot == null : "connot overwrite existing spill slot";
         splitParent().spillSlot = slot;
     }
@@ -658,9 +659,9 @@
     /**
      * Sentinel interval to denote the end of an interval list.
      */
-    static final Interval EndMarker = new Interval(CiValue.IllegalValue, -1);
+    static final Interval EndMarker = new Interval(Value.IllegalValue, -1);
 
-    Interval(CiValue operand, int operandNumber) {
+    Interval(Value operand, int operandNumber) {
         assert operand != null;
         this.operand = operand;
         this.operandNumber = operandNumber;
@@ -669,7 +670,7 @@
         } else {
             assert isIllegal(operand) || isVariable(operand);
         }
-        this.kind = CiKind.Illegal;
+        this.kind = Kind.Illegal;
         this.first = Range.EndMarker;
         this.usePosList = new UsePosList(4);
         this.current = Range.EndMarker;
@@ -800,7 +801,7 @@
                     TTY.println(String.format("two valid result intervals found for opId %d: %d and %d", opId, result.operandNumber, interval.operandNumber));
                     TTY.println(result.logString(allocator));
                     TTY.println(interval.logString(allocator));
-                    throw new CiBailout("two valid result intervals found");
+                    throw new BailoutException("two valid result intervals found");
                 }
             }
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,15 +22,13 @@
  */
 package com.oracle.graal.compiler.alloc;
 
-import static com.oracle.max.cri.ci.CiUtil.*;
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.graal.alloc.util.LocationUtil.*;
-
+import static com.oracle.graal.api.code.CodeUtil.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.alloc.Interval.RegisterBinding;
 import com.oracle.graal.compiler.alloc.Interval.RegisterPriority;
@@ -51,13 +49,13 @@
  */
 public final class LinearScan {
 
-    final CiTarget target;
-    final RiMethod method;
+    final TargetDescription target;
+    final JavaMethod method;
     final LIR ir;
     final LIRGenerator gen;
     final FrameMap frameMap;
-    final RiRegisterAttributes[] registerAttributes;
-    final CiRegister[] registers;
+    final RegisterAttributes[] registerAttributes;
+    final Register[] registers;
 
     private static final int INITIAL_SPLIT_INTERVALS_CAPACITY = 32;
 
@@ -66,30 +64,30 @@
          * Bit map specifying which {@linkplain OperandPool operands} are live upon entry to this block.
          * These are values used in this block or any of its successors where such value are not defined
          * in this block.
-         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.oracle.max.cri.Value.RiValue.ci.CiValue) operand number}.
          */
-        public BitMap liveIn;
+        public BitSet liveIn;
 
         /**
          * Bit map specifying which {@linkplain OperandPool operands} are live upon exit from this block.
          * These are values used in a successor block that are either defined in this block or were live
          * upon entry to this block.
-         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.oracle.max.cri.Value.RiValue.ci.CiValue) operand number}.
          */
-        public BitMap liveOut;
+        public BitSet liveOut;
 
         /**
          * Bit map specifying which {@linkplain OperandPool operands} are used (before being defined) in this block.
          * That is, these are the values that are live upon entry to the block.
-         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.oracle.max.cri.Value.RiValue.ci.CiValue) operand number}.
          */
-        public BitMap liveGen;
+        public BitSet liveGen;
 
         /**
          * Bit map specifying which {@linkplain OperandPool operands} are defined/overwritten in this block.
-         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.sun.cri.ci.CiValue) operand number}.
+         * The bit index of an operand is its {@linkplain OperandPool#operandNumber(com.oracle.max.cri.Value.RiValue.ci.CiValue) operand number}.
          */
-        public BitMap liveKill;
+        public BitSet liveKill;
     }
 
     public final BlockMap<BlockData> blockData;
@@ -100,7 +98,7 @@
     final Block[] sortedBlocks;
 
     /**
-     * Map from {@linkplain #operandNumber(CiValue) operand numbers} to intervals.
+     * Map from {@linkplain #operandNumber(Value) operand numbers} to intervals.
      */
     Interval[] intervals;
 
@@ -139,20 +137,20 @@
     BitMap2D intervalInLoop;
 
     /**
-     * The variable operands allocated from this pool. The {@linkplain #operandNumber(CiValue) number}
+     * The variable operands allocated from this pool. The {@linkplain #operandNumber(Value) number}
      * of the first variable operand in this pool is one greater than the number of the last
      * register operand in the pool.
      */
     private final ArrayList<Variable> variables;
 
     /**
-     * The {@linkplain #operandNumber(CiValue) number} of the first variable operand
-     * {@linkplain #newVariable(CiKind) allocated} from this pool.
+     * The {@linkplain #operandNumber(Value) number} of the first variable operand
+     * {@linkplain #newVariable(Kind) allocated} from this pool.
      */
     private final int firstVariableNumber;
 
 
-    public LinearScan(CiTarget target, RiResolvedMethod method, LIR ir, LIRGenerator gen, FrameMap frameMap) {
+    public LinearScan(TargetDescription target, ResolvedJavaMethod method, LIR ir, LIRGenerator gen, FrameMap frameMap) {
         this.target = target;
         this.method = method;
         this.ir = ir;
@@ -167,17 +165,17 @@
         this.blockData = new BlockMap<>(ir.cfg);
     }
 
-    public static boolean isVariableOrRegister(CiValue value) {
+    public static boolean isVariableOrRegister(Value value) {
         return isVariable(value) || isRegister(value);
     }
 
 
     /**
      * Converts an operand (variable or register) to an index in a flat address space covering all the
-     * {@linkplain Variable variables} and {@linkplain CiRegisterValue registers} being processed by this
+     * {@linkplain Variable variables} and {@linkplain RegisterValue registers} being processed by this
      * allocator.
      */
-    private int operandNumber(CiValue operand) {
+    private int operandNumber(Value operand) {
         if (isRegister(operand)) {
             int number = asRegister(operand).number;
             assert number < firstVariableNumber;
@@ -190,7 +188,7 @@
     /**
      * Gets the operand denoted by a given operand number.
      */
-    private CiValue operandFor(int operandNumber) {
+    private Value operandFor(int operandNumber) {
         if (operandNumber < firstVariableNumber) {
             assert operandNumber >= 0;
             return registers[operandNumber].asValue();
@@ -233,14 +231,14 @@
     static final IntervalPredicate IS_OOP_INTERVAL = new IntervalPredicate() {
         @Override
         public boolean apply(Interval i) {
-            return !isRegister(i.operand) && i.kind()  == CiKind.Object;
+            return !isRegister(i.operand) && i.kind()  == Kind.Object;
         }
     };
 
     /**
      * Gets an object describing the attributes of a given register according to this register configuration.
      */
-    RiRegisterAttributes attributes(CiRegister reg) {
+    RegisterAttributes attributes(Register reg) {
         return registerAttributes[reg.number];
     }
 
@@ -250,7 +248,7 @@
         if (interval.spillSlot() != null) {
             interval.assignLocation(interval.spillSlot());
         } else {
-            CiStackSlot slot = frameMap.allocateSpillSlot(interval.kind());
+            StackSlot slot = frameMap.allocateSpillSlot(interval.kind());
             interval.setSpillSlot(slot);
             interval.assignLocation(slot);
         }
@@ -262,7 +260,7 @@
      * @param operand the operand for the interval
      * @return the created interval
      */
-    Interval createInterval(CiValue operand) {
+    Interval createInterval(Value operand) {
         assert isProcessed(operand);
         assert isLegal(operand);
         int operandNumber = operandNumber(operand);
@@ -324,7 +322,7 @@
         return intervalInLoop.at(interval, loop);
     }
 
-    Interval intervalFor(CiValue operand) {
+    Interval intervalFor(Value operand) {
         int operandNumber = operandNumber(operand);
         assert operandNumber < intervalsSize;
         return intervals[operandNumber];
@@ -419,7 +417,7 @@
                 break;
 
             default:
-                throw new CiBailout("other states not allowed at this time");
+                throw new BailoutException("other states not allowed at this time");
         }
     }
 
@@ -458,7 +456,7 @@
                 break;
 
             default:
-                throw new CiBailout("other states not allowed at this time");
+                throw new BailoutException("other states not allowed at this time");
         }
     }
 
@@ -526,8 +524,8 @@
                             insertionBuffer.init(block.lir);
                         }
 
-                        CiValue fromLocation = interval.location();
-                        CiValue toLocation = canonicalSpillOpr(interval);
+                        Value fromLocation = interval.location();
+                        Value toLocation = canonicalSpillOpr(interval);
 
                         assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
                         assert isStackSlot(toLocation) : "to operand must be a stack slot";
@@ -535,7 +533,7 @@
                         insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation));
 
                         if (GraalOptions.TraceLinearScanLevel >= 4) {
-                            CiStackSlot slot = interval.spillSlot();
+                            StackSlot slot = interval.spillSlot();
                             TTY.println("inserting move after definition of interval %d to stack slot %s at opId %d",
                                             interval.operandNumber, slot, opId);
                         }
@@ -582,7 +580,7 @@
     void numberInstructions() {
         ValueProcedure setVariableProc = new ValueProcedure() {
             @Override
-            public CiValue doValue(CiValue value) {
+            public Value doValue(Value value) {
                 if (isVariable(value)) {
                     int variableIdx = asVariable(value).index;
                     while (variables.size() <= variableIdx) {
@@ -653,8 +651,8 @@
         // iterate all blocks
         for (int i = 0; i < numBlocks; i++) {
             final Block block = blockAt(i);
-            final BitMap liveGen = new BitMap(liveSize);
-            final BitMap liveKill = new BitMap(liveSize);
+            final BitSet liveGen = new BitSet(liveSize);
+            final BitSet liveKill = new BitSet(liveSize);
 
             List<LIRInstruction> instructions = block.lir;
             int numInst = instructions.size();
@@ -666,7 +664,7 @@
 
                 ValueProcedure useProc = new ValueProcedure() {
                     @Override
-                    protected CiValue doValue(CiValue operand) {
+                    protected Value doValue(Value operand) {
                         if (isVariable(operand)) {
                             int operandNum = operandNumber(operand);
                             if (!liveKill.get(operandNum)) {
@@ -688,7 +686,7 @@
                 };
                 ValueProcedure stateProc = new ValueProcedure() {
                     @Override
-                    public CiValue doValue(CiValue operand) {
+                    public Value doValue(Value operand) {
                         int operandNum = operandNumber(operand);
                         if (!liveKill.get(operandNum)) {
                             liveGen.set(operandNum);
@@ -701,7 +699,7 @@
                 };
                 ValueProcedure defProc = new ValueProcedure() {
                     @Override
-                    public CiValue doValue(CiValue operand) {
+                    public Value doValue(Value operand) {
                         if (isVariable(operand)) {
                             int varNum = operandNumber(operand);
                             liveKill.set(varNum);
@@ -730,8 +728,8 @@
 
             blockData.get(block).liveGen = liveGen;
             blockData.get(block).liveKill = liveKill;
-            blockData.get(block).liveIn = new BitMap(liveSize);
-            blockData.get(block).liveOut = new BitMap(liveSize);
+            blockData.get(block).liveIn = new BitSet(liveSize);
+            blockData.get(block).liveOut = new BitSet(liveSize);
 
             if (GraalOptions.TraceLinearScanLevel >= 4) {
                 TTY.println("liveGen  B%d %s", block.getId(), blockData.get(block).liveGen);
@@ -740,7 +738,7 @@
         } // end of block iteration
     }
 
-    private void verifyTemp(BitMap liveKill, CiValue operand) {
+    private void verifyTemp(BitSet liveKill, Value operand) {
         // fixed intervals are never live at block boundaries, so
         // they need not be processed in live sets
         // process them only in debug mode so that this can be checked
@@ -751,7 +749,7 @@
         }
     }
 
-    private void verifyInput(Block block, BitMap liveKill, CiValue operand) {
+    private void verifyInput(Block block, BitSet liveKill, Value operand) {
         // fixed intervals are never live at block boundaries, so
         // they need not be processed in live sets.
         // this is checked by these assertions to be sure about it.
@@ -773,7 +771,7 @@
         boolean changeOccurred;
         boolean changeOccurredInBlock;
         int iterationCount = 0;
-        BitMap liveOut = new BitMap(liveSetSize()); // scratch set for calculations
+        BitSet liveOut = new BitSet(liveSetSize()); // scratch set for calculations
 
         // Perform a backward dataflow analysis to compute liveOut and liveIn for each block.
         // The loop is executed until a fixpoint is reached (no changes in an iteration)
@@ -791,17 +789,18 @@
                 if (n > 0) {
                     // block has successors
                     if (n > 0) {
-                        liveOut.setFrom(blockData.get(block.suxAt(0)).liveIn);
+                        liveOut.clear();
+                        liveOut.or(blockData.get(block.suxAt(0)).liveIn);
                         for (int j = 1; j < n; j++) {
-                            liveOut.setUnion(blockData.get(block.suxAt(j)).liveIn);
+                            liveOut.or(blockData.get(block.suxAt(j)).liveIn);
                         }
                     } else {
-                        liveOut.clearAll();
+                        liveOut.clear();
                     }
 
-                    if (!blockData.get(block).liveOut.isSame(liveOut)) {
+                    if (!blockData.get(block).liveOut.equals(liveOut)) {
                         // A change occurred. Swap the old and new live out sets to avoid copying.
-                        BitMap temp = blockData.get(block).liveOut;
+                        BitSet temp = blockData.get(block).liveOut;
                         blockData.get(block).liveOut = liveOut;
                         liveOut = temp;
 
@@ -813,10 +812,11 @@
                 if (iterationCount == 0 || changeOccurredInBlock) {
                     // liveIn(block) is the union of liveGen(block) with (liveOut(block) & !liveKill(block))
                     // note: liveIn has to be computed only in first iteration or if liveOut has changed!
-                    BitMap liveIn = blockData.get(block).liveIn;
-                    liveIn.setFrom(blockData.get(block).liveOut);
-                    liveIn.setDifference(blockData.get(block).liveKill);
-                    liveIn.setUnion(blockData.get(block).liveGen);
+                    BitSet liveIn = blockData.get(block).liveIn;
+                    liveIn.clear();
+                    liveIn.or(blockData.get(block).liveOut);
+                    liveIn.andNot(blockData.get(block).liveKill);
+                    liveIn.or(blockData.get(block).liveGen);
                 }
 
                 if (GraalOptions.TraceLinearScanLevel >= 4) {
@@ -826,7 +826,7 @@
             iterationCount++;
 
             if (changeOccurred && iterationCount > 50) {
-                throw new CiBailout("too many iterations in computeGlobalLiveSets");
+                throw new BailoutException("too many iterations in computeGlobalLiveSets");
             }
         } while (changeOccurred);
 
@@ -836,8 +836,8 @@
 
         // check that the liveIn set of the first block is empty
         Block startBlock = ir.cfg.getStartBlock();
-        BitMap liveInArgs = new BitMap(blockData.get(startBlock).liveIn.size());
-        if (!blockData.get(startBlock).liveIn.isSame(liveInArgs)) {
+        BitSet liveInArgs = new BitSet(blockData.get(startBlock).liveIn.size());
+        if (!blockData.get(startBlock).liveIn.equals(liveInArgs)) {
             if (GraalOptions.DetailedAsserts) {
                 reportFailure(numBlocks);
             }
@@ -846,7 +846,7 @@
             TTY.println("startBlock-ID: " + startBlock.getId());
 
             // bailout of if this occurs in product mode.
-            throw new CiBailout("liveIn set of first block must be empty");
+            throw new GraalInternalError("liveIn set of first block must be empty");
         }
     }
 
@@ -859,7 +859,7 @@
         // print some additional information to simplify debugging
         for (int operandNum = 0; operandNum < blockData.get(ir.cfg.getStartBlock()).liveIn.size(); operandNum++) {
             if (blockData.get(ir.cfg.getStartBlock()).liveIn.get(operandNum)) {
-                CiValue operand = operandFor(operandNum);
+                Value operand = operandFor(operandNum);
                 TTY.println(" var %d; operand=%s; node=%s", operandNum, operand.toString(), gen.valueForOperand(operand));
 
                 for (int j = 0; j < numBlocks; j++) {
@@ -872,7 +872,7 @@
                             if (info != null) {
                                 info.forEachState(new ValueProcedure() {
                                     @Override
-                                    public CiValue doValue(CiValue liveStateOperand) {
+                                    public Value doValue(Value liveStateOperand) {
                                         TTY.println("   operand=" + liveStateOperand);
                                         return liveStateOperand;
                                     }
@@ -912,7 +912,7 @@
         TTY.println(blockData.get(block).liveOut.toString());
     }
 
-    void addUse(CiValue operand, int from, int to, RegisterPriority registerPriority, CiKind kind) {
+    void addUse(Value operand, int from, int to, RegisterPriority registerPriority, Kind kind) {
         if (!isProcessed(operand)) {
             return;
         }
@@ -925,7 +925,7 @@
             interval = createInterval(operand);
         }
 
-        if (kind != CiKind.Illegal) {
+        if (kind != Kind.Illegal) {
             interval.setKind(kind);
         }
 
@@ -935,7 +935,7 @@
         interval.addUsePos(to & ~1, registerPriority);
     }
 
-    void addTemp(CiValue operand, int tempPos, RegisterPriority registerPriority, CiKind kind) {
+    void addTemp(Value operand, int tempPos, RegisterPriority registerPriority, Kind kind) {
         if (!isProcessed(operand)) {
             return;
         }
@@ -947,7 +947,7 @@
             interval = createInterval(operand);
         }
 
-        if (kind != CiKind.Illegal) {
+        if (kind != Kind.Illegal) {
             interval.setKind(kind);
         }
 
@@ -955,11 +955,11 @@
         interval.addUsePos(tempPos, registerPriority);
     }
 
-    boolean isProcessed(CiValue operand) {
-        return !isRegister(operand) || attributes(asRegister(operand)).isAllocatable;
+    boolean isProcessed(Value operand) {
+        return !isRegister(operand) || attributes(asRegister(operand)).isAllocatable();
     }
 
-    void addDef(CiValue operand, int defPos, RegisterPriority registerPriority, CiKind kind) {
+    void addDef(Value operand, int defPos, RegisterPriority registerPriority, Kind kind) {
         if (!isProcessed(operand)) {
             return;
         }
@@ -969,7 +969,7 @@
         Interval interval = intervalFor(operand);
         if (interval != null) {
 
-            if (kind != CiKind.Illegal) {
+            if (kind != Kind.Illegal) {
                 interval.setKind(kind);
             }
 
@@ -994,7 +994,7 @@
             // Dead value - make vacuous interval
             // also add register priority for dead intervals
             interval = createInterval(operand);
-            if (kind != CiKind.Illegal) {
+            if (kind != Kind.Illegal) {
                 interval.setKind(kind);
             }
 
@@ -1019,7 +1019,7 @@
     static RegisterPriority registerPriorityOfOutputOperand(LIRInstruction op) {
         if (op instanceof MoveOp) {
             MoveOp move = (MoveOp) op;
-            if (isStackSlot(move.getInput()) && move.getInput().kind != CiKind.Object) {
+            if (isStackSlot(move.getInput()) && move.getInput().kind != Kind.Object) {
                 // method argument (condition must be equal to handleMethodArguments)
                 return RegisterPriority.None;
             }
@@ -1049,8 +1049,8 @@
     void handleMethodArguments(LIRInstruction op) {
         if (op instanceof MoveOp) {
             MoveOp move = (MoveOp) op;
-            if (isStackSlot(move.getInput()) && move.getInput().kind != CiKind.Object) {
-                CiStackSlot slot = (CiStackSlot) move.getInput();
+            if (isStackSlot(move.getInput()) && move.getInput().kind != Kind.Object) {
+                StackSlot slot = (StackSlot) move.getInput();
                 if (GraalOptions.DetailedAsserts) {
                     assert op.id() > 0 : "invalid id";
                     assert blockForId(op.id()).numberOfPreds() == 0 : "move from stack must be in first block";
@@ -1068,12 +1068,12 @@
         }
     }
 
-    void addRegisterHint(final LIRInstruction op, final CiValue targetValue, OperandMode mode, EnumSet<OperandFlag> flags) {
+    void addRegisterHint(final LIRInstruction op, final Value targetValue, OperandMode mode, EnumSet<OperandFlag> flags) {
         if (flags.contains(OperandFlag.RegisterHint) && isVariableOrRegister(targetValue)) {
 
             op.forEachRegisterHint(targetValue, mode, new ValueProcedure() {
                 @Override
-                protected CiValue doValue(CiValue registerHint) {
+                protected Value doValue(Value registerHint) {
                     if (isVariableOrRegister(registerHint)) {
                         Interval from = intervalFor(registerHint);
                         Interval to = intervalFor(targetValue);
@@ -1096,7 +1096,7 @@
         intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY];
 
         // create a list with all caller-save registers (cpu, fpu, xmm)
-        CiRegister[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters();
+        Register[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters();
 
         // iterate all blocks in reverse order
         for (int i = blockCount() - 1; i >= 0; i--) {
@@ -1109,15 +1109,15 @@
             assert blockTo == instructions.get(instructions.size() - 1).id();
 
             // Update intervals for operands live at the end of this block;
-            BitMap live = blockData.get(block).liveOut;
+            BitSet live = blockData.get(block).liveOut;
             for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) {
                 assert live.get(operandNum) : "should not stop here otherwise";
-                CiValue operand = operandFor(operandNum);
+                Value operand = operandFor(operandNum);
                 if (GraalOptions.TraceLinearScanLevel >= 2) {
                     TTY.println("live in %s to %d", operand, blockTo + 2);
                 }
 
-                addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, CiKind.Illegal);
+                addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, Kind.Illegal);
 
                 // add special use positions for loop-end blocks when the
                 // interval is used anywhere inside this loop. It's possible
@@ -1138,9 +1138,9 @@
 
                 // add a temp range for each register if operation destroys caller-save registers
                 if (op.hasCall()) {
-                    for (CiRegister r : callerSaveRegs) {
-                        if (attributes(r).isAllocatable) {
-                            addTemp(r.asValue(), opId, RegisterPriority.None, CiKind.Illegal);
+                    for (Register r : callerSaveRegs) {
+                        if (attributes(r).isAllocatable()) {
+                            addTemp(r.asValue(), opId, RegisterPriority.None, Kind.Illegal);
                         }
                     }
                     if (GraalOptions.TraceLinearScanLevel >= 4) {
@@ -1150,7 +1150,7 @@
 
                 op.forEachOutput(new ValueProcedure() {
                     @Override
-                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
                         if (isVariableOrRegister(operand)) {
                             addDef(operand, opId, registerPriorityOfOutputOperand(op), operand.kind.stackKind());
                             addRegisterHint(op, operand, mode, flags);
@@ -1160,7 +1160,7 @@
                 });
                 op.forEachTemp(new ValueProcedure() {
                     @Override
-                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
                         if (isVariableOrRegister(operand)) {
                             addTemp(operand, opId, RegisterPriority.MustHaveRegister, operand.kind.stackKind());
                             addRegisterHint(op, operand, mode, flags);
@@ -1170,7 +1170,7 @@
                 });
                 op.forEachAlive(new ValueProcedure() {
                     @Override
-                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
                         if (isVariableOrRegister(operand)) {
                             RegisterPriority p = registerPriorityOfInputOperand(flags);
                             addUse(operand, blockFrom, opId + 1, p, operand.kind.stackKind());
@@ -1181,7 +1181,7 @@
                 });
                 op.forEachInput(new ValueProcedure() {
                     @Override
-                    public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
                         if (isVariableOrRegister(operand)) {
                             RegisterPriority p = registerPriorityOfInputOperand(flags);
                             addUse(operand, blockFrom, opId, p, operand.kind.stackKind());
@@ -1197,7 +1197,7 @@
                 // to a call site, the value would be in a register at the call otherwise)
                 op.forEachState(new ValueProcedure() {
                     @Override
-                    public CiValue doValue(CiValue operand) {
+                    public Value doValue(Value operand) {
                         addUse(operand, blockFrom, opId + 1, RegisterPriority.None, operand.kind.stackKind());
                         return operand;
                     }
@@ -1395,24 +1395,24 @@
             return result;
         }
 
-        throw new CiBailout("LinearScan: interval is null");
+        throw new BailoutException("LinearScan: interval is null");
     }
 
-    Interval intervalAtBlockBegin(Block block, CiValue operand) {
+    Interval intervalAtBlockBegin(Block block, Value operand) {
         assert isVariable(operand) : "register number out of bounds";
         assert intervalFor(operand) != null : "no interval found";
 
         return splitChildAtOpId(intervalFor(operand), block.getFirstLirInstructionId(), LIRInstruction.OperandMode.Output);
     }
 
-    Interval intervalAtBlockEnd(Block block, CiValue operand) {
+    Interval intervalAtBlockEnd(Block block, Value operand) {
         assert isVariable(operand) : "register number out of bounds";
         assert intervalFor(operand) != null : "no interval found";
 
         return splitChildAtOpId(intervalFor(operand), block.getLastLirInstructionId() + 1, LIRInstruction.OperandMode.Output);
     }
 
-    Interval intervalAtOpId(CiValue operand, int opId) {
+    Interval intervalAtOpId(Value operand, int opId) {
         assert isVariable(operand) : "register number out of bounds";
         assert intervalFor(operand) != null : "no interval found";
 
@@ -1423,14 +1423,14 @@
         assert moveResolver.checkEmpty();
 
         int numOperands = operandSize();
-        BitMap liveAtEdge = blockData.get(toBlock).liveIn;
+        BitSet liveAtEdge = blockData.get(toBlock).liveIn;
 
         // visit all variables for which the liveAtEdge bit is set
         for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
             assert operandNum < numOperands : "live information set for not exisiting interval";
             assert blockData.get(fromBlock).liveOut.get(operandNum) && blockData.get(toBlock).liveIn.get(operandNum) : "interval not live at this edge";
 
-            CiValue liveOperand = operandFor(operandNum);
+            Value liveOperand = operandFor(operandNum);
             Interval fromInterval = intervalAtBlockEnd(fromBlock, liveOperand);
             Interval toInterval = intervalAtBlockBegin(toBlock, liveOperand);
 
@@ -1484,8 +1484,8 @@
     void resolveDataFlow() {
         int numBlocks = blockCount();
         MoveResolver moveResolver = new MoveResolver(this);
-        BitMap blockCompleted = new BitMap(numBlocks);
-        BitMap alreadyResolved = new BitMap(numBlocks);
+        BitSet blockCompleted = new BitSet(numBlocks);
+        BitSet alreadyResolved = new BitSet(numBlocks);
 
         int i;
         for (i = 0; i < numBlocks; i++) {
@@ -1523,7 +1523,8 @@
         for (i = 0; i < numBlocks; i++) {
             if (!blockCompleted.get(i)) {
                 Block fromBlock = blockAt(i);
-                alreadyResolved.setFrom(blockCompleted);
+                alreadyResolved.clear();
+                alreadyResolved.or(blockCompleted);
 
                 int numSux = fromBlock.numberOfSux();
                 for (int s = 0; s < numSux; s++) {
@@ -1551,13 +1552,13 @@
     // * Phase 7: assign register numbers back to LIR
     // (includes computation of debug information and oop maps)
 
-    boolean verifyAssignedLocation(Interval interval, CiValue location) {
-        CiKind kind = interval.kind();
+    boolean verifyAssignedLocation(Interval interval, Value location) {
+        Kind kind = interval.kind();
 
         assert isRegister(location) || isStackSlot(location);
 
         if (isRegister(location)) {
-            CiRegister reg = asRegister(location);
+            Register reg = asRegister(location);
 
             // register
             switch (kind) {
@@ -1594,7 +1595,7 @@
         return true;
     }
 
-    static CiStackSlot canonicalSpillOpr(Interval interval) {
+    static StackSlot canonicalSpillOpr(Interval interval) {
         assert interval.spillSlot() != null : "canonical spill slot not set";
         return interval.spillSlot();
     }
@@ -1607,7 +1608,7 @@
      * @param mode the usage mode for {@code operand} by the instruction
      * @return the location assigned for the operand
      */
-    private CiValue colorLirOperand(Variable operand, int opId, OperandMode mode) {
+    private Value colorLirOperand(Variable operand, int opId, OperandMode mode) {
         Interval interval = intervalFor(operand);
         assert interval != null : "interval must exist";
 
@@ -1645,13 +1646,13 @@
         // intervals that have no oops inside need not to be processed.
         // to ensure a walking until the last instruction id, add a dummy interval
         // with a high operation id
-        nonOopIntervals = new Interval(CiValue.IllegalValue, -1);
+        nonOopIntervals = new Interval(Value.IllegalValue, -1);
         nonOopIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
 
         return new IntervalWalker(this, oopIntervals, nonOopIntervals);
     }
 
-    void computeOopMap(IntervalWalker iw, LIRInstruction op, CiBitMap registerRefMap, CiBitMap frameRefMap) {
+    void computeOopMap(IntervalWalker iw, LIRInstruction op, BitSet registerRefMap, BitSet frameRefMap) {
         if (GraalOptions.TraceLinearScanLevel >= 3) {
             TTY.println("creating oop map at opId %d", op.id());
         }
@@ -1663,7 +1664,7 @@
 
         // Iterate through active intervals
         for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) {
-            CiValue operand = interval.operand;
+            Value operand = interval.operand;
 
             assert interval.currentFrom() <= op.id() && op.id() <= interval.currentTo() : "interval should not be active otherwise";
             assert isVariable(interval.operand) : "fixed interval found";
@@ -1692,8 +1693,8 @@
         }
     }
 
-    private boolean isCallerSave(CiValue operand) {
-        return attributes(asRegister(operand)).isCallerSave;
+    private boolean isCallerSave(Value operand) {
+        return attributes(asRegister(operand)).isCallerSave();
     }
 
 
@@ -1711,13 +1712,13 @@
 
 
     private void computeDebugInfo(IntervalWalker iw, final LIRInstruction op, LIRDebugInfo info) {
-        CiBitMap registerRefMap = op.hasCall() ? null : frameMap.initRegisterRefMap();
-        CiBitMap frameRefMap = frameMap.initFrameRefMap();
+        BitSet registerRefMap = op.hasCall() ? null : frameMap.initRegisterRefMap();
+        BitSet frameRefMap = frameMap.initFrameRefMap();
         computeOopMap(iw, op, registerRefMap, frameRefMap);
 
         info.forEachState(new ValueProcedure() {
             @Override
-            public CiValue doValue(CiValue operand) {
+            public Value doValue(Value operand) {
                 int tempOpId = op.id();
                 OperandMode mode = OperandMode.Input;
                 Block block = blockForId(tempOpId);
@@ -1739,7 +1740,7 @@
                 // Get current location of operand
                 // The operand must be live because debug information is considered when building the intervals
                 // if the interval is not live, colorLirOperand will cause an assert on failure
-                CiValue result = colorLirOperand((Variable) operand, tempOpId, mode);
+                Value result = colorLirOperand((Variable) operand, tempOpId, mode);
                 assert !hasCall(tempOpId) || isStackSlot(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls";
                 return result;
             }
@@ -1761,7 +1762,7 @@
 
             ValueProcedure assignProc = new ValueProcedure() {
                 @Override
-                public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
                     if (isVariable(operand)) {
                         return colorLirOperand((Variable) operand, op.id(), mode);
                     }
@@ -1954,7 +1955,7 @@
                 throw new GraalInternalError("");
             }
 
-            if (isVariable(i1.operand) && i1.kind()  == CiKind.Illegal) {
+            if (isVariable(i1.operand) && i1.kind()  == Kind.Illegal) {
                 TTY.println("Interval %d has no type assigned", i1.operandNumber);
                 TTY.println(i1.logString(this));
                 throw new GraalInternalError("");
@@ -2000,15 +2001,15 @@
                 if (i2.from() == 1 && i2.to() == 2) {
                     continue;
                 }
-                CiValue l1 = i1.location();
-                CiValue l2 = i2.location();
+                Value l1 = i1.location();
+                Value l2 = i2.location();
                 if (i1.intersects(i2) && (l1.equals(l2))) {
                     if (GraalOptions.DetailedAsserts) {
                         TTY.println("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber);
                         TTY.println(i1.logString(this));
                         TTY.println(i2.logString(this));
                     }
-                    throw new CiBailout("");
+                    throw new BailoutException("");
                 }
             }
         }
@@ -2019,7 +2020,7 @@
         Interval curInterval;
 
         @Override
-        protected CiValue doValue(CiValue operand) {
+        protected Value doValue(Value operand) {
             if (isRegister(operand)) {
                 if (intervalFor(operand) == curInterval) {
                     ok = true;
@@ -2037,7 +2038,7 @@
         fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first;
         // to ensure a walking until the last instruction id, add a dummy interval
         // with a high operation id
-        otherIntervals = new Interval(CiValue.IllegalValue, -1);
+        otherIntervals = new Interval(Value.IllegalValue, -1);
         otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
         IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals);
 
@@ -2083,14 +2084,14 @@
 
         for (int i = 0; i < numBlocks; i++) {
             Block block = blockAt(i);
-            BitMap liveAtEdge = blockData.get(block).liveIn;
+            BitSet liveAtEdge = blockData.get(block).liveIn;
 
             // visit all operands where the liveAtEdge bit is set
             for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
                 if (GraalOptions.TraceLinearScanLevel >= 4) {
                     TTY.println("checking interval %d of block B%d", operandNum, block.getId());
                 }
-                CiValue operand = operandFor(operandNum);
+                Value operand = operandFor(operandNum);
                 assert isVariable(operand) : "value must have variable operand";
                 // TKR assert value.asConstant() == null || value.isPinned() :
                 // "only pinned constants can be alive accross block boundaries";
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,15 @@
  */
 package com.oracle.graal.compiler.alloc;
 
-import static com.oracle.max.cri.ci.CiUtil.*;
 import static com.oracle.graal.alloc.util.LocationUtil.*;
+import static com.oracle.graal.api.code.CodeUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
 import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.alloc.Interval.RegisterBinding;
 import com.oracle.graal.compiler.alloc.Interval.RegisterPriority;
@@ -46,7 +47,7 @@
 
     private final boolean hasCalleeSavedRegisters;
 
-    private CiRegister[] availableRegs;
+    private Register[] availableRegs;
 
     private final int[] usePos;
     private final int[] blockPos;
@@ -82,7 +83,7 @@
     }
 
     void initUseLists(boolean onlyProcessUsePos) {
-        for (CiRegister register : availableRegs) {
+        for (Register register : availableRegs) {
             int i = register.number;
             usePos[i] = Integer.MAX_VALUE;
 
@@ -94,7 +95,7 @@
     }
 
     void excludeFromUse(Interval i) {
-        CiValue location = i.location();
+        Value location = i.location();
         int i1 = asRegister(location).number;
         if (i1 >= availableRegs[0].number && i1 <= availableRegs[availableRegs.length - 1].number) {
             usePos[i1] = 0;
@@ -606,13 +607,13 @@
         // only intervals overlapping with cur are processed, non-overlapping invervals can be ignored safely
         if (GraalOptions.TraceLinearScanLevel >= 4) {
             TTY.println("      state of registers:");
-            for (CiRegister register : availableRegs) {
+            for (Register register : availableRegs) {
                 int i = register.number;
                 TTY.println("      reg %d: usePos: %d", register.number, usePos[i]);
             }
         }
 
-        CiRegister hint = null;
+        Register hint = null;
         Interval locationHint = interval.locationHint(true);
         if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) {
             hint = asRegister(locationHint.location());
@@ -629,12 +630,12 @@
         boolean needSplit = false;
         int splitPos = -1;
 
-        CiRegister reg = null;
-        CiRegister minFullReg = null;
-        CiRegister maxPartialReg = null;
+        Register reg = null;
+        Register minFullReg = null;
+        Register maxPartialReg = null;
 
         for (int i = 0; i < availableRegs.length; ++i) {
-            CiRegister availableReg = availableRegs[i];
+            Register availableReg = availableRegs[i];
             int number = availableReg.number;
             if (usePos[number] >= intervalTo) {
                 // this register is free for the full interval
@@ -674,11 +675,11 @@
         return true;
     }
 
-    CiRegister findLockedRegister(int regNeededUntil, int intervalTo, CiValue ignoreReg, boolean[] needSplit) {
+    Register findLockedRegister(int regNeededUntil, int intervalTo, Value ignoreReg, boolean[] needSplit) {
         int maxReg = -1;
-        CiRegister ignore = isRegister(ignoreReg) ? asRegister(ignoreReg) : null;
+        Register ignore = isRegister(ignoreReg) ? asRegister(ignoreReg) : null;
 
-        for (CiRegister reg : availableRegs) {
+        for (Register reg : availableRegs) {
             int i = reg.number;
             if (reg == ignore) {
                 // this register must be ignored
@@ -700,7 +701,7 @@
         return null;
     }
 
-    void splitAndSpillIntersectingIntervals(CiRegister reg) {
+    void splitAndSpillIntersectingIntervals(Register reg) {
         assert reg != null : "no register assigned";
 
         for (int i = 0; i < spillIntervals[reg.number].size(); i++) {
@@ -727,7 +728,7 @@
 
         if (GraalOptions.TraceLinearScanLevel >= 4) {
             TTY.println("      state of registers:");
-            for (CiRegister reg : availableRegs) {
+            for (Register reg : availableRegs) {
                 int i = reg.number;
                 TTY.print("      reg %d: usePos: %d, blockPos: %d, intervals: ", i, usePos[i], blockPos[i]);
                 for (int j = 0; j < spillIntervals[i].size(); j++) {
@@ -743,9 +744,9 @@
         int intervalTo = interval.to();
         assert regNeededUntil > 0 && regNeededUntil < Integer.MAX_VALUE : "interval has no use";
 
-        CiRegister reg = null;
-        CiRegister ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null;
-        for (CiRegister availableReg : availableRegs) {
+        Register reg = null;
+        Register ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null;
+        for (Register availableReg : availableRegs) {
             int number = availableReg.number;
             if (availableReg == ignore) {
                 // this register must be ignored
@@ -766,7 +767,7 @@
                 assert false : "cannot spill interval that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage + ", interval.from()=" + interval.from();
                 // assign a reasonable register and do a bailout in product mode to avoid errors
                 allocator.assignSpillSlot(interval);
-                throw new CiBailout("LinearScan: no register found");
+                throw new BailoutException("LinearScan: no register found");
             }
 
             splitAndSpillInterval(interval);
@@ -821,7 +822,7 @@
     }
 
     void initVarsForAlloc(Interval interval) {
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = allocator.frameMap.registerConfig.getCategorizedAllocatableRegisters();
+        EnumMap<RegisterFlag, Register[]> categorizedRegs = allocator.frameMap.registerConfig.getCategorizedAllocatableRegisters();
         availableRegs = categorizedRegs.get(asVariable(interval.operand).flag);
     }
 
@@ -905,7 +906,7 @@
             TTY.println("      splitParent: %s, insertMoveWhenActivated: %b", interval.splitParent().operandNumber, interval.insertMoveWhenActivated());
         }
 
-        final CiValue operand = interval.operand;
+        final Value operand = interval.operand;
         if (interval.location() != null && isStackSlot(interval.location())) {
             // activating an interval that has a stack slot assigned . split it at first use position
             // used for method parameters
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.compiler.alloc;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.lir.*;
 
@@ -41,7 +42,7 @@
     private LIRInsertionBuffer insertionBuffer; // buffer where moves are inserted
 
     private final List<Interval> mappingFrom;
-    private final List<CiValue> mappingFromOpr;
+    private final List<Value> mappingFromOpr;
     private final List<Interval> mappingTo;
     private boolean multipleReadsAllowed;
     private final int[] registerBlocked;
@@ -106,7 +107,7 @@
             }
         }
 
-        HashSet<CiValue> usedRegs = new HashSet<>();
+        HashSet<Value> usedRegs = new HashSet<>();
         if (!multipleReadsAllowed) {
             for (i = 0; i < mappingFrom.size(); i++) {
                 Interval interval = mappingFrom.get(i);
@@ -141,7 +142,7 @@
 
     // mark assignedReg and assignedRegHi of the interval as blocked
     private void blockRegisters(Interval interval) {
-        CiValue location = interval.location();
+        Value location = interval.location();
         if (isRegister(location)) {
             int reg = asRegister(location).number;
             assert multipleReadsAllowed || registerBlocked(reg) == 0 : "register already marked as used";
@@ -151,7 +152,7 @@
 
     // mark assignedReg and assignedRegHi of the interval as unblocked
     private void unblockRegisters(Interval interval) {
-        CiValue location = interval.location();
+        Value location = interval.location();
         if (isRegister(location)) {
             int reg = asRegister(location).number;
             assert registerBlocked(reg) > 0 : "register already marked as unused";
@@ -164,9 +165,9 @@
      * or is only blocked by {@code from}.
      */
     private boolean safeToProcessMove(Interval from, Interval to) {
-        CiValue fromReg = from != null ? from.location() : null;
+        Value fromReg = from != null ? from.location() : null;
 
-        CiValue reg = to.location();
+        Value reg = to.location();
         if (isRegister(reg)) {
             if (registerBlocked(asRegister(reg).number) > 1 || (registerBlocked(asRegister(reg).number) == 1 && reg != fromReg)) {
                 return false;
@@ -195,8 +196,8 @@
         assert fromInterval.kind() == toInterval.kind() : "move between different types";
         assert insertIdx != -1 : "must setup insert position first";
 
-        CiValue fromOpr = fromInterval.operand;
-        CiValue toOpr = toInterval.operand;
+        Value fromOpr = fromInterval.operand;
+        Value toOpr = toInterval.operand;
 
         insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
@@ -205,11 +206,11 @@
         }
     }
 
-    private void insertMove(CiValue fromOpr, Interval toInterval) {
+    private void insertMove(Value fromOpr, Interval toInterval) {
         assert fromOpr.kind == toInterval.kind() : "move between different types";
         assert insertIdx != -1 : "must setup insert position first";
 
-        CiValue toOpr = toInterval.operand;
+        Value toOpr = toInterval.operand;
         insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
         if (GraalOptions.TraceLinearScanLevel >= 4) {
@@ -276,7 +277,7 @@
                 // do not allocate a new spill slot for temporary interval, but
                 // use spill slot assigned to fromInterval. Otherwise moves from
                 // one stack slot to another can happen (not allowed by LIRAssembler
-                CiStackSlot spillSlot = fromInterval.spillSlot();
+                StackSlot spillSlot = fromInterval.spillSlot();
                 if (spillSlot == null) {
                     spillSlot = allocator.frameMap.allocateSpillSlot(spillInterval.kind());
                     fromInterval.setSpillSlot(spillSlot);
@@ -332,11 +333,11 @@
         assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval;
         assert fromInterval.kind() == toInterval.kind();
         mappingFrom.add(fromInterval);
-        mappingFromOpr.add(CiValue.IllegalValue);
+        mappingFromOpr.add(Value.IllegalValue);
         mappingTo.add(toInterval);
     }
 
-    void addMapping(CiValue fromOpr, Interval toInterval) {
+    void addMapping(Value fromOpr, Interval toInterval) {
         if (GraalOptions.TraceLinearScanLevel >= 4) {
             TTY.println("MoveResolver: adding mapping from %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.compiler.alloc;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.util.*;
 import com.oracle.graal.graph.*;
@@ -44,7 +45,7 @@
     ArrayMap<Interval[]> savedStates; // saved information of previous check
 
     // simplified access to methods of LinearScan
-    Interval intervalAt(CiValue operand) {
+    Interval intervalAt(Value operand) {
         return allocator.intervalFor(operand);
     }
 
@@ -177,9 +178,9 @@
         return inputState.clone();
     }
 
-    static void statePut(Interval[] inputState, CiValue location, Interval interval) {
+    static void statePut(Interval[] inputState, Value location, Interval interval) {
         if (location != null && isRegister(location)) {
-            CiRegister reg = asRegister(location);
+            Register reg = asRegister(location);
             int regNum = reg.number;
             if (interval != null) {
                 if (GraalOptions.TraceLinearScanLevel >= 4) {
@@ -195,7 +196,7 @@
         }
     }
 
-    static boolean checkState(Interval[] inputState, CiValue reg, Interval interval) {
+    static boolean checkState(Interval[] inputState, Value reg, Interval interval) {
         if (reg != null && isRegister(reg)) {
             if (inputState[asRegister(reg).number] != interval) {
                 throw new GraalInternalError("!! Error in register allocation: register %s does not contain interval %s but interval %s", reg, interval.operand, inputState[asRegister(reg).number]);
@@ -215,7 +216,7 @@
 
             ValueProcedure useProc = new ValueProcedure() {
                 @Override
-                public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
                     if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) {
                         Interval interval = intervalAt(operand);
                         if (op.id() != -1) {
@@ -230,7 +231,7 @@
 
             ValueProcedure defProc = new ValueProcedure() {
                 @Override
-                public CiValue doValue(CiValue operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
                     if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) {
                         Interval interval = intervalAt(operand);
                         if (op.id() != -1) {
@@ -247,7 +248,7 @@
             op.forEachInput(useProc);
             // invalidate all caller save registers at calls
             if (op.hasCall()) {
-                for (CiRegister r : allocator.frameMap.registerConfig.getCallerSaveRegisters()) {
+                for (Register r : allocator.frameMap.registerConfig.getCallerSaveRegisters()) {
                     statePut(inputState, r.asValue(), null);
                 }
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/debug/package-info.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.
- */
-/**
- * A collection of debugging aids for Graal development.
- */
-package com.oracle.graal.compiler.debug;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,46 +25,39 @@
 import java.util.*;
 import java.util.Map.Entry;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.LIRGenerator.LockScope;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.virtual.*;
 
 public class DebugInfoBuilder {
-    private final NodeMap<CiValue> nodeOperands;
+    private final NodeMap<Value> nodeOperands;
 
-    public DebugInfoBuilder(NodeMap<CiValue> nodeOperands) {
+    public DebugInfoBuilder(NodeMap<Value> nodeOperands) {
         this.nodeOperands = nodeOperands;
     }
 
 
-    private HashMap<VirtualObjectNode, CiVirtualObject> virtualObjects = new HashMap<>();
+    private HashMap<VirtualObjectNode, VirtualObject> virtualObjects = new HashMap<>();
 
-    public LIRDebugInfo build(FrameState topState, LockScope locks, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) {
+    public LIRDebugInfo build(FrameState topState, LockScope locks, List<StackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) {
         assert virtualObjects.size() == 0;
-        CiFrame frame = computeFrameForState(topState, locks, leafGraphId);
+        BytecodeFrame frame = computeFrameForState(topState, locks, leafGraphId);
 
-        CiVirtualObject[] virtualObjectsArray = null;
+        VirtualObject[] virtualObjectsArray = null;
         if (virtualObjects.size() != 0) {
             // collect all VirtualObjectField instances:
-            IdentityHashMap<VirtualObjectNode, VirtualObjectFieldNode> objectStates = new IdentityHashMap<>();
+            IdentityHashMap<VirtualObjectNode, VirtualObjectState> objectStates = new IdentityHashMap<>();
             FrameState current = topState;
             do {
-                for (Node n : current.virtualObjectMappings()) {
-                    Node p = n;
-                    while (p instanceof PhiNode) {
-                        PhiNode phi = (PhiNode) p;
-                        assert phi.type() == PhiType.Virtual;
-                        p = phi.valueAt(0);
-                    }
-                    VirtualObjectFieldNode field = (VirtualObjectFieldNode) p;
+                for (VirtualObjectState state : current.virtualObjectMappings()) {
                     // null states occur for objects with 0 fields
-                    if (field != null && !objectStates.containsKey(field.object())) {
-                        objectStates.put(field.object(), field);
+                    if (!objectStates.containsKey(state.object())) {
+                        objectStates.put(state.object(), state);
                     }
                 }
                 current = current.outerFrameState();
@@ -74,51 +67,42 @@
             boolean changed;
             do {
                 changed = false;
-                IdentityHashMap<VirtualObjectNode, CiVirtualObject> virtualObjectsCopy = new IdentityHashMap<>(virtualObjects);
-                for (Entry<VirtualObjectNode, CiVirtualObject> entry : virtualObjectsCopy.entrySet()) {
+                IdentityHashMap<VirtualObjectNode, VirtualObject> virtualObjectsCopy = new IdentityHashMap<>(virtualObjects);
+                for (Entry<VirtualObjectNode, VirtualObject> entry : virtualObjectsCopy.entrySet()) {
                     if (entry.getValue().values() == null) {
                         VirtualObjectNode vobj = entry.getKey();
                         if (vobj instanceof BoxedVirtualObjectNode) {
                             BoxedVirtualObjectNode boxedVirtualObjectNode = (BoxedVirtualObjectNode) vobj;
-                            entry.getValue().setValues(new CiValue[]{toCiValue(boxedVirtualObjectNode.getUnboxedValue())});
+                            entry.getValue().setValues(new Value[]{toCiValue(boxedVirtualObjectNode.getUnboxedValue())});
                         } else {
-                            CiValue[] values = new CiValue[vobj.fieldsCount()];
+                            Value[] values = new Value[vobj.fieldsCount()];
                             entry.getValue().setValues(values);
                             if (values.length > 0) {
                                 changed = true;
-                                ValueNode currentField = objectStates.get(vobj);
+                                VirtualObjectState currentField = objectStates.get(vobj);
                                 assert currentField != null;
-                                do {
-                                    if (currentField instanceof VirtualObjectFieldNode) {
-                                        int index = ((VirtualObjectFieldNode) currentField).index();
-                                        if (values[index] == null) {
-                                            values[index] = toCiValue(((VirtualObjectFieldNode) currentField).input());
-                                        }
-                                        currentField = ((VirtualObjectFieldNode) currentField).lastState();
-                                    } else {
-                                        assert currentField instanceof PhiNode : currentField;
-                                        currentField = ((PhiNode) currentField).valueAt(0);
-                                    }
-                                } while (currentField != null);
+                                for (int i = 0; i < vobj.fieldsCount(); i++) {
+                                    values[i] = toCiValue(currentField.fieldValues().get(i));
+                                }
                             }
                         }
                     }
                 }
             } while (changed);
 
-            virtualObjectsArray = virtualObjects.values().toArray(new CiVirtualObject[virtualObjects.size()]);
+            virtualObjectsArray = virtualObjects.values().toArray(new VirtualObject[virtualObjects.size()]);
             virtualObjects.clear();
         }
 
         return new LIRDebugInfo(frame, virtualObjectsArray, pointerSlots, exceptionEdge);
     }
 
-    private CiFrame computeFrameForState(FrameState state, LockScope locks, long leafGraphId) {
+    private BytecodeFrame computeFrameForState(FrameState state, LockScope locks, long leafGraphId) {
         int numLocals = state.localsSize();
         int numStack = state.stackSize();
-        int numLocks = (locks != null && locks.callerState == state.outerFrameState()) ? locks.stateDepth + 1 : 0;
+        int numLocks = (locks != null && locks.inliningIdentifier == state.inliningIdentifier()) ? locks.stateDepth + 1 : 0;
 
-        CiValue[] values = new CiValue[numLocals + numStack + numLocks];
+        Value[] values = new Value[numLocals + numStack + numLocks];
         for (int i = 0; i < numLocals; i++) {
             values[i] = toCiValue(state.localAt(i));
         }
@@ -128,35 +112,35 @@
 
         LockScope nextLock = locks;
         for (int i = numLocks - 1; i >= 0; i--) {
-            assert locks != null && nextLock.callerState == state.outerFrameState() && nextLock.stateDepth == i;
+            assert locks != null && nextLock.inliningIdentifier == state.inliningIdentifier() && nextLock.stateDepth == i;
 
-            CiValue owner = toCiValue(nextLock.monitor.object());
-            CiValue lockData = nextLock.lockData;
+            Value owner = toCiValue(nextLock.monitor.object());
+            Value lockData = nextLock.lockData;
             boolean eliminated = nextLock.monitor.eliminated();
-            values[numLocals + numStack + nextLock.stateDepth] = new CiMonitorValue(owner, lockData, eliminated);
+            values[numLocals + numStack + nextLock.stateDepth] = new MonitorValue(owner, lockData, eliminated);
 
             nextLock = nextLock.outer;
         }
 
-        CiFrame caller = null;
+        BytecodeFrame caller = null;
         if (state.outerFrameState() != null) {
             caller = computeFrameForState(state.outerFrameState(), nextLock, -1);
         } else {
             if (nextLock != null) {
-                throw new CiBailout("unbalanced monitors: found monitor for unknown frame");
+                throw new BailoutException("unbalanced monitors: found monitor for unknown frame");
             }
         }
         assert state.bci >= 0 || state.bci == FrameState.BEFORE_BCI;
-        CiFrame frame = new CiFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, state.localsSize(), state.stackSize(), numLocks, leafGraphId);
+        BytecodeFrame frame = new BytecodeFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, state.localsSize(), state.stackSize(), numLocks, leafGraphId);
         return frame;
     }
 
-    private CiValue toCiValue(ValueNode value) {
+    private Value toCiValue(ValueNode value) {
         if (value instanceof VirtualObjectNode) {
             VirtualObjectNode obj = (VirtualObjectNode) value;
-            CiVirtualObject ciObj = virtualObjects.get(value);
+            VirtualObject ciObj = virtualObjects.get(value);
             if (ciObj == null) {
-                ciObj = CiVirtualObject.get(obj.type(), null, virtualObjects.size());
+                ciObj = VirtualObject.get(obj.type(), null, virtualObjects.size());
                 virtualObjects.put(obj, ciObj);
             }
             Debug.metric("StateVirtualObjects").increment();
@@ -168,14 +152,14 @@
 
         } else if (value != null) {
             Debug.metric("StateVariables").increment();
-            CiValue operand = nodeOperands.get(value);
-            assert operand != null && (operand instanceof Variable || operand instanceof CiConstant);
+            Value operand = nodeOperands.get(value);
+            assert operand != null && (operand instanceof Variable || operand instanceof Constant) : operand + " for " + value;
             return operand;
 
         } else {
             // return a dummy value because real value not needed
             Debug.metric("StateIllegals").increment();
-            return CiValue.IllegalValue;
+            return Value.IllegalValue;
         }
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/InstructionPrinter.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/InstructionPrinter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -124,7 +124,7 @@
              fillTo(USE.position + indentation, ' ').
              print("0").
              fillTo(VALUE.position + indentation, ' ').
-             print(ValueUtil.valueString(instruction)).
+             print(ValueNodeUtil.valueString(instruction)).
              fillTo(INSTRUCTION.position + indentation, ' ');
         printInstruction(instruction);
         if (instruction instanceof StateSplit) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,18 @@
  */
 package com.oracle.graal.compiler.gen;
 
-import static com.oracle.graal.lir.ValueUtil.*;
-import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
-import static com.oracle.max.cri.ci.CiValue.*;
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.api.meta.Value.*;
+import static com.oracle.graal.lir.LIRValueUtil.*;
 
 import java.util.*;
 import java.util.Map.Entry;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.util.*;
 import com.oracle.graal.debug.*;
@@ -41,17 +46,15 @@
 import com.oracle.graal.lir.StandardOp.PhiLabelOp;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.FrameState.InliningIdentifier;
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.Mark;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.Representation;
 import com.oracle.max.cri.xir.CiXirAssembler.XirConstant;
 import com.oracle.max.cri.xir.CiXirAssembler.XirInstruction;
 import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
@@ -67,11 +70,11 @@
  */
 public abstract class LIRGenerator extends LIRGeneratorTool {
     protected final Graph graph;
-    protected final RiRuntime runtime;
-    protected final CiTarget target;
-    protected final RiResolvedMethod method;
+    protected final CodeCacheProvider runtime;
+    protected final TargetDescription target;
+    protected final ResolvedJavaMethod method;
     protected final FrameMap frameMap;
-    public final NodeMap<CiValue> nodeOperands;
+    public final NodeMap<Value> nodeOperands;
 
     protected final LIR lir;
     protected final XirSupport xirSupport;
@@ -93,12 +96,10 @@
         public final LockScope outer;
 
         /**
-         * The frame state of the caller of the method performing the lock, or null if the outermost method
-         * performs the lock. This information is used to compute the {@link CiFrame} that this lock belongs to.
-         * We cannot use the actual frame state of the locking method, because it is not unique for a method. The
-         * caller frame states are unique, i.e., all frame states of inlined methods refer to the same caller frame state.
+         * The identifier of the actual inlined method instance performing the lock, or null if the outermost method
+         * performs the lock. This information is used to compute the {@link BytecodeFrame} that this lock belongs to.
          */
-        public final FrameState callerState;
+        public final InliningIdentifier inliningIdentifier;
 
         /**
          * The number of locks already found for this frame state.
@@ -113,14 +114,14 @@
         /**
          * Space in the stack frame needed by the VM to perform the locking.
          */
-        public final CiStackSlot lockData;
+        public final StackSlot lockData;
 
-        public LockScope(LockScope outer, FrameState callerState, MonitorEnterNode monitor, CiStackSlot lockData) {
+        public LockScope(LockScope outer, InliningIdentifier inliningIdentifier, MonitorEnterNode monitor, StackSlot lockData) {
             this.outer = outer;
-            this.callerState = callerState;
+            this.inliningIdentifier = inliningIdentifier;
             this.monitor = monitor;
             this.lockData = lockData;
-            if (outer != null && outer.callerState == callerState) {
+            if (outer != null && outer.inliningIdentifier == inliningIdentifier) {
                 this.stateDepth = outer.stateDepth + 1;
             } else {
                 this.stateDepth = 0;
@@ -141,7 +142,7 @@
     private LockScope curLocks;
 
 
-    public LIRGenerator(Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+    public LIRGenerator(Graph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir, RiXirGenerator xir, Assumptions assumptions) {
         this.graph = graph;
         this.runtime = runtime;
         this.target = target;
@@ -150,14 +151,14 @@
         this.nodeOperands = graph.createNodeMap();
         this.lir = lir;
         this.xir = xir;
-        this.xirSupport = new XirSupport();
+        this.xirSupport = new XirSupport(assumptions);
         this.debugInfoBuilder = new DebugInfoBuilder(nodeOperands);
         this.blockLocks = new BlockMap<>(lir.cfg);
         this.blockLastState = new BlockMap<>(lir.cfg);
     }
 
     @Override
-    public CiTarget target() {
+    public TargetDescription target() {
         return target;
     }
 
@@ -167,15 +168,15 @@
      * @param node A node that produces a result value.
      */
     @Override
-    public CiValue operand(ValueNode node) {
+    public Value operand(ValueNode node) {
         if (nodeOperands == null) {
             return null;
         }
         return nodeOperands.get(node);
     }
 
-    public ValueNode valueForOperand(CiValue value) {
-        for (Entry<Node, CiValue> entry : nodeOperands.entries()) {
+    public ValueNode valueForOperand(Value value) {
+        for (Entry<Node, Value> entry : nodeOperands.entries()) {
             if (entry.getValue() == value) {
                 return (ValueNode) entry.getKey();
             }
@@ -189,26 +190,32 @@
      * @return a new variable
      */
     @Override
-    public Variable newVariable(CiKind kind) {
-        CiKind stackKind = kind.stackKind();
+    public Variable newVariable(Kind kind) {
+        Kind stackKind = kind.stackKind();
         switch (stackKind) {
             case Jsr:
             case Int:
             case Long:
             case Object:
-                return new Variable(stackKind, lir.nextVariable(), CiRegister.RegisterFlag.CPU);
+                return new Variable(stackKind, lir.nextVariable(), Register.RegisterFlag.CPU);
             case Float:
             case Double:
-                return new Variable(stackKind, lir.nextVariable(), CiRegister.RegisterFlag.FPU);
+                return new Variable(stackKind, lir.nextVariable(), Register.RegisterFlag.FPU);
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     @Override
-    public CiValue setResult(ValueNode x, CiValue operand) {
-        assert (isVariable(operand) && x.kind() == operand.kind) || (isConstant(operand) && x.kind() == operand.kind.stackKind()) : operand.kind + " for node " + x;
+    public RegisterAttributes attributes(Register register) {
+        return frameMap.registerConfig.getAttributesMap()[register.number];
+    }
 
+    @Override
+    public Value setResult(ValueNode x, Value operand) {
+        assert (isVariable(operand) && x.kind() == operand.kind) ||
+               (isRegister(operand) && !attributes(asRegister(operand)).isAllocatable()) ||
+               (isConstant(operand) && x.kind() == operand.kind.stackKind()) : operand.kind + " for node " + x;
         assert operand(x) == null : "operand cannot be set twice";
         assert operand != null && isLegal(operand) : "operand must be legal";
         assert operand.kind.stackKind() == x.kind();
@@ -218,28 +225,28 @@
     }
 
     @Override
-    public abstract Variable emitMove(CiValue input);
+    public abstract Variable emitMove(Value input);
 
-    public Variable load(CiValue value) {
+    public Variable load(Value value) {
         if (!isVariable(value)) {
             return emitMove(value);
         }
         return (Variable) value;
     }
 
-    public CiValue loadNonConst(CiValue value) {
-        if (isConstant(value) && !canInlineConstant((CiConstant) value)) {
+    public Value loadNonConst(Value value) {
+        if (isConstant(value) && !canInlineConstant((Constant) value)) {
             return emitMove(value);
         }
         return value;
     }
 
-    public CiValue loadForStore(CiValue value, CiKind storeKind) {
-        if (isConstant(value) && canStoreConstant((CiConstant) value)) {
+    public Value loadForStore(Value value, Kind storeKind) {
+        if (isConstant(value) && canStoreConstant((Constant) value)) {
             return value;
         }
-        if (storeKind == CiKind.Byte || storeKind == CiKind.Boolean) {
-            Variable tempVar = new Variable(value.kind, lir.nextVariable(), CiRegister.RegisterFlag.Byte);
+        if (storeKind == Kind.Byte || storeKind == Kind.Boolean) {
+            Variable tempVar = new Variable(value.kind, lir.nextVariable(), Register.RegisterFlag.Byte);
             emitMove(value, tempVar);
             return tempVar;
         }
@@ -268,7 +275,7 @@
         return stateFor(state, null, null, leafGraphId);
     }
 
-    public LIRDebugInfo stateFor(FrameState state, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) {
+    public LIRDebugInfo stateFor(FrameState state, List<StackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) {
         return debugInfoBuilder.build(state, curLocks, pointerSlots, exceptionEdge, leafGraphId);
     }
 
@@ -278,8 +285,8 @@
      * @param kind the kind of value being returned
      * @return the operand representing the ABI defined location used return a value of kind {@code kind}
      */
-    public CiValue resultOperandFor(CiKind kind) {
-        if (kind == CiKind.Void) {
+    public Value resultOperandFor(Kind kind) {
+        if (kind == Kind.Void) {
             return IllegalValue;
         }
         return frameMap.registerConfig.getReturnRegister(kind).asValue(kind);
@@ -315,12 +322,12 @@
             MergeNode merge = (MergeNode) block.getBeginNode();
             for (PhiNode phi : merge.phis()) {
                 if (phi.type() == PhiType.Value) {
-                    CiValue phiValue = newVariable(phi.kind());
+                    Value phiValue = newVariable(phi.kind());
                     setResult(phi, phiValue);
                     phiValues.add(phiValue);
                 }
             }
-            append(new PhiLabelOp(new Label(), block.align, phiValues.toArray(new CiValue[phiValues.size()])));
+            append(new PhiLabelOp(new Label(), block.align, phiValues.toArray(new Value[phiValues.size()])));
             phiValues.clear();
         } else {
             append(new LabelOp(new Label(), block.align));
@@ -336,7 +343,7 @@
             if (curLocks == null) {
                 curLocks = predLocks;
             } else if (curLocks != predLocks && (!pred.isLoopEnd() || predLocks != null)) {
-                throw new CiBailout("unbalanced monitors: predecessor blocks have different monitor states");
+                throw new BailoutException("unbalanced monitors: predecessor blocks have different monitor states");
             }
         }
 
@@ -351,9 +358,20 @@
             for (Block pred : block.getPredecessors()) {
                 if (fs == null) {
                     fs = blockLastState.get(pred);
-                } else if (fs != blockLastState.get(pred)) {
-                    fs = null;
-                    break;
+                } else {
+                    if (blockLastState.get(pred) == null) {
+                        // Only a back edge can have a null state for its enclosing block.
+                        assert pred.getEndNode() instanceof LoopEndNode;
+
+                        if (block.getBeginNode().stateAfter() == null) {
+                            // We'll assert later that the begin and end of a framestate-less loop
+                            // share the frame state that flowed into the loop
+                            blockLastState.put(pred, fs);
+                        }
+                    } else if (fs != blockLastState.get(pred)) {
+                        fs = null;
+                        break;
+                    }
                 }
             }
             if (GraalOptions.TraceLIRGeneratorLevel >= 2) {
@@ -369,7 +387,7 @@
             lastState = fs;
         }
 
-        List<Node> nodes = lir.nodesFor(block);
+        List<ScheduledNode> nodes = lir.nodesFor(block);
         for (int i = 0; i < nodes.size(); i++) {
             Node instr = nodes.get(i);
 
@@ -381,11 +399,11 @@
 
                 if (instr instanceof GuardNode) {
                     GuardNode guardNode = (GuardNode) instr;
-                    if (guardNode.condition() instanceof NullCheckNode) {
-                        NullCheckNode nullCheckNode = (NullCheckNode) guardNode.condition();
-                        if (!nullCheckNode.expectedNull && nextInstr instanceof Access) {
+                    if (guardNode.condition() instanceof IsNullNode && guardNode.negated()) {
+                        IsNullNode isNullNode = (IsNullNode) guardNode.condition();
+                        if (nextInstr instanceof Access) {
                             Access access = (Access) nextInstr;
-                            if (nullCheckNode.object() == access.object() && canBeNullCheck(access.location())) {
+                            if (isNullNode.object() == access.object() && canBeNullCheck(access.location())) {
                                 //TTY.println("implicit null check");
                                 access.setNullCheck(true);
                                 continue;
@@ -404,6 +422,8 @@
             if (instr instanceof ValueNode) {
                 try {
                     doRoot((ValueNode) instr);
+                } catch (GraalInternalError e) {
+                    throw e.addContext(instr);
                 } catch (Throwable e) {
                     throw new GraalInternalError(e).addContext(instr);
                 }
@@ -430,6 +450,10 @@
             TTY.println("END Generating LIR for block B" + block.getId());
         }
 
+        // Check that the begin and end of a framestate-less loop
+        // share the frame state that flowed into the loop
+        assert blockLastState.get(block) == null || blockLastState.get(block) == lastState;
+
         blockLocks.put(currentBlock, curLocks);
         blockLastState.put(block, lastState);
         currentBlock = null;
@@ -484,14 +508,14 @@
         return !(location instanceof IndexedLocationNode) && location.displacement() < 4096;
     }
 
-    private void emitPrologue() {
-        CiCallingConvention incomingArguments = frameMap.registerConfig.getCallingConvention(JavaCallee, CiUtil.signatureToKinds(method), target, false);
+    protected void emitPrologue() {
+        CallingConvention incomingArguments = frameMap.registerConfig.getCallingConvention(JavaCallee, CodeUtil.signatureToKinds(method), target, false);
 
-        CiValue[] params = new CiValue[incomingArguments.locations.length];
+        Value[] params = new Value[incomingArguments.locations.length];
         for (int i = 0; i < params.length; i++) {
             params[i] = toStackKind(incomingArguments.locations[i]);
-            if (CiValueUtil.isStackSlot(params[i])) {
-                CiStackSlot slot = CiValueUtil.asStackSlot(params[i]);
+            if (ValueUtil.isStackSlot(params[i])) {
+                StackSlot slot = ValueUtil.asStackSlot(params[i]);
                 if (slot.inCallerFrame() && !lir.hasArgInCallerFrame()) {
                     lir.setHasArgInCallerFrame();
                 }
@@ -501,7 +525,7 @@
         append(new ParametersOp(params));
 
         for (LocalNode local : graph.getNodes(LocalNode.class)) {
-            CiValue param = params[local.index()];
+            Value param = params[local.index()];
             assert param.kind == local.kind().stackKind();
             setResult(local, emitMove(param));
         }
@@ -509,21 +533,19 @@
 
     @Override
     public void visitCheckCast(CheckCastNode x) {
-        if (x.emitCode()) {
-            XirSnippet snippet = xir.genCheckCast(site(x, x.object()), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact());
-            emitXir(snippet, x, state(), true);
-        }
+        XirSnippet snippet = xir.genCheckCast(site(x, x.object()), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.profile());
+        emitXir(snippet, x, state(), true);
         // The result of a checkcast is the unmodified object, so no need to allocate a new variable for it.
         setResult(x, operand(x.object()));
     }
 
     @Override
     public void visitMonitorEnter(MonitorEnterNode x) {
-        CiStackSlot lockData = frameMap.allocateStackBlock(runtime.sizeOfLockData(), false);
+        StackSlot lockData = frameMap.allocateStackBlock(runtime.sizeOfLockData(), false);
         if (x.eliminated()) {
             // No code is emitted for eliminated locks, but for proper debug information generation we need to
             // register the monitor and its lock data.
-            curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData);
+            curLocks = new LockScope(curLocks, x.stateAfter().inliningIdentifier(), x, lockData);
             return;
         }
 
@@ -532,7 +554,7 @@
 
         LIRDebugInfo stateBefore = state();
         // The state before the monitor enter is used for null checks, so it must not contain the newly locked object.
-        curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData);
+        curLocks = new LockScope(curLocks, x.stateAfter().inliningIdentifier(), x, lockData);
         // The state after the monitor enter is used for deoptimization, after the monitor has blocked, so it must contain the newly locked object.
         LIRDebugInfo stateAfter = stateFor(x.stateAfter(), -1);
 
@@ -543,14 +565,14 @@
     @Override
     public void visitMonitorExit(MonitorExitNode x) {
         if (curLocks == null || curLocks.monitor.object() != x.object() || curLocks.monitor.eliminated() != x.eliminated()) {
-            throw new CiBailout("unbalanced monitors: attempting to unlock an object that is not on top of the locking stack");
+            throw new BailoutException("unbalanced monitors: attempting to unlock an object that is not on top of the locking stack");
         }
         if (x.eliminated()) {
             curLocks = curLocks.outer;
             return;
         }
 
-        CiStackSlot lockData = curLocks.lockData;
+        StackSlot lockData = curLocks.lockData;
         XirArgument obj = toXirArgument(x.object());
         XirArgument lockAddress = lockData == null ? null : toXirArgument(emitLea(lockData));
 
@@ -570,14 +592,14 @@
     @Override
     public void visitNewTypeArray(NewTypeArrayNode x) {
         XirArgument length = toXirArgument(x.length());
-        XirSnippet snippet = xir.genNewArray(site(x), length, x.elementType().kind(true), null, null);
+        XirSnippet snippet = xir.genNewArray(site(x), length, x.elementType().kind(), null, null);
         emitXir(snippet, x, state(), true);
     }
 
     @Override
     public void visitNewObjectArray(NewObjectArrayNode x) {
         XirArgument length = toXirArgument(x.length());
-        XirSnippet snippet = xir.genNewArray(site(x), length, CiKind.Object, x.elementType(), x.exactType());
+        XirSnippet snippet = xir.genNewArray(site(x), length, Kind.Object, x.elementType(), x.elementType().arrayOf());
         emitXir(snippet, x, state(), true);
     }
 
@@ -593,7 +615,7 @@
 
     @Override
     public void visitReturn(ReturnNode x) {
-        CiValue operand = CiValue.IllegalValue;
+        Value operand = Value.IllegalValue;
         if (!x.kind().isVoid()) {
             operand = resultOperandFor(x.kind());
             emitMove(operand(x.result()), operand);
@@ -601,7 +623,7 @@
         emitReturn(operand);
     }
 
-    protected abstract void emitReturn(CiValue input);
+    protected abstract void emitReturn(Value input);
 
     @Override
     public void visitMerge(MergeNode x) {
@@ -619,7 +641,7 @@
     public void visitLoopEnd(LoopEndNode x) {
     }
 
-    private ArrayList<CiValue> phiValues = new ArrayList<>();
+    private ArrayList<Value> phiValues = new ArrayList<>();
 
     private void moveToPhi(MergeNode merge, EndNode pred) {
         if (GraalOptions.AllocSSA) {
@@ -629,7 +651,7 @@
                     phiValues.add(operand(phi.valueAt(pred)));
                 }
             }
-            append(new PhiJumpOp(getLIRBlock(merge), phiValues.toArray(new CiValue[phiValues.size()])));
+            append(new PhiJumpOp(getLIRBlock(merge), phiValues.toArray(new Value[phiValues.size()])));
             phiValues.clear();
             return;
         }
@@ -649,9 +671,9 @@
         append(new JumpOp(getLIRBlock(merge), null));
     }
 
-    private CiValue operandForPhi(PhiNode phi) {
+    private Value operandForPhi(PhiNode phi) {
         assert phi.type() == PhiType.Value : "wrong phi type: " + phi;
-        CiValue result = operand(phi);
+        Value result = operand(phi);
         if (result == null) {
             // allocate a variable for this phi
             Variable newOperand = newVariable(phi.kind());
@@ -664,30 +686,33 @@
 
     @Override
     public void emitIf(IfNode x) {
-        assert x.defaultSuccessor() == x.falseSuccessor() : "wrong destination";
         emitBranch(x.compare(), getLIRBlock(x.trueSuccessor()),  getLIRBlock(x.falseSuccessor()), null);
     }
 
     @Override
-    public void emitGuardCheck(BooleanNode comp, RiDeoptReason deoptReason, RiDeoptAction action, long leafGraphId) {
-        if (comp instanceof NullCheckNode && !((NullCheckNode) comp).expectedNull) {
-            emitNullCheckGuard((NullCheckNode) comp, leafGraphId);
-        } else if (comp instanceof ConstantNode && comp.asConstant().asBoolean()) {
+    public void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+        if (comp instanceof IsNullNode && negated) {
+            emitNullCheckGuard(((IsNullNode) comp).object(), leafGraphId);
+        } else if (comp instanceof ConstantNode && (comp.asConstant().asBoolean() != negated)) {
             // True constant, nothing to emit.
             // False constants are handled within emitBranch.
         } else {
             // Fall back to a normal branch.
             LIRDebugInfo info = state(leafGraphId);
             LabelRef stubEntry = createDeoptStub(action, deoptReason, info, comp);
-            emitBranch(comp, null, stubEntry, info);
+            if (negated) {
+                emitBranch(comp, stubEntry, null, info);
+            } else {
+                emitBranch(comp, null, stubEntry, info);
+            }
         }
     }
 
-    protected abstract void emitNullCheckGuard(NullCheckNode node, long leafGraphId);
+    protected abstract void emitNullCheckGuard(ValueNode object, long leafGraphId);
 
     public void emitBranch(BooleanNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
-        if (node instanceof NullCheckNode) {
-            emitNullCheckBranch((NullCheckNode) node, trueSuccessor, falseSuccessor, info);
+        if (node instanceof IsNullNode) {
+            emitNullCheckBranch((IsNullNode) node, trueSuccessor, falseSuccessor, info);
         } else if (node instanceof CompareNode) {
             emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor, info);
         } else if (node instanceof InstanceOfNode) {
@@ -701,25 +726,32 @@
         }
     }
 
-    private void emitNullCheckBranch(NullCheckNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
-        Condition cond = node.expectedNull ? Condition.NE : Condition.EQ;
-        emitBranch(operand(node.object()), CiConstant.NULL_OBJECT, cond, false, falseSuccessor, info);
-        if (trueSuccessor != null) {
-            emitJump(trueSuccessor, null);
+    private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
+        if (falseSuccessor != null) {
+            emitBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.NE, false, falseSuccessor, info);
+            if (trueSuccessor != null) {
+                emitJump(trueSuccessor, null);
+            }
+        } else {
+            emitBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, info);
         }
     }
 
     public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRDebugInfo info) {
-        emitBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock, info);
-        if (trueSuccessorBlock != null) {
-            emitJump(trueSuccessorBlock, null);
+        if (falseSuccessorBlock != null) {
+            emitBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock, info);
+            if (trueSuccessorBlock != null) {
+                emitJump(trueSuccessorBlock, null);
+            }
+        } else {
+            emitBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessorBlock, info);
         }
     }
 
     private void emitInstanceOfBranch(InstanceOfNode x, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRDebugInfo info) {
         XirArgument obj = toXirArgument(x.object());
-        XirSnippet snippet = xir.genInstanceOf(site(x, x.object()), obj, toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact());
-        emitXir(snippet, x, info, null, false, x.negated() ? falseSuccessor : trueSuccessor, x.negated() ? trueSuccessor : falseSuccessor);
+        XirSnippet snippet = xir.genInstanceOf(site(x, x.object()), obj, toXirArgument(x.targetClassInstruction()), x.targetClass(), x.profile());
+        emitXir(snippet, x, info, null, false, trueSuccessor, falseSuccessor);
     }
 
     public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRDebugInfo info) {
@@ -741,14 +773,14 @@
 
     @Override
     public void emitConditional(ConditionalNode conditional) {
-        CiValue tVal = operand(conditional.trueValue());
-        CiValue fVal = operand(conditional.falseValue());
+        Value tVal = operand(conditional.trueValue());
+        Value fVal = operand(conditional.falseValue());
         setResult(conditional, emitConditional(conditional.condition(), tVal, fVal));
     }
 
-    public Variable emitConditional(BooleanNode node, CiValue trueValue, CiValue falseValue) {
-        if (node instanceof NullCheckNode) {
-            return emitNullCheckConditional((NullCheckNode) node, trueValue, falseValue);
+    public Variable emitConditional(BooleanNode node, Value trueValue, Value falseValue) {
+        if (node instanceof IsNullNode) {
+            return emitNullCheckConditional((IsNullNode) node, trueValue, falseValue);
         } else if (node instanceof CompareNode) {
             return emitCompareConditional((CompareNode) node, trueValue, falseValue);
         } else if (node instanceof InstanceOfNode) {
@@ -760,38 +792,37 @@
         }
     }
 
-    private Variable emitNullCheckConditional(NullCheckNode node, CiValue trueValue, CiValue falseValue) {
-        Condition cond = node.expectedNull ? Condition.EQ : Condition.NE;
-        return emitCMove(operand(node.object()), CiConstant.NULL_OBJECT, cond, false, trueValue, falseValue);
+    private Variable emitNullCheckConditional(IsNullNode node, Value trueValue, Value falseValue) {
+        return emitCMove(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueValue, falseValue);
     }
 
-    private Variable emitInstanceOfConditional(InstanceOfNode x, CiValue trueValue, CiValue falseValue) {
+    private Variable emitInstanceOfConditional(InstanceOfNode x, Value trueValue, Value falseValue) {
         XirArgument obj = toXirArgument(x.object());
-        XirArgument trueArg = toXirArgument(x.negated() ? falseValue : trueValue);
-        XirArgument falseArg = toXirArgument(x.negated() ? trueValue : falseValue);
-        XirSnippet snippet = xir.genMaterializeInstanceOf(site(x, x.object()), obj, toXirArgument(x.targetClassInstruction()), trueArg, falseArg, x.targetClass(), x.hints(), x.hintsExact());
+        XirArgument trueArg = toXirArgument(trueValue);
+        XirArgument falseArg = toXirArgument(falseValue);
+        XirSnippet snippet = xir.genMaterializeInstanceOf(site(x, x.object()), obj, toXirArgument(x.targetClassInstruction()), trueArg, falseArg, x.targetClass(), x.profile());
         return (Variable) emitXir(snippet, null, null, false);
     }
 
-    private Variable emitConstantConditional(boolean value, CiValue trueValue, CiValue falseValue) {
+    private Variable emitConstantConditional(boolean value, Value trueValue, Value falseValue) {
         return emitMove(value ? trueValue : falseValue);
     }
 
-    private Variable emitCompareConditional(CompareNode compare, CiValue trueValue, CiValue falseValue) {
+    private Variable emitCompareConditional(CompareNode compare, Value trueValue, Value falseValue) {
         return emitCMove(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
     }
 
 
     public abstract void emitLabel(Label label, boolean align);
     public abstract void emitJump(LabelRef label, LIRDebugInfo info);
-    public abstract void emitBranch(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info);
-    public abstract Variable emitCMove(CiValue leftVal, CiValue right, Condition cond, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue);
+    public abstract void emitBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info);
+    public abstract Variable emitCMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue);
 
     protected FrameState stateBeforeCallWithArguments(FrameState stateAfter, MethodCallTargetNode call, int bci) {
         return stateAfter.duplicateModified(bci, stateAfter.rethrowException(), call.returnKind(), toJVMArgumentStack(call.targetMethod().signature(), call.isStatic(), call.arguments()));
     }
 
-    private static ValueNode[] toJVMArgumentStack(RiSignature signature, boolean isStatic, NodeInputList<ValueNode> arguments) {
+    private static ValueNode[] toJVMArgumentStack(Signature signature, boolean isStatic, NodeInputList<ValueNode> arguments) {
         int slotCount = signature.argumentSlots(!isStatic);
         ValueNode[] stack = new ValueNode[slotCount];
         int stackIndex = 0;
@@ -801,9 +832,9 @@
 
             if (stackIndex == 0 && !isStatic) {
                 // Current argument is receiver.
-                stackIndex += stackSlots(CiKind.Object);
+                stackIndex += stackSlots(Kind.Object);
             } else {
-                stackIndex += stackSlots(signature.argumentKindAt(argumentIndex, false));
+                stackIndex += stackSlots(signature.argumentKindAt(argumentIndex));
                 argumentIndex++;
             }
         }
@@ -811,19 +842,19 @@
     }
 
 
-    public static int stackSlots(CiKind kind) {
+    public static int stackSlots(Kind kind) {
         return isTwoSlot(kind) ? 2 : 1;
     }
 
-    public static boolean isTwoSlot(CiKind kind) {
-        assert kind != CiKind.Void && kind != CiKind.Illegal;
-        return kind == CiKind.Long || kind == CiKind.Double;
+    public static boolean isTwoSlot(Kind kind) {
+        assert kind != Kind.Void && kind != Kind.Illegal;
+        return kind == Kind.Long || kind == Kind.Double;
     }
 
     @Override
     public void emitInvoke(Invoke x) {
         MethodCallTargetNode callTarget = x.callTarget();
-        RiMethod targetMethod = callTarget.targetMethod();
+        JavaMethod targetMethod = callTarget.targetMethod();
 
         XirSnippet snippet = null;
         XirArgument receiver;
@@ -836,18 +867,18 @@
                 snippet = xir.genInvokeSpecial(site(x.node(), callTarget.receiver()), receiver, targetMethod);
                 break;
             case Virtual:
-                assert callTarget.receiver().kind() == CiKind.Object : callTarget + ": " + callTarget.targetMethod().toString();
+                assert callTarget.receiver().kind() == Kind.Object : callTarget + ": " + callTarget.targetMethod().toString();
                 receiver = toXirArgument(callTarget.receiver());
-                snippet = xir.genInvokeVirtual(site(x.node(), callTarget.receiver()), receiver, targetMethod, x.megamorph());
+                snippet = xir.genInvokeVirtual(site(x.node(), callTarget.receiver()), receiver, targetMethod, x.isMegamorphic());
                 break;
             case Interface:
-                assert callTarget.receiver().kind() == CiKind.Object : callTarget;
+                assert callTarget.receiver().kind() == Kind.Object : callTarget;
                 receiver = toXirArgument(callTarget.receiver());
                 snippet = xir.genInvokeInterface(site(x.node(), callTarget.receiver()), receiver, targetMethod);
                 break;
         }
 
-        CiValue destinationAddress = null;
+        Value destinationAddress = null;
         if (!target().invokeSnippetAfterArguments) {
             // This is the version currently necessary for Maxine: since the invokeinterface-snippet uses a division, it
             // destroys rdx, which is also used to pass a parameter.  Therefore, the snippet must be before the parameters are assigned to their locations.
@@ -855,12 +886,12 @@
             destinationAddress = emitXir(snippet, x.node(), addrInfo, false);
         }
 
-        CiValue resultOperand = resultOperandFor(x.node().kind());
+        Value resultOperand = resultOperandFor(x.node().kind());
 
-        CiKind[] signature = CiUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind(true));
-        CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false);
+        Kind[] signature = CodeUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind());
+        CallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false);
         frameMap.callsMethod(cc, JavaCall);
-        List<CiValue> argList = visitInvokeArguments(cc, callTarget.arguments());
+        List<Value> argList = visitInvokeArguments(cc, callTarget.arguments());
 
         if (target().invokeSnippetAfterArguments) {
             // This is the version currently active for HotSpot.
@@ -876,16 +907,16 @@
         }
     }
 
-    protected abstract void emitCall(Object targetMethod, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks);
+    protected abstract void emitCall(Object targetMethod, Value result, List<Value> arguments, Value targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks);
 
 
-    private static CiValue toStackKind(CiValue value) {
+    private static Value toStackKind(Value value) {
         if (value.kind.stackKind() != value.kind) {
             // We only have stack-kinds in the LIR, so convert the operand kind for values from the calling convention.
             if (isRegister(value)) {
                 return asRegister(value).asValue(value.kind.stackKind());
             } else if (isStackSlot(value)) {
-                return CiStackSlot.get(value.kind.stackKind(), asStackSlot(value).rawOffset(), asStackSlot(value).rawAddFrameSize());
+                return StackSlot.get(value.kind.stackKind(), asStackSlot(value).rawOffset(), asStackSlot(value).rawAddFrameSize());
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
@@ -893,13 +924,13 @@
         return value;
     }
 
-    public List<CiValue> visitInvokeArguments(CiCallingConvention cc, Iterable<ValueNode> arguments) {
+    public List<Value> visitInvokeArguments(CallingConvention cc, Iterable<ValueNode> arguments) {
         // for each argument, load it into the correct location
-        List<CiValue> argList = new ArrayList<>();
+        List<Value> argList = new ArrayList<>();
         int j = 0;
         for (ValueNode arg : arguments) {
             if (arg != null) {
-                CiValue operand = toStackKind(cc.locations[j++]);
+                Value operand = toStackKind(cc.locations[j++]);
                 emitMove(operand(arg), operand);
                 argList.add(operand);
 
@@ -911,25 +942,23 @@
     }
 
 
-    protected abstract LabelRef createDeoptStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo);
+    protected abstract LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRDebugInfo info, Object deoptInfo);
 
     @Override
-    public Variable emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args) {
+    public Variable emitCall(@SuppressWarnings("hiding") Object target, Kind result, Kind[] arguments, boolean canTrap, Value... args) {
         LIRDebugInfo info = canTrap ? state() : null;
 
-        CiKind result = runtimeCall.resultKind;
-        CiKind[] arguments = runtimeCall.arguments;
-        CiValue physReg = resultOperandFor(result);
+        Value physReg = resultOperandFor(result);
 
-        List<CiValue> argumentList;
+        List<Value> argumentList;
         if (arguments.length > 0) {
             // move the arguments into the correct location
-            CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
+            CallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
             frameMap.callsMethod(cc, RuntimeCall);
             assert cc.locations.length == args.length : "argument count mismatch";
             for (int i = 0; i < args.length; i++) {
-                CiValue arg = args[i];
-                CiValue loc = cc.locations[i];
+                Value arg = args[i];
+                Value loc = cc.locations[i];
                 emitMove(arg, loc);
             }
             argumentList = Arrays.asList(cc.locations);
@@ -939,7 +968,7 @@
             argumentList = Collections.emptyList();
         }
 
-        emitCall(runtimeCall, physReg, argumentList, CiConstant.forLong(0), info, null);
+        emitCall(target, physReg, argumentList, Constant.forLong(0), info, null);
 
         if (isLegal(physReg)) {
             return emitMove(physReg);
@@ -950,12 +979,10 @@
 
     @Override
     public void emitRuntimeCall(RuntimeCallNode x) {
-        // TODO Merge with emitCallToRuntime() method above.
-
-        CiValue resultOperand = resultOperandFor(x.kind());
-        CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, x.call().arguments, target(), false);
+        Value resultOperand = resultOperandFor(x.kind());
+        CallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, x.call().arguments, target(), false);
         frameMap.callsMethod(cc, RuntimeCall);
-        List<CiValue> argList = visitInvokeArguments(cc, x.arguments());
+        List<Value> argList = visitInvokeArguments(cc, x.arguments());
 
         LIRDebugInfo info = null;
         FrameState stateAfter = x.stateAfter();
@@ -972,127 +999,153 @@
 
             // TODO is it correct here that the pointerSlots are not passed to the oop map generation?
             info = stateFor(stateBeforeReturn, -1);
+        } else {
+            // Every runtime call needs an info
+            // TODO This is conservative. It's not needed for RuntimeCalls that are implemented purely in a stub
+            //       that does not trash any registers and does not call into the runtime.
+            info = state();
         }
 
-        emitCall(x.call(), resultOperand, argList, CiConstant.forLong(0), info, null);
+        emitCall(x.call(), resultOperand, argList, Constant.forLong(0), info, null);
 
         if (isLegal(resultOperand)) {
             setResult(x, emitMove(resultOperand));
         }
     }
 
+    /**
+     * This method tries to create a switch implementation that is optimal for the given switch.
+     * It will either generate a sequential if/then/else cascade, a set of range tests or a table switch.
+     *
+     * If the given switch does not contain int keys, it will always create a sequential implementation.
+     */
     @Override
-    public void emitLookupSwitch(LookupSwitchNode x) {
-        Variable tag = load(operand(x.value()));
-        if (x.numberOfCases() == 0 || x.numberOfCases() < GraalOptions.SequentialSwitchLimit) {
-            int len = x.numberOfCases();
-            for (int i = 0; i < len; i++) {
-                emitBranch(tag, CiConstant.forInt(x.keyAt(i)), Condition.EQ, false, getLIRBlock(x.blockSuccessor(i)), null);
-            }
+    public void emitSwitch(SwitchNode x) {
+        int keyCount = x.keyCount();
+        if (keyCount == 0) {
             emitJump(getLIRBlock(x.defaultSuccessor()), null);
         } else {
-            visitSwitchRanges(createSwitchRanges(x, null), tag, getLIRBlock(x.defaultSuccessor()));
-        }
-    }
-
-    @Override
-    public void emitTableSwitch(TableSwitchNode x) {
-        Variable value = load(operand(x.value()));
-        // TODO: tune the defaults for the controls used to determine what kind of translation to use
-        if (x.numberOfCases() == 0 || x.numberOfCases() <= GraalOptions.SequentialSwitchLimit) {
-            int loKey = x.lowKey();
-            int len = x.numberOfCases();
-            for (int i = 0; i < len; i++) {
-                emitBranch(value, CiConstant.forInt(i + loKey), Condition.EQ, false, getLIRBlock(x.blockSuccessor(i)), null);
-            }
-            emitJump(getLIRBlock(x.defaultSuccessor()), null);
-        } else {
-            SwitchRange[] switchRanges = createSwitchRanges(null, x);
-            int rangeDensity = x.numberOfCases() / switchRanges.length;
-            if (rangeDensity >= GraalOptions.RangeTestsSwitchDensity) {
-                visitSwitchRanges(switchRanges, value, getLIRBlock(x.defaultSuccessor()));
+            Variable value = load(operand(x.value()));
+            LabelRef defaultTarget = x.defaultSuccessor() == null ? null : getLIRBlock(x.defaultSuccessor());
+            if (value.kind == Kind.Object || keyCount < GraalOptions.SequentialSwitchLimit) {
+                // only a few entries
+                emitSequentialSwitch(x, value, defaultTarget);
             } else {
-                LabelRef[] targets = new LabelRef[x.numberOfCases()];
-                for (int i = 0; i < x.numberOfCases(); ++i) {
-                    targets[i] = getLIRBlock(x.blockSuccessor(i));
+                long valueRange = x.keyAt(keyCount - 1).asLong() - x.keyAt(0).asLong() + 1;
+                int switchRangeCount = switchRangeCount(x);
+                int rangeDensity = keyCount / switchRangeCount;
+                if (rangeDensity >= GraalOptions.RangeTestsSwitchDensity) {
+                    emitSwitchRanges(x, switchRangeCount, value, defaultTarget);
+                } else if (keyCount / (double) valueRange >= GraalOptions.MinTableSwitchDensity) {
+                    int minValue = x.keyAt(0).asInt();
+                    assert valueRange < Integer.MAX_VALUE;
+                    LabelRef[] targets = new LabelRef[(int) valueRange];
+                    for (int i = 0; i < valueRange; i++) {
+                        targets[i] = defaultTarget;
+                    }
+                    for (int i = 0; i < keyCount; i++) {
+                        targets[x.keyAt(i).asInt() - minValue] = getLIRBlock(x.keySuccessor(i));
+                    }
+                    emitTableSwitch(minValue, defaultTarget, targets, value);
+                } else {
+                    emitSequentialSwitch(x, value, defaultTarget);
                 }
-                emitTableSwitch(x.lowKey(), getLIRBlock(x.defaultSuccessor()), targets, value);
             }
         }
     }
 
-    protected abstract void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiValue index);
+    private void emitSequentialSwitch(final SwitchNode x, Variable key, LabelRef defaultTarget) {
+        int keyCount = x.keyCount();
+        Integer[] indexes = new Integer[keyCount];
+        for (int i = 0; i < keyCount; i++) {
+            indexes[i] = i;
+        }
+        Arrays.sort(indexes, new Comparator<Integer>() {
+            @Override
+            public int compare(Integer o1, Integer o2) {
+                return x.keyProbability(o1) < x.keyProbability(o2) ? 1 : x.keyProbability(o1) > x.keyProbability(o2) ? -1 : 0;
+            }
+        });
+        LabelRef[] keyTargets = new LabelRef[keyCount];
+        Constant[] keyConstants = new Constant[keyCount];
+        for (int i = 0; i < keyCount; i++) {
+            keyTargets[i] = getLIRBlock(x.keySuccessor(indexes[i]));
+            keyConstants[i] = x.keyAt(indexes[i]);
+        }
+        emitSequentialSwitch(keyConstants, keyTargets, defaultTarget, key);
+    }
 
-    // the range of values in a lookupswitch or tableswitch statement
-    private static final class SwitchRange {
-        protected final int lowKey;
-        protected int highKey;
-        protected final LabelRef sux;
+    protected abstract void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key);
+    protected abstract void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key);
+    protected abstract void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key);
 
-        SwitchRange(int lowKey, LabelRef sux) {
-            this.lowKey = lowKey;
-            this.highKey = lowKey;
-            this.sux = sux;
+    private static int switchRangeCount(SwitchNode x) {
+        int keyCount = x.keyCount();
+        int i = 0;
+        while (i < keyCount && x.keySuccessorIndex(i) == x.defaultSuccessorIndex()) {
+            i++;
+        }
+        if (i == keyCount) {
+            return 0;
+        } else {
+            int switchRangeCount = 1;
+            i++;
+            for (; i < keyCount; i++) {
+                if (x.keySuccessorIndex(i) != x.defaultSuccessorIndex()) {
+                    if (x.keyAt(i).asInt() != x.keyAt(i - 1).asInt() + 1 || x.keySuccessorIndex(i) != x.keySuccessorIndex(i - 1)) {
+                        switchRangeCount++;
+                    }
+                }
+            }
+            return switchRangeCount;
         }
     }
 
-    private SwitchRange[] createSwitchRanges(LookupSwitchNode ls, TableSwitchNode ts) {
-        // Only one of the parameters is used, but code is shared because it is mostly the same.
-        SwitchNode x = ls != null ? ls : ts;
-        // we expect the keys to be sorted by increasing value
-        List<SwitchRange> res = new ArrayList<>(x.numberOfCases());
-        int len = x.numberOfCases();
-        if (len > 0) {
-            LabelRef defaultSux = getLIRBlock(x.defaultSuccessor());
-            int key = ls != null ? ls.keyAt(0) : ts.lowKey();
-            LabelRef sux = getLIRBlock(x.blockSuccessor(0));
-            SwitchRange range = new SwitchRange(key, sux);
-            for (int i = 1; i < len; i++) {
-                int newKey = ls != null ? ls.keyAt(i) : key + 1;
-                LabelRef newSux = getLIRBlock(x.blockSuccessor(i));
-                if (key + 1 == newKey && sux == newSux) {
-                    // still in same range
-                    range.highKey = newKey;
-                } else {
-                    // skip tests which explicitly dispatch to the default
-                    if (range.sux != defaultSux) {
-                        res.add(range);
+    private void emitSwitchRanges(SwitchNode x, int switchRangeCount, Variable keyValue, LabelRef defaultTarget) {
+        int[] lowKeys = new int[switchRangeCount];
+        int[] highKeys = new int[switchRangeCount];
+        LabelRef[] targets = new LabelRef[switchRangeCount];
+
+        int keyCount = x.keyCount();
+        int defaultSuccessor = x.defaultSuccessorIndex();
+
+        int current = 0;
+        int i = 0;
+        while (i < keyCount && x.keySuccessorIndex(i) == x.defaultSuccessorIndex()) {
+            i++;
+        }
+        if (i == keyCount) {
+            emitJump(defaultTarget, null);
+        } else {
+            int key = x.keyAt(i).asInt();
+            int successor = x.keySuccessorIndex(i);
+            lowKeys[current] = key;
+            highKeys[current] = key;
+            targets[current] = getLIRBlock(x.blockSuccessor(successor));
+            i++;
+            for (; i < keyCount; i++) {
+                int newSuccessor = x.keySuccessorIndex(i);
+                if (newSuccessor != defaultSuccessor) {
+                    int newKey = x.keyAt(i).asInt();
+                    if (key + 1 == newKey && successor == newSuccessor) {
+                        // still in same range
+                        highKeys[current] = newKey;
+                    } else {
+                        current++;
+                        lowKeys[current] = newKey;
+                        highKeys[current] = newKey;
+                        targets[current] = getLIRBlock(x.blockSuccessor(newSuccessor));
                     }
-                    range = new SwitchRange(newKey, newSux);
+                    key = newKey;
                 }
-                key = newKey;
-                sux = newSux;
+                successor = newSuccessor;
             }
-            if (res.size() == 0 || res.get(res.size() - 1) != range) {
-                res.add(range);
-            }
+            assert current == switchRangeCount - 1;
+            emitSwitchRanges(lowKeys, highKeys, targets, defaultTarget, keyValue);
         }
-        return res.toArray(new SwitchRange[res.size()]);
     }
 
-    private void visitSwitchRanges(SwitchRange[] x, Variable value, LabelRef defaultSux) {
-        for (int i = 0; i < x.length; i++) {
-            SwitchRange oneRange = x[i];
-            int lowKey = oneRange.lowKey;
-            int highKey = oneRange.highKey;
-            LabelRef dest = oneRange.sux;
-            if (lowKey == highKey) {
-                emitBranch(value, CiConstant.forInt(lowKey), Condition.EQ, false, dest, null);
-            } else if (highKey - lowKey == 1) {
-                emitBranch(value, CiConstant.forInt(lowKey), Condition.EQ, false, dest, null);
-                emitBranch(value, CiConstant.forInt(highKey), Condition.EQ, false, dest, null);
-            } else {
-                Label l = new Label();
-                emitBranch(value, CiConstant.forInt(lowKey), Condition.LT, false, LabelRef.forLabel(l), null);
-                emitBranch(value, CiConstant.forInt(highKey), Condition.LE, false, dest, null);
-                emitLabel(l, false);
-            }
-        }
-        emitJump(defaultSux, null);
-    }
-
-
-    protected XirArgument toXirArgument(CiValue v) {
+    protected XirArgument toXirArgument(Value v) {
         if (v == null) {
             return null;
         }
@@ -1106,7 +1159,7 @@
         return XirArgument.forInternalObject(loadNonConst(operand(i)));
     }
 
-    private CiValue allocateOperand(XirSnippet snippet, XirOperand op) {
+    private Value allocateOperand(XirSnippet snippet, XirOperand op) {
         if (op instanceof XirParameter)  {
             XirParameter param = (XirParameter) op;
             return allocateOperand(snippet.arguments[param.parameterIndex], op, param.canBeConstant);
@@ -1121,44 +1174,44 @@
         }
     }
 
-    private CiValue allocateOperand(XirArgument arg, XirOperand var, boolean canBeConstant) {
+    private Value allocateOperand(XirArgument arg, XirOperand var, boolean canBeConstant) {
         if (arg.constant != null) {
             return arg.constant;
         }
 
-        CiValue value = (CiValue) arg.object;
+        Value value = (Value) arg.object;
         if (canBeConstant) {
             return value;
         }
         Variable variable = load(value);
-        if (var.kind == CiKind.Byte || var.kind == CiKind.Boolean) {
-            Variable tempVar = new Variable(value.kind, lir.nextVariable(), CiRegister.RegisterFlag.Byte);
+        if (var.kind == Kind.Byte || var.kind == Kind.Boolean) {
+            Variable tempVar = new Variable(value.kind, lir.nextVariable(), Register.RegisterFlag.Byte);
             emitMove(variable, tempVar);
             variable = tempVar;
         }
         return variable;
     }
 
-    protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, boolean setInstructionResult) {
+    protected Value emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, boolean setInstructionResult) {
         return emitXir(snippet, x, info, null, setInstructionResult, null, null);
     }
 
-    protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, boolean setInstructionResult, LabelRef trueSuccessor, LabelRef falseSuccessor) {
+    protected Value emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, boolean setInstructionResult, LabelRef trueSuccessor, LabelRef falseSuccessor) {
         if (GraalOptions.PrintXirTemplates) {
             TTY.println("Emit XIR template " + snippet.template.name);
         }
 
-        final CiValue[] operandsArray = new CiValue[snippet.template.variableCount];
+        final Value[] operandsArray = new Value[snippet.template.variableCount];
 
         frameMap.reserveOutgoing(snippet.template.outgoingStackSize);
 
         XirOperand resultOperand = snippet.template.resultOperand;
 
         if (snippet.template.allocateResultOperand) {
-            CiValue outputOperand = IllegalValue;
+            Value outputOperand = IllegalValue;
             // This snippet has a result that must be separately allocated
             // Otherwise it is assumed that the result is part of the inputs
-            if (resultOperand.kind != CiKind.Void && resultOperand.kind != CiKind.Illegal) {
+            if (resultOperand.kind != Kind.Void && resultOperand.kind != Kind.Illegal) {
                 if (setInstructionResult) {
                     outputOperand = newVariable(instruction.kind());
                 } else {
@@ -1190,13 +1243,13 @@
         XirOperand[] inputTempOperands = snippet.template.inputTempOperands;
         XirOperand[] tempOperands = snippet.template.tempOperands;
 
-        CiValue[] inputOperandArray = new CiValue[inputOperands.length + inputTempOperands.length];
-        CiValue[] tempOperandArray = new CiValue[tempOperands.length];
+        Value[] inputOperandArray = new Value[inputOperands.length + inputTempOperands.length];
+        Value[] tempOperandArray = new Value[tempOperands.length];
         int[] inputOperandIndicesArray = new int[inputOperands.length + inputTempOperands.length];
         int[] tempOperandIndicesArray = new int[tempOperands.length];
         for (int i = 0; i < inputOperands.length; i++) {
             XirOperand x = inputOperands[i];
-            CiValue op = allocateOperand(snippet, x);
+            Value op = allocateOperand(snippet, x);
             operandsArray[x.index] = op;
             inputOperandArray[i] = op;
             inputOperandIndicesArray[i] = x.index;
@@ -1209,7 +1262,7 @@
 
         for (int i = 0; i < tempOperands.length; i++) {
             XirOperand x = tempOperands[i];
-            CiValue op = allocateOperand(snippet, x);
+            Value op = allocateOperand(snippet, x);
             operandsArray[x.index] = op;
             tempOperandArray[i] = op;
             tempOperandIndicesArray[i] = x.index;
@@ -1218,17 +1271,17 @@
             }
         }
 
-        for (CiValue operand : operandsArray) {
+        for (Value operand : operandsArray) {
             assert operand != null;
         }
 
-        CiValue allocatedResultOperand = operandsArray[resultOperand.index];
+        Value allocatedResultOperand = operandsArray[resultOperand.index];
         if (!isVariable(allocatedResultOperand) && !isRegister(allocatedResultOperand)) {
             allocatedResultOperand = IllegalValue;
         }
 
         if (setInstructionResult && isLegal(allocatedResultOperand)) {
-            CiValue operand = operand(instruction);
+            Value operand = operand(instruction);
             if (operand == null) {
                 setResult(instruction, allocatedResultOperand);
             } else {
@@ -1250,25 +1303,25 @@
         return operandsArray[resultOperand.index];
     }
 
-    protected abstract void emitXir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+    protected abstract void emitXir(XirSnippet snippet, Value[] operands, Value outputOperand, Value[] inputs, Value[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
                     LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor);
 
-    protected final CiValue callRuntime(CiRuntimeCall runtimeCall, LIRDebugInfo info, CiValue... args) {
+    protected final Value callRuntime(RuntimeCall runtimeCall, LIRDebugInfo info, Value... args) {
         // get a result register
-        CiKind result = runtimeCall.resultKind;
-        CiKind[] arguments = runtimeCall.arguments;
+        Kind result = runtimeCall.resultKind;
+        Kind[] arguments = runtimeCall.arguments;
 
-        CiValue physReg = result.isVoid() ? IllegalValue : resultOperandFor(result);
+        Value physReg = result.isVoid() ? IllegalValue : resultOperandFor(result);
 
-        List<CiValue> argumentList;
+        List<Value> argumentList;
         if (arguments.length > 0) {
             // move the arguments into the correct location
-            CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
+            CallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
             frameMap.callsMethod(cc, RuntimeCall);
             assert cc.locations.length == args.length : "argument count mismatch";
             for (int i = 0; i < args.length; i++) {
-                CiValue arg = args[i];
-                CiValue loc = cc.locations[i];
+                Value arg = args[i];
+                Value loc = cc.locations[i];
                 emitMove(arg, loc);
             }
             argumentList = Arrays.asList(cc.locations);
@@ -1278,78 +1331,16 @@
             argumentList = Util.uncheckedCast(Collections.emptyList());
         }
 
-        emitCall(runtimeCall, physReg, argumentList, CiConstant.forLong(0), info, null);
+        emitCall(runtimeCall, physReg, argumentList, Constant.forLong(0), info, null);
 
         return physReg;
     }
 
-    protected final Variable callRuntimeWithResult(CiRuntimeCall runtimeCall, LIRDebugInfo info, CiValue... args) {
-        CiValue location = callRuntime(runtimeCall, info, args);
+    protected final Variable callRuntimeWithResult(RuntimeCall runtimeCall, LIRDebugInfo info, Value... args) {
+        Value location = callRuntime(runtimeCall, info, args);
         return emitMove(location);
     }
 
-    SwitchRange[] createLookupRanges(LookupSwitchNode x) {
-        // we expect the keys to be sorted by increasing value
-        List<SwitchRange> res = new ArrayList<>(x.numberOfCases());
-        int len = x.numberOfCases();
-        if (len > 0) {
-            LabelRef defaultSux = getLIRBlock(x.defaultSuccessor());
-            int key = x.keyAt(0);
-            LabelRef sux = getLIRBlock(x.blockSuccessor(0));
-            SwitchRange range = new SwitchRange(key, sux);
-            for (int i = 1; i < len; i++) {
-                int newKey = x.keyAt(i);
-                LabelRef newSux = getLIRBlock(x.blockSuccessor(i));
-                if (key + 1 == newKey && sux == newSux) {
-                    // still in same range
-                    range.highKey = newKey;
-                } else {
-                    // skip tests which explicitly dispatch to the default
-                    if (range.sux != defaultSux) {
-                        res.add(range);
-                    }
-                    range = new SwitchRange(newKey, newSux);
-                }
-                key = newKey;
-                sux = newSux;
-            }
-            if (res.size() == 0 || res.get(res.size() - 1) != range) {
-                res.add(range);
-            }
-        }
-        return res.toArray(new SwitchRange[res.size()]);
-    }
-
-    SwitchRange[] createLookupRanges(TableSwitchNode x) {
-        // TODO: try to merge this with the code for LookupSwitch
-        List<SwitchRange> res = new ArrayList<>(x.numberOfCases());
-        int len = x.numberOfCases();
-        if (len > 0) {
-            LabelRef sux = getLIRBlock(x.blockSuccessor(0));
-            int key = x.lowKey();
-            LabelRef defaultSux = getLIRBlock(x.defaultSuccessor());
-            SwitchRange range = new SwitchRange(key, sux);
-            for (int i = 0; i < len; i++, key++) {
-                LabelRef newSux = getLIRBlock(x.blockSuccessor(i));
-                if (sux == newSux) {
-                    // still in same range
-                    range.highKey = key;
-                } else {
-                    // skip tests which explicitly dispatch to the default
-                    if (sux != defaultSux) {
-                        res.add(range);
-                    }
-                    range = new SwitchRange(key, newSux);
-                }
-                sux = newSux;
-            }
-            if (res.size() == 0 || res.get(res.size() - 1) != range) {
-                res.add(range);
-            }
-        }
-        return res.toArray(new SwitchRange[res.size()]);
-    }
-
     protected XirSupport site(ValueNode x) {
         return xirSupport.site(x, null);
     }
@@ -1362,15 +1353,21 @@
      * Implements site-specific information for the XIR interface.
      */
     static class XirSupport implements XirSite {
+        final Assumptions assumptions;
         ValueNode current;
         ValueNode receiver;
 
+
+        public XirSupport(Assumptions assumptions) {
+            this.assumptions = assumptions;
+        }
+
         public boolean isNonNull(XirArgument argument) {
             return false;
         }
 
         public boolean requiresNullCheck() {
-            return receiver == null || !receiver.stamp().nonNull();
+            return receiver == null || !(receiver.stamp() instanceof ObjectStamp && ((ObjectStamp) receiver.stamp()).nonNull());
         }
 
         public boolean requiresBoundsCheck() {
@@ -1389,6 +1386,10 @@
             return true;
         }
 
+        public Assumptions assumptions() {
+            return assumptions;
+        }
+
         XirSupport site(ValueNode v, ValueNode r) {
             current = v;
             receiver = r;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.compiler.gen;
 
-import static com.oracle.max.cri.ci.CiValue.*;
-import static com.oracle.graal.lir.ValueUtil.*;
+import static com.oracle.graal.api.meta.Value.*;
+import static com.oracle.graal.lir.LIRValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -58,7 +58,7 @@
         /**
          * A source operand whose value flows into the {@linkplain #destinations destination} operands.
          */
-        final CiValue operand;
+        final Value operand;
 
         /**
          * The operands whose values are defined by the {@linkplain #operand source} operand.
@@ -80,7 +80,7 @@
          */
         boolean startNode;
 
-        PhiResolverNode(CiValue operand) {
+        PhiResolverNode(Value operand) {
             this.operand = operand;
             destinations = new ArrayList<>(4);
         }
@@ -105,7 +105,7 @@
      */
     private PhiResolverNode loop;
 
-    private CiValue temp;
+    private Value temp;
 
     private final ArrayList<PhiResolverNode> variableOperands = new ArrayList<>(3);
     private final ArrayList<PhiResolverNode> otherOperands = new ArrayList<>(3);
@@ -113,7 +113,7 @@
     /**
      * Maps operands to nodes.
      */
-    private final HashMap<CiValue, PhiResolverNode> operandToNodeMap = new HashMap<>();
+    private final HashMap<Value, PhiResolverNode> operandToNodeMap = new HashMap<>();
 
     public PhiResolver(LIRGenerator gen) {
         this.gen = gen;
@@ -141,7 +141,7 @@
         }
     }
 
-    public void move(CiValue src, CiValue dest) {
+    public void move(Value src, Value dest) {
         assert isVariable(dest) : "destination must be virtual";
         // tty.print("move "); src.print(); tty.print(" to "); dest.print(); tty.cr();
         assert isLegal(src) : "source for phi move is illegal";
@@ -151,7 +151,7 @@
         srcNode.destinations.add(destNode);
       }
 
-    private PhiResolverNode createNode(CiValue operand, boolean source) {
+    private PhiResolverNode createNode(Value operand, boolean source) {
         PhiResolverNode node;
         if (isVariable(operand)) {
             node = operandToNodeMap.get(operand);
@@ -175,11 +175,11 @@
         return node;
     }
 
-    private PhiResolverNode destinationNode(CiValue opr) {
+    private PhiResolverNode destinationNode(Value opr) {
         return createNode(opr, false);
     }
 
-    private void emitMove(CiValue src, CiValue dest) {
+    private void emitMove(Value src, Value dest) {
         assert isLegal(src);
         assert isLegal(dest);
         gen.emitMove(src, dest);
@@ -217,19 +217,19 @@
         }
     }
 
-    private void moveTempTo(CiValue dest) {
+    private void moveTempTo(Value dest) {
         assert isLegal(temp);
         emitMove(temp, dest);
         temp = IllegalValue;
     }
 
-    private void moveToTemp(CiValue src) {
+    private void moveToTemp(Value src) {
         assert isIllegal(temp);
         temp = gen.newVariable(src.kind);
         emitMove(src, temp);
     }
 
-    private PhiResolverNode sourceNode(CiValue opr) {
+    private PhiResolverNode sourceNode(Value opr) {
         return createNode(opr, true);
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/graph/GraphCache.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +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.graal.compiler.graph;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.cri.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ri.*;
-
-public class GraphCache implements RiGraphCache {
-
-    private static final PrintStream out = System.out;
-    private final boolean dump;
-    private boolean enabled = true;
-
-    private final AtomicLong hitCounter = new AtomicLong();
-    private final AtomicLong missCounter = new AtomicLong();
-    private final AtomicLong removeHitCounter = new AtomicLong();
-    private final AtomicLong removeMissCounter = new AtomicLong();
-    private final AtomicLong putCounter = new AtomicLong();
-
-    private class LRUCache extends LinkedHashMap<RiResolvedMethod, Long> {
-        private static final long serialVersionUID = -3973307040793397840L;
-
-        public LRUCache(int initialCapacity) {
-            super(initialCapacity * 2, 0.75f, false);
-        }
-        @Override
-        protected boolean removeEldestEntry(Entry<RiResolvedMethod, Long> eldest) {
-            if (size() > GraalOptions.GraphCacheSize) {
-                graphs.remove(eldest.getValue());
-                cachedGraphIds.remove(eldest.getKey());
-                return true;
-            } else {
-                return false;
-            }
-        }
-
-    }
-
-    private final Map<RiResolvedMethod, Long> currentGraphIds = Collections.synchronizedMap(new LRUCache(GraalOptions.GraphCacheSize));
-
-    private final ConcurrentHashMap<Long, StructuredGraph> graphs = new ConcurrentHashMap<>();
-    private final ConcurrentHashMap<Long, RiResolvedMethod> cachedGraphIds = new ConcurrentHashMap<>();
-
-
-    public GraphCache(boolean dump) {
-        this.dump = dump;
-
-        if (dump) {
-            Runtime.getRuntime().addShutdownHook(new Thread() {
-                @Override
-                public void run() {
-                    out.println("put: " + putCounter.get());
-                    out.println("get hit: " + hitCounter.get());
-                    out.println("get miss: " + missCounter.get());
-                    out.println("remove hit: " + removeHitCounter.get());
-                    out.println("remove miss: " + removeMissCounter.get());
-                }
-            });
-        }
-    }
-
-    public void enable() {
-        enabled = true;
-    }
-
-    @Override
-    public StructuredGraph get(RiResolvedMethod method) {
-        if (!enabled) {
-            return null;
-        }
-        Long currentId = currentGraphIds.get(method);
-        StructuredGraph result = null;
-        if (currentId != null) {
-            result = graphs.get(currentId);
-        }
-
-        if (dump) {
-            if (result == null) {
-                missCounter.incrementAndGet();
-            } else {
-                hitCounter.incrementAndGet();
-            }
-//            if (result == null) {
-//                out.println("miss: " + missCounter.incrementAndGet() + " " + method);
-//            } else {
-//                out.println("hit: " + hitCounter.incrementAndGet() + " " + method);
-//            }
-        }
-        return result;
-    }
-
-    @Override
-    public void put(StructuredGraph graph) {
-        if (!enabled) {
-            return;
-        }
-        assert graph.method() != null;
-        Long currentId = currentGraphIds.get(graph.method());
-        if (currentId != null) {
-            graphs.remove(currentId);
-            cachedGraphIds.remove(currentId);
-        }
-        currentGraphIds.put(graph.method(), graph.graphId());
-        cachedGraphIds.put(graph.graphId(), graph.method());
-        graphs.put(graph.graphId(), graph);
-
-        if (dump) {
-            putCounter.incrementAndGet();
-//            out.println("put: " + putCounter.incrementAndGet() + " (size: " + graphs.size() + ")");
-        }
-    }
-
-    public void clear() {
-        graphs.clear();
-        currentGraphIds.clear();
-        cachedGraphIds.clear();
-        hitCounter.set(0);
-        missCounter.set(0);
-        removeHitCounter.set(0);
-        removeMissCounter.set(0);
-        putCounter.set(0);
-    }
-
-    public void removeGraphs(long[] deoptedGraphs) {
-        for (long graphId : deoptedGraphs) {
-            graphs.remove(graphId);
-            RiResolvedMethod method = cachedGraphIds.get(graphId);
-            if (method != null) {
-                cachedGraphIds.remove(graphId);
-                currentGraphIds.remove(method);
-            }
-            if (dump) {
-                if (method != null) {
-                    removeHitCounter.incrementAndGet();
-                } else {
-                    removeMissCounter.incrementAndGet();
-                }
-//                if (method != null) {
-//                    out.println("remove hit: " + removeHitCounter.incrementAndGet() + " (" + graphId + " " + method + ")");
-//                } else {
-//                    out.println("remove miss: " + removeMissCounter.incrementAndGet() + " (" + graphId + ")");
-//                }
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/BasicInductionVariable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.type.*;
+
+
+public class BasicInductionVariable extends InductionVariable {
+    private PhiNode phi;
+    private ValueNode init;
+    private ValueNode rawStride;
+    private IntegerArithmeticNode op;
+
+    public BasicInductionVariable(LoopEx loop, PhiNode phi, ValueNode init, ValueNode rawStride, IntegerArithmeticNode op) {
+        super(loop);
+        this.phi = phi;
+        this.init = init;
+        this.rawStride = rawStride;
+        this.op = op;
+    }
+
+    @Override
+    public Direction direction() {
+        Stamp stamp = rawStride.stamp();
+        if (stamp instanceof IntegerStamp) {
+            IntegerStamp integerStamp = (IntegerStamp) stamp;
+            Direction dir = null;
+            if (integerStamp.lowerBound() > 0) {
+                dir = Direction.Up;
+            } else if (integerStamp.upperBound() < 0) {
+                dir =  Direction.Down;
+            }
+            if (dir != null) {
+                if (op instanceof IntegerAddNode) {
+                    return dir;
+                } else {
+                    assert op instanceof IntegerSubNode;
+                    return dir.opposite();
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public PhiNode valueNode() {
+        return phi;
+    }
+
+    @Override
+    public ValueNode initNode() {
+        return init;
+    }
+
+    @Override
+    public ValueNode strideNode() {
+        if (op instanceof IntegerAddNode) {
+            return rawStride;
+        }
+        if (op instanceof IntegerSubNode) {
+            return rawStride.graph().unique(new NegateNode(rawStride));
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    @Override
+    public boolean isConstantInit() {
+        return init.isConstant();
+    }
+
+    @Override
+    public boolean isConstantStride() {
+        return rawStride.isConstant();
+    }
+
+    @Override
+    public long constantInit() {
+        return init.asConstant().asLong();
+    }
+
+    @Override
+    public long constantStride() {
+        if (op instanceof IntegerAddNode) {
+            return rawStride.asConstant().asLong();
+        }
+        if (op instanceof IntegerSubNode) {
+            return -rawStride.asConstant().asLong();
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    @Override
+    public ValueNode extremumNode() {
+        return IntegerArithmeticNode.add(IntegerArithmeticNode.mul(strideNode(), loop.counted().maxTripCountNode()), init);
+    }
+
+    @Override
+    public boolean isConstantExtremum() {
+        return isConstantInit() && isConstantStride() && loop.counted().isConstantMaxTripCount();
+    }
+
+    @Override
+    public long constantExtremum() {
+        return constantStride() * loop.counted().constantMaxTripCount() + constantInit();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/CountedLoopInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.compiler.loop.InductionVariable.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+
+public class CountedLoopInfo {
+    private final LoopEx loop;
+    private InductionVariable iv;
+    private ValueNode end;
+    private boolean oneOff;
+
+    CountedLoopInfo(LoopEx loop, InductionVariable iv, ValueNode end, boolean oneOff) {
+        this.loop = loop;
+        this.iv = iv;
+        this.end = end;
+        this.oneOff = oneOff;
+    }
+
+    public ValueNode maxTripCountNode() {
+        //TODO (gd) stuarte and respect oneOff
+        return IntegerArithmeticNode.div(IntegerArithmeticNode.sub(end, iv.initNode()), iv.strideNode());
+    }
+
+    public boolean isConstantMaxTripCount() {
+        return end instanceof ConstantNode && iv.isConstantInit() && iv.isConstantStride();
+    }
+
+    public long constantMaxTripCount() {
+        long off = oneOff ? iv.direction() == Direction.Up ? 1 : -1 : 0;
+        long max = (((ConstantNode) end).asConstant().asLong() + off - iv.constantInit()) / iv.constantStride();
+        return Math.max(0, max);
+    }
+
+    public boolean isExactTripCount() {
+        return loop.loopBegin().loopExits().count() == 1;
+    }
+
+    public ValueNode exactTripCountNode() {
+        assert isExactTripCount();
+        return maxTripCountNode();
+    }
+
+    public boolean isConstantExactTripCount() {
+        assert isExactTripCount();
+        return isConstantMaxTripCount();
+    }
+
+    public long constantExactTripCount() {
+        assert isExactTripCount();
+        return constantMaxTripCount();
+    }
+
+    @Override
+    public String toString() {
+        return "iv=" + iv + " until " + end + (oneOff ? iv.direction() == Direction.Up ? "+1" : "-1" : "");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/DerivedOffsetInductionVariable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+
+
+public class DerivedOffsetInductionVariable extends InductionVariable {
+    private InductionVariable base;
+    private ValueNode offset;
+    private IntegerArithmeticNode value;
+
+    public DerivedOffsetInductionVariable(LoopEx loop, InductionVariable base, ValueNode offset, IntegerArithmeticNode value) {
+        super(loop);
+        this.base = base;
+        this.offset = offset;
+        this.value = value;
+    }
+
+    @Override
+    public Direction direction() {
+        return base.direction();
+    }
+
+    @Override
+    public ValueNode valueNode() {
+        return value;
+    }
+
+    @Override
+    public boolean isConstantInit() {
+        return offset.isConstant() && base.isConstantInit();
+    }
+
+    @Override
+    public boolean isConstantStride() {
+        return base.isConstantStride();
+    }
+
+    @Override
+    public long constantInit() {
+        return op(base.constantInit(), offset.asConstant().asLong());
+    }
+
+    @Override
+    public long constantStride() {
+        if (value instanceof IntegerSubNode && base.valueNode() == value.y()) {
+            return -base.constantStride();
+        }
+        return base.constantStride();
+    }
+
+    @Override
+    public ValueNode initNode() {
+        return op(base.initNode(), offset);
+    }
+
+    @Override
+    public ValueNode strideNode() {
+        if (value instanceof IntegerSubNode && base.valueNode() == value.y()) {
+            return value.graph().unique(new NegateNode(base.strideNode()));
+        }
+        return base.strideNode();
+    }
+
+    @Override
+    public ValueNode extremumNode() {
+        return op(offset, base.extremumNode());
+    }
+
+    @Override
+    public boolean isConstantExtremum() {
+        return offset.isConstant() && base.isConstantExtremum();
+    }
+
+    @Override
+    public long constantExtremum() {
+        return op(base.constantExtremum(), offset.asConstant().asLong());
+    }
+
+    private long op(long b, long o) {
+        if (value instanceof IntegerAddNode) {
+            return b + o;
+        }
+        if (value instanceof IntegerSubNode) {
+            if (base.valueNode() == value.x()) {
+                return b - o;
+            } else {
+                assert base.valueNode() == value.y();
+                return o - b;
+            }
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+
+    private ValueNode op(ValueNode b, ValueNode o) {
+        if (value instanceof IntegerAddNode) {
+        return IntegerArithmeticNode.add(b, o);
+        }
+        if (value instanceof IntegerSubNode) {
+            if (base.valueNode() == value.x()) {
+                return IntegerArithmeticNode.sub(b, o);
+            } else {
+                assert base.valueNode() == value.y();
+                return IntegerArithmeticNode.sub(o, b);
+            }
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/DerivedScaledInductionVariable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.type.*;
+
+
+public class DerivedScaledInductionVariable extends InductionVariable {
+    private InductionVariable base;
+    private ValueNode scale;
+    private ValueNode value;
+
+    public DerivedScaledInductionVariable(LoopEx loop, InductionVariable base, ValueNode scale, ValueNode value) {
+        super(loop);
+        this.base = base;
+        this.scale = scale;
+        this.value = value;
+    }
+
+    public DerivedScaledInductionVariable(LoopEx loop, InductionVariable base, NegateNode value) {
+        super(loop);
+        this.base = base;
+        this.scale = ConstantNode.forInt(-1, value.graph());
+        this.value = value;
+    }
+
+    @Override
+    public Direction direction() {
+        Stamp stamp = scale.stamp();
+        if (stamp instanceof IntegerStamp) {
+            IntegerStamp integerStamp = (IntegerStamp) stamp;
+            if (integerStamp.lowerBound() > 0) {
+                return base.direction();
+            } else if (integerStamp.upperBound() < 0) {
+                return base.direction().opposite();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public ValueNode valueNode() {
+        return value;
+    }
+
+    @Override
+    public ValueNode initNode() {
+        return IntegerArithmeticNode.mul(base.initNode(), scale);
+    }
+
+    @Override
+    public ValueNode strideNode() {
+        return IntegerArithmeticNode.mul(base.strideNode(), scale);
+    }
+
+    @Override
+    public boolean isConstantInit() {
+        return scale.isConstant() && base.isConstantInit();
+    }
+
+    @Override
+    public boolean isConstantStride() {
+        return scale.isConstant() && base.isConstantStride();
+    }
+
+    @Override
+    public long constantInit() {
+        return base.constantInit() * scale.asConstant().asLong();
+    }
+
+    @Override
+    public long constantStride() {
+        return base.constantStride() * scale.asConstant().asLong();
+    }
+
+    @Override
+    public ValueNode extremumNode() {
+        return IntegerArithmeticNode.mul(base.extremumNode(), scale);
+    }
+
+    @Override
+    public boolean isConstantExtremum() {
+        return scale.isConstant() && base.isConstantExtremum();
+    }
+
+    @Override
+    public long constantExtremum() {
+        return base.constantExtremum() * scale.asConstant().asLong();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/InductionVariable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+
+
+public abstract class InductionVariable {
+    public enum Direction {
+        Up,
+        Down;
+        public Direction opposite() {
+            switch(this) {
+                case Up: return Down;
+                case Down: return Up;
+                default: throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    protected final LoopEx loop;
+
+    public InductionVariable(LoopEx loop) {
+        this.loop = loop;
+    }
+
+    public abstract Direction direction();
+
+    public abstract ValueNode valueNode();
+
+    public abstract ValueNode initNode();
+    public abstract ValueNode strideNode();
+
+    public abstract boolean isConstantInit();
+    public abstract boolean isConstantStride();
+
+    public abstract long constantInit();
+    public abstract long constantStride();
+
+    public abstract ValueNode extremumNode();
+    public abstract boolean isConstantExtremum();
+    public abstract long constantExtremum();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/InductionVariables.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+
+
+public class InductionVariables {
+    private final LoopEx loop;
+    private Map<Node, InductionVariable> ivs;
+
+    public InductionVariables(LoopEx loop) {
+        this.loop = loop;
+        ivs = new IdentityHashMap<>();
+        findDerived(findBasic());
+    }
+
+    public InductionVariable get(ValueNode v) {
+        return ivs.get(v);
+    }
+
+    private Collection<BasicInductionVariable> findBasic() {
+        List<BasicInductionVariable> bivs = new LinkedList<>();
+        LoopBeginNode loopBegin = loop.loopBegin();
+        EndNode forwardEnd = loopBegin.forwardEnd();
+        for (PhiNode phi : loopBegin.phis()) {
+            ValueNode backValue = phi.singleBackValue();
+            if (backValue == null) {
+                continue;
+            }
+            ValueNode stride = addSub(backValue, phi);
+            if (stride != null) {
+                BasicInductionVariable biv = new BasicInductionVariable(loop, phi, phi.valueAt(forwardEnd), stride, (IntegerArithmeticNode) backValue);
+                ivs.put(phi, biv);
+                bivs.add(biv);
+            }
+        }
+        return bivs;
+    }
+
+    private void findDerived(Collection<BasicInductionVariable> bivs) {
+        Queue<InductionVariable> scanQueue = new LinkedList<InductionVariable>(bivs);
+        while (!scanQueue.isEmpty()) {
+            InductionVariable baseIv = scanQueue.remove();
+            ValueNode baseIvNode = baseIv.valueNode();
+            for (ValueNode op : baseIvNode.usages().filter(ValueNode.class)) {
+                if (loop.isOutsideLoop(op)) {
+                    continue;
+                }
+                InductionVariable iv = null;
+                ValueNode offset = addSub(op, baseIvNode);
+                ValueNode scale;
+                if (offset != null) {
+                    iv = new DerivedOffsetInductionVariable(loop, baseIv, offset, (IntegerArithmeticNode) op);
+                } else if (op instanceof NegateNode) {
+                    iv = new DerivedScaledInductionVariable(loop, baseIv, (NegateNode) op);
+                } else if ((scale = mul(op, baseIvNode)) != null) {
+                    iv = new DerivedScaledInductionVariable(loop, baseIv, scale, op);
+                }
+
+                if (iv != null) {
+                    ivs.put(op, iv);
+                    scanQueue.offer(iv);
+                }
+            }
+        }
+    }
+
+    private ValueNode addSub(ValueNode op, ValueNode base) {
+        if (op instanceof IntegerAddNode || op instanceof IntegerSubNode) {
+            IntegerArithmeticNode aritOp = (IntegerArithmeticNode) op;
+            if (aritOp.x() == base && loop.isOutsideLoop(aritOp.y())) {
+                return aritOp.y();
+            } else if (aritOp.y() == base && loop.isOutsideLoop(aritOp.x())) {
+                return aritOp.x();
+            }
+        }
+        return null;
+    }
+
+    private ValueNode mul(ValueNode op, ValueNode base) {
+        if (op instanceof IntegerMulNode) {
+            IntegerMulNode mul = (IntegerMulNode) op;
+            if (mul.x() == base && loop.isOutsideLoop(mul.y())) {
+                return mul.y();
+            } else if (mul.y() == base && loop.isOutsideLoop(mul.x())) {
+                return mul.x();
+            }
+        }
+        if (op instanceof LeftShiftNode) {
+            LeftShiftNode shift = (LeftShiftNode) op;
+            if (shift.x() == base && shift.y().isConstant()) {
+                return ConstantNode.forInt(1 << shift.y().asConstant().asInt(), base.graph());
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopEx.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.lir.cfg.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+
+public class LoopEx {
+    private final Loop lirLoop;
+    private LoopFragmentInside inside;
+    private LoopFragmentWhole whole;
+    private CountedLoopInfo counted; //TODO (gd) detect
+    private LoopsData data;
+
+    LoopEx(Loop lirLoop, LoopsData data) {
+        this.lirLoop = lirLoop;
+        this.data = data;
+    }
+
+    public Loop lirLoop() {
+        return lirLoop;
+    }
+
+    public LoopFragmentInside inside() {
+        if (inside == null) {
+            inside = new LoopFragmentInside(this);
+        }
+        return inside;
+    }
+
+    public LoopFragmentWhole whole() {
+        if (whole == null) {
+            whole = new LoopFragmentWhole(this);
+        }
+        return whole;
+    }
+
+    @SuppressWarnings("unused")
+    public LoopFragmentInsideFrom insideFrom(FixedNode point) {
+        // TODO (gd)
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    public LoopFragmentInsideBefore insideBefore(FixedNode point) {
+        // TODO (gd)
+        return null;
+    }
+
+    public boolean isOutsideLoop(Node n) {
+        return !whole().contains(n);
+    }
+
+    public LoopBeginNode loopBegin() {
+        return lirLoop().loopBegin();
+    }
+
+    public FixedNode predecessor() {
+        return (FixedNode) loopBegin().forwardEnd().predecessor();
+    }
+
+    public FixedNode entryPoint() {
+        return loopBegin().forwardEnd();
+    }
+
+    public boolean isCounted() {
+        return counted != null;
+    }
+
+    public CountedLoopInfo counted() {
+        return counted;
+    }
+
+    public LoopEx parent() {
+        if (lirLoop.parent == null) {
+            return null;
+        }
+        return data.loop(lirLoop.parent);
+    }
+
+    public int size() {
+        return whole().nodes().count();
+    }
+
+    @Override
+    public String toString() {
+        return (isCounted() ? "CountedLoop [" + counted() + "] " : "Loop ") + "(depth=" + lirLoop().depth + ") " + loopBegin();
+    }
+
+    private class InvariantPredicate extends NodePredicate {
+        @Override
+        public boolean apply(Node n) {
+            return isOutsideLoop(n);
+        }
+    }
+
+    public void reassociateInvariants() {
+        InvariantPredicate invariant = new InvariantPredicate();
+        StructuredGraph graph = (StructuredGraph) loopBegin().graph();
+        for (BinaryNode binary : whole().nodes().filter(BinaryNode.class)) {
+            if (!BinaryNode.canTryReassociate(binary)) {
+                continue;
+            }
+            BinaryNode result = BinaryNode.reassociate(binary, invariant);
+            if (result != binary) {
+                Debug.log(CodeUtil.format("%H::%n", Debug.contextLookup(ResolvedJavaMethod.class)) + " : Reassociated %s into %s", binary, result);
+                graph.replaceFloating(binary, result);
+            }
+        }
+    }
+
+    public void setCounted(CountedLoopInfo countedLoopInfo) {
+        counted = countedLoopInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Graph.DuplicationReplacement;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.lir.cfg.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.PhiNode.PhiType;
+
+
+public abstract class LoopFragment {
+    private final LoopEx loop;
+    private final LoopFragment original;
+    protected NodeBitMap nodes;
+    protected boolean nodesReady;
+    private Map<Node, Node> duplicationMap;
+
+    public LoopFragment(LoopEx loop) {
+        this(loop, null);
+        this.nodesReady = true;
+    }
+
+    public LoopFragment(LoopEx loop, LoopFragment original) {
+        this.loop = loop;
+        this.original = original;
+        this.nodesReady = false;
+    }
+
+    public LoopEx loop() {
+        return loop;
+    }
+
+    public abstract LoopFragment duplicate();
+
+    public abstract void insertBefore(LoopEx l);
+
+    public void disconnect() {
+        // TODO (gd) possibly abstract
+    }
+
+    public boolean contains(Node n) {
+        return nodes().contains(n);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <New extends Node, Old extends New> New getDuplicatedNode(Old n) {
+        assert isDuplicate();
+        return (New) duplicationMap.get(n);
+    }
+
+    protected <New extends Node, Old extends New> void putDuplicatedNode(Old oldNode, New newNode) {
+        duplicationMap.put(oldNode, newNode);
+    }
+
+    public boolean isDuplicate() {
+        return original != null;
+    }
+
+    public LoopFragment original() {
+        return original;
+    }
+
+    public abstract NodeIterable<Node> nodes();
+
+    public StructuredGraph graph() {
+        return (StructuredGraph) loop.loopBegin().graph();
+    }
+
+    protected abstract DuplicationReplacement getDuplicationReplacement();
+
+    protected abstract void finishDuplication();
+
+    protected void patchNodes(final DuplicationReplacement dataFix) {
+        if (isDuplicate() && !nodesReady) {
+            assert !original.isDuplicate();
+            final DuplicationReplacement cfgFix = getDuplicationReplacement();
+            DuplicationReplacement dr;
+            if (cfgFix == null) {
+                dr = dataFix;
+            } else {
+                dr = new DuplicationReplacement() {
+                    @Override
+                    public Node replacement(Node o) {
+                        Node r1 = dataFix.replacement(o);
+                        if (r1 != o) {
+                            assert cfgFix.replacement(o) == o;
+                            return r1;
+                        }
+                        Node r2 = cfgFix.replacement(o);
+                        if (r2 != o) {
+                            return r2;
+                        }
+                        return o;
+                    }
+                };
+            }
+            duplicationMap = graph().addDuplicates(nodes(), dr);
+            finishDuplication();
+            nodesReady = true;
+        } else {
+            //TODO (gd) apply fix ?
+        }
+    }
+
+    public static Collection<BeginNode> toHirBlocks(Collection<Block> blocks) {
+        List<BeginNode> hir = new ArrayList<>(blocks.size());
+        for (Block b : blocks) {
+            hir.add(b.getBeginNode());
+        }
+        return hir;
+    }
+
+    protected static NodeBitMap computeNodes(Graph graph, Collection<BeginNode> blocks) {
+        return computeNodes(graph, blocks, Collections.<BeginNode>emptyList());
+    }
+
+    protected static NodeBitMap computeNodes(Graph graph, Collection<BeginNode> blocks, Collection<BeginNode> earlyExits) {
+        NodeBitMap nodes = graph.createNodeBitMap(true);
+        for (BeginNode b : blocks) {
+            for (Node n : b.getBlockNodes()) {
+                if (n instanceof Invoke) {
+                    nodes.mark(((Invoke) n).callTarget());
+                }
+                if (n instanceof StateSplit) {
+                    FrameState stateAfter = ((StateSplit) n).stateAfter();
+                    if (stateAfter != null) {
+                        nodes.mark(stateAfter);
+                    }
+                }
+                nodes.mark(n);
+            }
+        }
+        for (BeginNode earlyExit : earlyExits) {
+            FrameState stateAfter = earlyExit.stateAfter();
+            if (stateAfter != null) {
+                nodes.mark(stateAfter);
+            }
+            nodes.mark(earlyExit);
+            for (ValueProxyNode proxy : earlyExit.proxies()) {
+                nodes.mark(proxy);
+            }
+        }
+
+        for (BeginNode b : blocks) {
+            for (Node n : b.getBlockNodes()) {
+                for (Node usage : n.usages()) {
+                    markFloating(usage, nodes);
+                }
+            }
+        }
+
+        return nodes;
+    }
+
+    private static boolean markFloating(Node n, NodeBitMap loopNodes) {
+        if (loopNodes.isMarked(n)) {
+            return true;
+        }
+        if (n instanceof FixedNode) {
+            return false;
+        }
+        boolean mark = false;
+        if (n instanceof PhiNode) {
+            PhiNode phi = (PhiNode) n;
+            mark = loopNodes.isMarked(phi.merge());
+            if (mark) {
+                loopNodes.mark(n);
+            } else {
+                return false;
+            }
+        }
+        for (Node usage : n.usages()) {
+            if (markFloating(usage, loopNodes)) {
+                mark = true;
+            }
+        }
+        if (mark) {
+            loopNodes.mark(n);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Merges the early exits (i.e. loop exits) that were duplicated as part of this fragment, with the original fragment's exits.
+     */
+    protected void mergeEarlyExits() {
+        assert isDuplicate();
+        StructuredGraph graph = graph();
+        for (BeginNode earlyExit : toHirBlocks(original().loop().lirLoop().exits)) {
+            FixedNode next = earlyExit.next();
+            if (earlyExit.isDeleted() || !this.contains(earlyExit)) {
+                continue;
+            }
+            BeginNode newEarlyExit = getDuplicatedNode(earlyExit);
+            assert newEarlyExit != null;
+            MergeNode merge = graph.add(new MergeNode());
+            merge.setProbability(next.probability());
+            EndNode originalEnd = graph.add(new EndNode());
+            EndNode newEnd = graph.add(new EndNode());
+            merge.addForwardEnd(originalEnd);
+            merge.addForwardEnd(newEnd);
+            earlyExit.setNext(originalEnd);
+            newEarlyExit.setNext(newEnd);
+            merge.setNext(next);
+
+            FrameState exitState = earlyExit.stateAfter();
+            FrameState state = null;
+            if (exitState != null) {
+                state = exitState.duplicate();
+                merge.setStateAfter(state);
+            }
+
+            for (Node anchored : earlyExit.anchored().snapshot()) {
+                anchored.replaceFirstInput(earlyExit, merge);
+            }
+
+            for (ValueProxyNode vpn : earlyExit.proxies().snapshot()) {
+                ValueNode replaceWith;
+                ValueProxyNode newVpn = getDuplicatedNode(vpn);
+                if (newVpn != null) {
+                    PhiNode phi = graph.add(vpn.type() == PhiType.Value ? new PhiNode(vpn.kind(), merge) : new PhiNode(vpn.type(), merge));
+                    phi.addInput(vpn);
+                    phi.addInput(newVpn);
+                    replaceWith = phi;
+                } else {
+                    replaceWith = vpn.value();
+                }
+                if (state != null) {
+                    state.replaceFirstInput(vpn, replaceWith);
+                }
+                for (Node usage : vpn.usages().snapshot()) {
+                    if (usage != exitState && !merge.isPhiAtMerge(usage)) {
+                        usage.replaceFirstInput(vpn, replaceWith);
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import java.util.*;
+
+import com.oracle.graal.graph.Graph.DuplicationReplacement;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.PhiNode.PhiType;
+import com.oracle.graal.nodes.VirtualState.NodeClosure;
+import com.oracle.graal.nodes.util.*;
+
+
+public class LoopFragmentInside extends LoopFragment {
+    /** mergedInitializers.
+     * When an inside fragment's (loop)ends are merged to create a unique exit point,
+     * some phis must be created : they phis together all the back-values of the loop-phis
+     * These can then be used to update the loop-phis' forward edge value ('initializer') in the peeling case.
+     * In the unrolling case they will be used as the value that replace the loop-phis of the duplicated inside fragment
+     */
+    private Map<PhiNode, ValueNode> mergedInitializers;
+    private final DuplicationReplacement dataFix = new DuplicationReplacement() {
+        @Override
+        public Node replacement(Node oriInput) {
+            if (!(oriInput instanceof ValueNode)) {
+                return oriInput;
+            }
+            return prim((ValueNode) oriInput);
+        }
+    };
+
+    public LoopFragmentInside(LoopEx loop) {
+        super(loop);
+    }
+
+    public LoopFragmentInside(LoopFragmentInside original) {
+        super(original.loop(), original);
+    }
+
+    @Override
+    public LoopFragmentInside duplicate() {
+        assert !isDuplicate();
+        return new LoopFragmentInside(this);
+    }
+
+    @Override
+    public LoopFragmentInside original() {
+        return (LoopFragmentInside) super.original();
+    }
+
+    @SuppressWarnings("unused")
+    public void appendInside(LoopEx loop) {
+        // TODO (gd)
+    }
+
+    @Override
+    public void insertBefore(LoopEx loop) {
+        if (this.loop() != loop) {
+            throw new UnsupportedOperationException();
+        }
+        patchNodes(dataFix);
+
+        BeginNode end = mergeEnds();
+
+        original().patchPeeling(this);
+
+        mergeEarlyExits();
+
+        BeginNode entry = getDuplicatedNode(this.loop().loopBegin());
+        FrameState state = entry.stateAfter();
+        if (state != null) {
+            entry.setStateAfter(null);
+            GraphUtil.killWithUnusedFloatingInputs(state);
+        }
+        loop.entryPoint().replaceAtPredecessor(entry);
+        end.setProbability(loop.entryPoint().probability());
+        end.setNext(loop.entryPoint());
+    }
+
+    @Override
+    public NodeIterable<Node> nodes() {
+        if (nodes == null) {
+            LoopFragmentWhole whole = loop().whole();
+            whole.nodes(); // init nodes bitmap in whole
+            nodes = whole.nodes.copy();
+            // remove the phis
+            for (PhiNode phi : loop().loopBegin().phis()) {
+                nodes.clear(phi);
+            }
+        }
+        return nodes;
+    }
+
+    @Override
+    protected DuplicationReplacement getDuplicationReplacement() {
+        final LoopBeginNode loopBegin = loop().loopBegin();
+        final StructuredGraph graph = graph();
+        return new DuplicationReplacement() {
+            @Override
+            public Node replacement(Node original) {
+                if (original == loopBegin) {
+                    return graph.add(new BeginNode());
+                }
+                if (original instanceof LoopExitNode && ((LoopExitNode) original).loopBegin() == loopBegin) {
+                    return graph.add(new BeginNode());
+                }
+                if (original instanceof LoopEndNode && ((LoopEndNode) original).loopBegin() == loopBegin) {
+                    return graph.add(new EndNode());
+                }
+                return original;
+            }
+        };
+    }
+
+    @Override
+    protected void finishDuplication() {
+        // TODO (gd) ?
+
+    }
+
+    private void patchPeeling(LoopFragmentInside peel) {
+        LoopBeginNode loopBegin = loop().loopBegin();
+        StructuredGraph graph = (StructuredGraph) loopBegin.graph();
+        List<PhiNode> newPhis = new LinkedList<>();
+        for (PhiNode phi : loopBegin.phis().snapshot()) {
+            ValueNode first;
+            if (loopBegin.loopEnds().count() == 1) {
+                ValueNode b = phi.valueAt(loopBegin.loopEnds().first()); // back edge value
+                first = peel.prim(b); // corresponding value in the peel
+            } else {
+                first = peel.mergedInitializers.get(phi);
+            }
+            // create a new phi (we don't patch the old one since some usages of the old one may still be valid)
+            PhiNode newPhi = graph.add(phi.type() == PhiType.Value ? new PhiNode(phi.kind(), loopBegin) : new PhiNode(phi.type(), loopBegin));
+            newPhi.addInput(first);
+            for (LoopEndNode end : loopBegin.orderedLoopEnds()) {
+                newPhi.addInput(phi.valueAt(end));
+            }
+            peel.putDuplicatedNode(phi, newPhi);
+            newPhis.add(newPhi);
+            for (Node usage : phi.usages().snapshot()) {
+                if (peel.getDuplicatedNode(usage) != null) { // patch only usages that should use the new phi ie usages that were peeled
+                    usage.replaceFirstInput(phi, newPhi);
+                }
+            }
+        }
+        // check new phis to see if they have as input some old phis, replace those inputs with the new corresponding phis
+        for (PhiNode phi : newPhis) {
+            for (int i = 0; i < phi.valueCount(); i++) {
+                ValueNode v = phi.valueAt(i);
+                if (loopBegin.isPhiAtMerge(v)) {
+                    PhiNode newV = peel.getDuplicatedNode((PhiNode) v);
+                    if (newV != null) {
+                        phi.setValueAt(i, newV);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the corresponding value in this fragment.
+     * @param peel the peel to look into
+     * @param b original value
+     * @return corresponding value in the peel
+     */
+    private ValueNode prim(ValueNode b) {
+        LoopBeginNode loopBegin = loop().loopBegin();
+        if (loopBegin.isPhiAtMerge(b)) {
+            PhiNode phi = (PhiNode) b;
+            return phi.valueAt(loopBegin.forwardEnd());
+        } else if (nodesReady) {
+            ValueNode v = getDuplicatedNode(b);
+            if (v == null) {
+                return b;
+            }
+            return v;
+        } else {
+            return b;
+        }
+    }
+
+    private BeginNode mergeEnds() {
+        List<EndNode> endsToMerge = new LinkedList<>();
+        Map<EndNode, LoopEndNode> reverseEnds = new HashMap<>(); // map peel's exit to the corresponding loop exits
+        LoopBeginNode loopBegin = loop().loopBegin();
+        for (LoopEndNode le : loopBegin.loopEnds()) {
+            EndNode duplicate = getDuplicatedNode(le);
+            if (duplicate != null) {
+                endsToMerge.add(duplicate);
+                reverseEnds.put(duplicate, le);
+            }
+        }
+        mergedInitializers = new IdentityHashMap<>();
+        BeginNode newExit;
+        StructuredGraph graph = graph();
+        if (endsToMerge.size() == 1) {
+            EndNode end = endsToMerge.get(0);
+            assert end.usages().count() == 0;
+            newExit = graph.add(new BeginNode());
+            end.replaceAtPredecessor(newExit);
+            end.safeDelete();
+        } else {
+            assert endsToMerge.size() > 1;
+            MergeNode newExitMerge = graph.add(new MergeNode());
+            newExit = newExitMerge;
+            FrameState state = loopBegin.stateAfter();
+            FrameState duplicateState = null;
+            if (state != null) {
+                duplicateState = state.duplicate();
+                newExitMerge.setStateAfter(duplicateState);
+            }
+            for (EndNode end : endsToMerge) {
+                newExitMerge.addForwardEnd(end);
+            }
+
+            for (final PhiNode phi : loopBegin.phis().snapshot()) {
+                final PhiNode firstPhi = graph.add(phi.type() == PhiType.Value ? new PhiNode(phi.kind(), newExitMerge) : new PhiNode(phi.type(), newExitMerge));
+                for (EndNode end : newExitMerge.forwardEnds()) {
+                    LoopEndNode loopEnd = reverseEnds.get(end);
+                    ValueNode prim = prim(phi.valueAt(loopEnd));
+                    assert prim != null;
+                    firstPhi.addInput(prim);
+                }
+                ValueNode initializer = firstPhi;
+                if (duplicateState != null) {
+                    // fix the merge's state after
+                    duplicateState.applyToNonVirtual(new NodeClosure<ValueNode>() {
+                        @Override
+                        public void apply(Node from, ValueNode node) {
+                            if (node == phi) {
+                                from.replaceFirstInput(phi, firstPhi);
+                            }
+                        }
+                    });
+                }
+                mergedInitializers.put(phi, initializer);
+            }
+        }
+        return newExit;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInsideBefore.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.*;
+
+
+public class LoopFragmentInsideBefore extends LoopFragmentInside {
+    private final FixedNode point;
+
+    public LoopFragmentInsideBefore(LoopEx loop, FixedNode point) {
+        super(loop);
+        this.point = point;
+    }
+
+    // duplicates lazily
+    public LoopFragmentInsideBefore(LoopFragmentInsideBefore original) {
+        super(original);
+        this.point = original.point();
+    }
+
+    public FixedNode point() {
+        return point;
+    }
+
+    @Override
+    public LoopFragmentInsideBefore duplicate() {
+        return new LoopFragmentInsideBefore(this);
+    }
+
+    @Override
+    public NodeIterable<Node> nodes() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInsideFrom.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.*;
+
+
+public class LoopFragmentInsideFrom extends LoopFragmentInside {
+    private final FixedNode point;
+
+    public LoopFragmentInsideFrom(LoopEx loop, FixedNode point) {
+        super(loop);
+        this.point = point;
+    }
+
+    // duplicates lazily
+    public LoopFragmentInsideFrom(LoopFragmentInsideFrom original) {
+        super(original);
+        this.point = original.point();
+    }
+
+    public FixedNode point() {
+        return point;
+    }
+
+    @Override
+    public LoopFragmentInsideFrom duplicate() {
+        return new LoopFragmentInsideFrom(this);
+    }
+
+    @Override
+    public NodeIterable<Node> nodes() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Graph.DuplicationReplacement;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.lir.cfg.*;
+
+
+public class LoopFragmentWhole extends LoopFragment {
+
+    public LoopFragmentWhole(LoopEx loop) {
+        super(loop);
+    }
+
+    @Override
+    public LoopFragmentWhole duplicate() {
+        // TODO (gd) do not forget to make a FULL loop : do not forget the forward end which is not part of the original loop stricto sensus
+        return null;
+    }
+
+    @Override
+    public NodeIterable<Node> nodes() {
+        if (nodes == null) {
+            Loop lirLoop = loop().lirLoop();
+            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.blocks), LoopFragment.toHirBlocks(lirLoop.exits));
+        }
+        return nodes;
+    }
+
+    @Override
+    protected DuplicationReplacement getDuplicationReplacement() {
+        return null;
+    }
+
+    @Override
+    protected void finishDuplication() {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void insertBefore(LoopEx loop) {
+        // TODO Auto-generated method stub
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopPolicies.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.nodes.*;
+
+
+public abstract class LoopPolicies {
+    private LoopPolicies() {
+        // does not need to be instantiated
+    }
+
+    // TODO (gd) change when inversion is available
+    public static boolean shouldPeel(LoopEx loop) {
+        LoopBeginNode loopBegin = loop.loopBegin();
+        double entryProbability = loopBegin.forwardEnd().probability();
+        return entryProbability > GraalOptions.MinimumPeelProbability && loop.size() + loopBegin.graph().getNodeCount() < GraalOptions.MaximumDesiredSize;
+    }
+
+    public static boolean shouldFullUnroll(LoopEx loop) {
+        if (!loop.isCounted() || !loop.counted().isConstantMaxTripCount()) {
+            return false;
+        }
+        long exactTrips = loop.counted().constantMaxTripCount();
+        int maxNodes = Math.min(GraalOptions.FullUnrollMaxNodes, GraalOptions.MaximumDesiredSize - loop.loopBegin().graph().getNodeCount());
+        int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
+        return size * exactTrips <= maxNodes;
+    }
+
+    public static boolean shouldTryUnswitch(@SuppressWarnings("unused") LoopEx loop) {
+        // TODO (gd) maybe there should be a may number of unswitching per loop
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformDataResolver.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 2012, 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.compiler.loop;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.NodeClass.NodeClassIterator;
-import com.oracle.graal.graph.NodeClass.Position;
-import com.oracle.graal.nodes.*;
-
-
-
-public class LoopTransformDataResolver {
-    private List<ResolvableSuperBlock> resolvables = new LinkedList<>();
-
-    private abstract static class ResolvableSuperBlock {
-        final SuperBlock block;
-        public ResolvableSuperBlock(SuperBlock block) {
-            this.block = block;
-        }
-        public abstract void resolve();
-    }
-
-    private static class PeeledResolvableSuperBlock extends ResolvableSuperBlock{
-        final SuperBlock peel;
-        final boolean nextIteration;
-        public PeeledResolvableSuperBlock(SuperBlock peeled, SuperBlock peel, boolean nextIteration) {
-            super(peeled);
-            this.peel = peel;
-            this.nextIteration = nextIteration;
-        }
-        @Override
-        public void resolve() {
-            if (nextIteration) {
-                SuperBlock peeled = block;
-                LoopBeginNode loopBegin = (LoopBeginNode) peeled.getEntry();
-                Map<Node, Node> dup = peel.getDuplicationMapping();
-                List<PhiNode> newPhis = new LinkedList<>();
-                for (PhiNode phi : loopBegin.phis().snapshot()) {
-                    ValueNode first = null;
-                    if (loopBegin.loopEnds().count() == 1) {
-                        ValueNode b = phi.valueAt(loopBegin.loopEnds().first()); // back edge value
-                        first = prim(b); // corresponding value in the peel
-                    } else {
-                        Map<EndNode, LoopEndNode> reverseEnds = new HashMap<>(); // map peel's exit to the corresponding loop exits
-                        MergeNode merge = null; // look for the merge if the peel's exits
-                        for (LoopEndNode end : loopBegin.loopEnds()) {
-                            EndNode newEnd = (EndNode) dup.get(end);
-                            if (newEnd != null) {
-                                reverseEnds.put(newEnd, end);
-                                if (prim(phi.valueAt(end)) != null) {
-                                    merge = newEnd.merge();
-                                }
-                            }
-                        }
-                        if (merge != null) { // found values of interest (backedge values that exist in the peel)
-                            PhiNode firstPhi = loopBegin.graph().add(new PhiNode(phi.kind(), merge, phi.type()));
-                            for (EndNode end : merge.forwardEnds()) {
-                                LoopEndNode loopEnd = reverseEnds.get(end);
-                                ValueNode prim = prim(phi.valueAt(loopEnd));
-                                assert prim != null;
-                                firstPhi.addInput(prim);
-                            }
-                            first = firstPhi;
-                            merge.stateAfter().replaceFirstInput(phi, firstPhi); // fix the merge's state after (see SuperBlock.mergeExits)
-                        }
-                    }
-                    if (first != null) { // create a new phi (we don't patch the old one since some usages of the old one may still be valid)
-                        PhiNode newPhi = loopBegin.graph().add(new PhiNode(phi.kind(), loopBegin, phi.type()));
-                        newPhi.addInput(first);
-                        for (LoopEndNode end : loopBegin.orderedLoopEnds()) {
-                            newPhi.addInput(phi.valueAt(end));
-                        }
-                        dup.put(phi, newPhi);
-                        newPhis.add(newPhi);
-                        for (Node usage : phi.usages().snapshot()) {
-                            if (dup.get(usage) != null) { // patch only usages that should use the new phi ie usages that were peeled
-                                usage.replaceFirstInput(phi, newPhi);
-                            }
-                        }
-                    }
-                }
-                // check new phis to see if they have as input some old phis, replace those inputs with the new corresponding phis
-                for (PhiNode phi : newPhis) {
-                    for (int i = 0; i < phi.valueCount(); i++) {
-                        ValueNode v = phi.valueAt(i);
-                        if (loopBegin.isPhiAtMerge(v)) {
-                            PhiNode newV = (PhiNode) dup.get(v);
-                            if (newV != null) {
-                                phi.setValueAt(i, newV);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        /**
-         * Gets the corresponding value in the peel.
-         * @param b original value
-         * @return corresponding value in the peel
-         */
-        public ValueNode prim(ValueNode b) {
-            SuperBlock peeled = block;
-            LoopBeginNode loopBegin = (LoopBeginNode) peeled.getEntry();
-            Map<Node, Node> dup = peel.getDuplicationMapping();
-            if (loopBegin.isPhiAtMerge(b)) {
-                PhiNode phi = (PhiNode) b;
-                return phi.valueAt(loopBegin.forwardEnd());
-            } else {
-                ValueNode v = (ValueNode) dup.get(b);
-                if (v == null && nextIteration) {
-                    // may not be right in inversion case
-                    return b;
-                }
-                return v;
-            }
-        }
-    }
-
-    private static class PeelResolvableSuperBlock extends ResolvableSuperBlock{
-        final SuperBlock peeled;
-        public PeelResolvableSuperBlock(SuperBlock peel, SuperBlock peeled) {
-            super(peel);
-            this.peeled = peeled;
-        }
-        @Override
-        public void resolve() {
-            SuperBlock peel = block;
-            LoopBeginNode loopBegin = (LoopBeginNode) peeled.getEntry();
-            for (Entry<Node, Node> entry : peel.getDuplicationMapping().entrySet()) {
-                Node oriNode = entry.getKey();
-                Node newNode = entry.getValue();
-                for (NodeClassIterator iter = oriNode.inputs().iterator(); iter.hasNext();) {
-                    Position pos = iter.nextPosition();
-                    if (pos.isValidFor(newNode, oriNode) && pos.get(newNode) == null) {
-                        Node oriInput = pos.get(oriNode);
-                        // oriInput is not checked against null because oriNode.inputs().iterator() only iterates over non-null pos/input
-                        Node v;
-                        if (loopBegin.isPhiAtMerge(oriInput)) {
-                            PhiNode phi = (PhiNode) oriInput;
-                            v = phi.valueAt(loopBegin.forwardEnd());
-                        } else {
-                            v = oriInput;
-                        }
-                        pos.set(newNode, v);
-                    }
-                }
-            }
-        }
-    }
-
-    public class WholeLoop {
-        private final SuperBlock from;
-        public WholeLoop(SuperBlock from) {
-            this.from = from;
-        }
-        public void peeled(SuperBlock peel) {
-            resolvables.add(new PeelResolvableSuperBlock(peel, from));
-            resolvables.add(new PeeledResolvableSuperBlock(from, peel, true));
-        }
-
-    }
-
-    public void resolve() {
-        for (ResolvableSuperBlock resolvable : this.resolvables) {
-            resolvable.resolve();
-        }
-    }
-
-    public WholeLoop wholeLoop(SuperBlock block) {
-        return new WholeLoop(block);
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2012, 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.compiler.loop;
-
-import java.util.*;
-
-import com.oracle.graal.lir.cfg.*;
-import com.oracle.graal.nodes.*;
-
-
-public class LoopTransformUtil {
-
-    public static void peel(Loop loop) {
-        peel(loop, wholeLoop(loop));
-    }
-
-    public static void peel(Loop loop, SuperBlock wholeLoop) {
-        SuperBlock peel = wholeLoop.duplicate(); // duplicates the nodes, merges early exits
-
-        peel.insertBefore(loop.loopBegin().forwardEnd()); // connects peeled part's CFG
-
-        LoopTransformDataResolver resolver = new LoopTransformDataResolver();
-        resolver.wholeLoop(wholeLoop).peeled(peel); // block (comming from the loop) was peeled into peel
-        resolver.resolve();
-
-        peel.finish();
-    }
-
-    public static SuperBlock wholeLoop(Loop loop) {
-        List<BeginNode> blocks = new LinkedList<>();
-        List<BeginNode> earlyExits = new LinkedList<>();
-        for (Block b : loop.blocks) {
-            blocks.add(b.getBeginNode());
-        }
-        for (Block b : loop.exits) {
-            earlyExits.add(b.getBeginNode());
-        }
-        return new SuperBlock(loop.loopBegin(), loop.loopBegin(), blocks, earlyExits, loop.loopBegin());
-    }
-
-    public static int estimateSize(Loop loop) {
-        int fixed = 0;
-        for (Block b : loop.blocks) {
-            fixed += b.getBeginNode().getBlockNodes().count();
-        }
-        return fixed * 3;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.nodes.*;
+
+
+public abstract class LoopTransformations {
+    private static final int UNROLL_LIMIT = GraalOptions.FullUnrollMaxNodes * 2;
+
+    private LoopTransformations() {
+        // does not need to be instantiated
+    }
+
+    public static void invert(LoopEx loop, FixedNode point) {
+        LoopFragmentInsideBefore head = loop.insideBefore(point);
+        LoopFragmentInsideBefore duplicate = head.duplicate();
+        head.disconnect();
+        head.insertBefore(loop);
+        duplicate.appendInside(loop);
+    }
+
+    public static void peel(LoopEx loop) {
+        loop.inside().duplicate().insertBefore(loop);
+    }
+
+    public static void fullUnroll(LoopEx loop, CodeCacheProvider runtime) {
+        //assert loop.isCounted(); //TODO (gd) strenghten : counted with known trip count
+        int iterations = 0;
+        LoopBeginNode loopBegin = loop.loopBegin();
+        StructuredGraph graph = (StructuredGraph) loopBegin.graph();
+        while (!loopBegin.isDeleted()) {
+            int mark = graph.getMark();
+            peel(loop);
+            new CanonicalizerPhase(null, runtime, null, mark, null).apply(graph);
+            if (iterations++ > UNROLL_LIMIT || graph.getNodeCount() > GraalOptions.MaximumDesiredSize * 3) {
+                throw new BailoutException("FullUnroll : Graph seems to grow out of proportion");
+            }
+        }
+    }
+
+    public static void unswitch(LoopEx loop, IfNode ifNode) {
+        // duplicate will be true case, original will be false case
+        LoopFragmentWhole duplicateLoop = loop.whole().duplicate();
+        StructuredGraph graph = (StructuredGraph) ifNode.graph();
+        BeginNode tempBegin = graph.add(new BeginNode());
+        loop.entryPoint().replaceAtPredecessor(tempBegin);
+        double takenProbability = ifNode.probability(ifNode.blockSuccessorIndex(ifNode.trueSuccessor()));
+        IfNode newIf = graph.add(new IfNode(ifNode.compare(), duplicateLoop.loop().entryPoint(), loop.entryPoint(), takenProbability, ifNode.leafGraphId()));
+        tempBegin.setNext(newIf);
+        ifNode.setCompare(graph.unique(ConstantNode.forBoolean(false, graph)));
+        IfNode duplicateIf = duplicateLoop.getDuplicatedNode(ifNode);
+        duplicateIf.setCompare(graph.unique(ConstantNode.forBoolean(true, graph)));
+        // TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms)
+    }
+
+    public static void unroll(LoopEx loop, int factor) {
+        assert loop.isCounted();
+        if (factor > 0) {
+            throw new UnsupportedOperationException();
+        }
+        // TODO (gd) implement counted loop
+        LoopFragmentWhole main = loop.whole();
+        LoopFragmentWhole prologue = main.duplicate();
+        prologue.insertBefore(loop);
+        //CountedLoopBeginNode counted = prologue.countedLoop();
+        //StructuredGraph graph = (StructuredGraph) counted.graph();
+        //ValueNode tripCountPrologue = counted.tripCount();
+        //ValueNode tripCountMain = counted.tripCount();
+        //graph.replaceFloating(tripCountPrologue, "tripCountPrologue % factor");
+        //graph.replaceFloating(tripCountMain, "tripCountMain - (tripCountPrologue % factor)");
+        LoopFragmentInside inside = loop.inside();
+        for (int i = 0; i < factor; i++) {
+            inside.duplicate().appendInside(loop);
+        }
+    }
+
+    public static IfNode findUnswitchableIf(LoopEx loop) {
+        for (IfNode ifNode : loop.whole().nodes().filter(IfNode.class)) {
+            if (loop.isOutsideLoop(ifNode.compare())) {
+                return ifNode;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopsData.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2012, 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.compiler.loop;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.compiler.loop.InductionVariable.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.lir.cfg.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+
+public class LoopsData {
+    private Map<Loop, LoopEx> lirLoopToEx = new IdentityHashMap<>();
+    private Map<LoopBeginNode, LoopEx> loopBeginToEx = new IdentityHashMap<>();
+
+    public LoopsData(final StructuredGraph graph) {
+
+        ControlFlowGraph cfg = Debug.scope("ControlFlowGraph", new Callable<ControlFlowGraph>() {
+            @Override
+            public ControlFlowGraph call() throws Exception {
+                return ControlFlowGraph.compute(graph, true, true, true, false);
+            }
+        });
+        for (Loop lirLoop : cfg.getLoops()) {
+            LoopEx ex = new LoopEx(lirLoop, this);
+            lirLoopToEx.put(lirLoop, ex);
+            loopBeginToEx.put(ex.loopBegin(), ex);
+        }
+    }
+
+    public LoopEx loop(Loop lirLoop) {
+        return lirLoopToEx.get(lirLoop);
+    }
+
+    public LoopEx loop(LoopBeginNode loopBegin) {
+        return loopBeginToEx.get(loopBegin);
+    }
+
+    public Collection<LoopEx> loops() {
+        return lirLoopToEx.values();
+    }
+
+    public List<LoopEx> outterFirst() {
+        ArrayList<LoopEx> loops = new ArrayList<>(loops());
+        Collections.sort(loops, new Comparator<LoopEx>() {
+            @Override
+            public int compare(LoopEx o1, LoopEx o2) {
+                return o1.lirLoop().depth - o2.lirLoop().depth;
+            }
+        });
+        return loops;
+    }
+
+    public Collection<LoopEx> countedLoops() {
+        List<LoopEx> counted = new LinkedList<>();
+        for (LoopEx loop : loops()) {
+            if (loop.isCounted()) {
+                counted.add(loop);
+            }
+        }
+        return counted;
+    }
+
+    public void detectedCountedLoops() {
+        for (LoopEx loop : loops()) {
+            InductionVariables ivs = new InductionVariables(loop);
+            LoopBeginNode loopBegin = loop.loopBegin();
+            FixedNode next = loopBegin.next();
+            if (next instanceof IfNode) {
+                IfNode ifNode = (IfNode) next;
+                boolean negated = false;
+                if (!loopBegin.isLoopExit(ifNode.falseSuccessor())) {
+                    if (!loopBegin.isLoopExit(ifNode.trueSuccessor())) {
+                        continue;
+                    }
+                    negated = true;
+                }
+                BooleanNode ifTest = ifNode.compare();
+                if (!(ifTest instanceof IntegerLessThanNode)) {
+                    if (ifTest instanceof IntegerBelowThanNode) {
+                        Debug.log("Ignored potential Counted loop at %s with |<|", loopBegin);
+                    }
+                    continue;
+                }
+                IntegerLessThanNode lessThan = (IntegerLessThanNode) ifTest;
+                Condition condition = null;
+                InductionVariable iv = null;
+                ValueNode limit = null;
+                if (loop.isOutsideLoop(lessThan.x())) {
+                    iv = ivs.get(lessThan.y());
+                    if (iv != null) {
+                        condition = lessThan.condition().mirror();
+                        limit = lessThan.x();
+                    }
+                } else if (loop.isOutsideLoop(lessThan.y())) {
+                    iv = ivs.get(lessThan.x());
+                    if (iv != null) {
+                        condition = lessThan.condition();
+                        limit = lessThan.y();
+                    }
+                }
+                if (condition == null) {
+                    continue;
+                }
+                if (negated) {
+                    condition = condition.negate();
+                }
+                boolean oneOff = false;
+                switch (condition) {
+                    case LE:
+                        oneOff = true; // fall through
+                    case LT:
+                        if (iv.direction() != Direction.Up) {
+                            continue;
+                        }
+                        break;
+                    case GE:
+                        oneOff = true; // fall through
+                    case GT:
+                        if (iv.direction() != Direction.Down) {
+                            continue;
+                        }
+                        break;
+                    default: throw GraalInternalError.shouldNotReachHere();
+                }
+                loop.setCounted(new CountedLoopInfo(loop, iv, limit, oneOff));
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/SuperBlock.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2012, 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.compiler.loop;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.nodes.virtual.*;
-
-public class SuperBlock {
-    protected BeginNode entry;
-    protected BeginNode exit;
-    protected List<BeginNode> blocks;
-    protected List<BeginNode> earlyExits;
-    protected LoopBeginNode loop;
-    protected Map<Node, Node> duplicationMapping;
-    protected SuperBlock original;
-    protected NodeBitMap loopNodes;
-
-    public SuperBlock(BeginNode entry, BeginNode exit, List<BeginNode> blocks, List<BeginNode> earlyExits, LoopBeginNode loop) {
-        this.entry = entry;
-        this.exit = exit;
-        this.blocks = blocks;
-        this.earlyExits = earlyExits;
-        this.loop = loop;
-        assert blocks.contains(entry);
-        assert !blocks.contains(exit) || exit == entry;
-    }
-
-    public Map<Node, Node> getDuplicationMapping() {
-        return duplicationMapping;
-    }
-
-    public BeginNode getEntry() {
-        return entry;
-    }
-
-    public NodeBitMap loopNodes() {
-        if (loopNodes == null) {
-            loopNodes = computeNodes();
-        }
-        return loopNodes;
-    }
-
-    public SuperBlock duplicate() {
-        NodeBitMap nodes = loopNodes();
-        Map<Node, Node> replacements = new HashMap<>();
-        StructuredGraph graph = (StructuredGraph) entry.graph();
-        BeginNode newEntry = graph.add(new BeginNode());
-        BeginNode newExit = null;
-        List<BeginNode> newEarlyExits = new ArrayList<>(earlyExits.size());
-        if (!(exit instanceof MergeNode)) {
-            newExit = graph.add(new BeginNode());
-            replacements.put(exit, newExit);
-        }
-        replacements.put(entry, newEntry); // no merge/loop begin
-        for (BeginNode earlyExit : earlyExits) {
-            BeginNode newEarlyExit = graph.add(new BeginNode());
-            newEarlyExits.add(newEarlyExit);
-            replacements.put(earlyExit, newEarlyExit);
-        }
-        if (loop != null) {
-            for (LoopEndNode end : loop.loopEnds()) {
-                if (nodes.isMarked(end)) {
-                    replacements.put(end, graph.add(new EndNode()));
-                }
-            }
-        }
-        Map<Node, Node> duplicates = graph.addDuplicates(nodes, replacements);
-        if (exit instanceof MergeNode) {
-            newExit = mergeExits(replacements, graph, duplicates, (MergeNode) exit);
-        }
-
-        List<BeginNode> newBlocks = new ArrayList<>(blocks.size());
-        for (BeginNode block : blocks) {
-            BeginNode newBlock = (BeginNode) duplicates.get(block);
-            if (newBlock == null) {
-                newBlock = (BeginNode) replacements.get(block);
-            }
-            assert newBlock != null : block;
-            newBlocks.add(newBlock);
-        }
-        for (Entry<Node, Node> e : replacements.entrySet()) {
-            duplicates.put(e.getKey(), e.getValue());
-        }
-        SuperBlock superBlock = new SuperBlock(newEntry, newExit, newBlocks, newEarlyExits, loop);
-        superBlock.duplicationMapping = duplicates;
-        superBlock.original = this;
-        return superBlock;
-    }
-
-    private BeginNode mergeExits(Map<Node, Node> replacements, StructuredGraph graph, Map<Node, Node> duplicates, MergeNode mergeExit) {
-        BeginNode newExit;
-        List<EndNode> endsToMerge = new LinkedList<>();
-        if (mergeExit == loop) {
-            LoopBeginNode loopBegin = (LoopBeginNode) mergeExit;
-            for (LoopEndNode le : loopBegin.loopEnds()) {
-                Node duplicate = replacements.get(le);
-                if (duplicate != null) {
-                    endsToMerge.add((EndNode) duplicate);
-                }
-            }
-        } else {
-            for (EndNode end : mergeExit.forwardEnds()) {
-                Node duplicate = duplicates.get(end);
-                if (duplicate != null) {
-                    endsToMerge.add((EndNode) duplicate);
-                }
-            }
-        }
-
-        if (endsToMerge.size() == 1) {
-            EndNode end = endsToMerge.get(0);
-            assert end.usages().count() == 0;
-            newExit = graph.add(new BeginNode());
-            end.replaceAtPredecessors(newExit);
-            end.safeDelete();
-        } else {
-            assert endsToMerge.size() > 1;
-            MergeNode newExitMerge = graph.add(new MergeNode());
-            newExit = newExitMerge;
-            FrameState state = mergeExit.stateAfter().duplicate();
-            newExitMerge.setStateAfter(state); // this state is wrong (incudes phis from the loop begin) needs to be fixed while resolving data
-            for (EndNode end : endsToMerge) {
-                newExitMerge.addForwardEnd(end);
-            }
-        }
-        return newExit;
-    }
-
-    public void finish() {
-        if (original != null) {
-            mergeEarlyExits((StructuredGraph) entry.graph(), original.earlyExits, duplicationMapping);
-        }
-    }
-
-    private static void mergeEarlyExits(StructuredGraph graph, List<BeginNode> earlyExits, Map<Node, Node> duplicates) {
-        for (BeginNode earlyExit : earlyExits) {
-            BeginNode newEarlyExit = (BeginNode) duplicates.get(earlyExit);
-            assert newEarlyExit != null;
-            MergeNode merge = graph.add(new MergeNode());
-            EndNode originalEnd = graph.add(new EndNode());
-            EndNode newEnd = graph.add(new EndNode());
-            merge.addForwardEnd(originalEnd);
-            merge.addForwardEnd(newEnd);
-            FixedNode next = earlyExit.next();
-            earlyExit.setNext(originalEnd);
-            newEarlyExit.setNext(newEnd);
-            merge.setNext(next);
-            FrameState exitState = earlyExit.stateAfter();
-            FrameState state = exitState.duplicate();
-            merge.setStateAfter(state);
-            for (ValueProxyNode vpn : earlyExit.proxies().snapshot()) {
-                ValueNode replaceWith;
-                ValueProxyNode newVpn = (ValueProxyNode) duplicates.get(vpn);
-                if (newVpn != null) {
-                    PhiNode phi = graph.add(new PhiNode(vpn.kind(), merge, vpn.type()));
-                    phi.addInput(vpn);
-                    phi.addInput(newVpn);
-                    if (vpn.type() == PhiType.Value) {
-                        replaceWith = phi;
-                    } else {
-                        assert vpn.type() == PhiType.Virtual;
-                        VirtualObjectFieldNode vof = (VirtualObjectFieldNode) GraphUtil.unProxify(vpn);
-                        VirtualObjectFieldNode newVof = (VirtualObjectFieldNode) GraphUtil.unProxify(newVpn);
-                        replaceWith = mergeVirtualChain(graph, vof, newVof, phi, earlyExit, newEarlyExit, merge);
-                    }
-                } else {
-                    replaceWith = vpn.value();
-                }
-                state.replaceFirstInput(vpn, replaceWith);
-                for (Node usage : vpn.usages().snapshot()) {
-                    if (usage != exitState && !merge.isPhiAtMerge(usage)) {
-                        usage.replaceFirstInput(vpn, replaceWith);
-                    }
-                }
-            }
-        }
-    }
-
-    private static ValueProxyNode findProxy(ValueNode value, BeginNode proxyPoint) {
-        for (ValueProxyNode vpn : proxyPoint.proxies()) {
-            ValueNode v = vpn;
-            while (v instanceof ValueProxyNode) {
-                v = ((ValueProxyNode) v).value();
-                if (v == value) {
-                    return vpn;
-                }
-            }
-        }
-        return null;
-    }
-
-    private static ValueNode mergeVirtualChain(
-                    StructuredGraph graph,
-                    VirtualObjectFieldNode vof,
-                    VirtualObjectFieldNode newVof,
-                    PhiNode vPhi,
-                    BeginNode earlyExit,
-                    BeginNode newEarlyExit,
-                    MergeNode merge) {
-        VirtualObjectNode vObject = vof.object();
-        assert newVof.object() == vObject;
-        ValueNode[] virtualState = virtualState(vof);
-        ValueNode[] newVirtualState = virtualState(newVof);
-        ValueNode chain = vPhi;
-        for (int i = 0; i < virtualState.length; i++) {
-            ValueNode value = virtualState[i];
-            ValueNode newValue = newVirtualState[i];
-            assert value.kind() == newValue.kind();
-            if (value != newValue) {
-                PhiNode valuePhi = graph.add(new PhiNode(value.kind(), merge, PhiType.Value));
-                ValueProxyNode inputProxy = findProxy(value, earlyExit);
-                if (inputProxy != null) {
-                    ValueProxyNode newInputProxy = findProxy(newValue, newEarlyExit);
-                    assert newInputProxy != null : "no proxy for " + newValue + " at " + newEarlyExit;
-                    valuePhi.addInput(inputProxy);
-                    valuePhi.addInput(newInputProxy);
-                } else {
-                    valuePhi.addInput(graph.unique(new ValueProxyNode(value, earlyExit, PhiType.Value)));
-                    valuePhi.addInput(newValue);
-                }
-                chain = graph.add(new VirtualObjectFieldNode(vObject, chain, valuePhi, i));
-            }
-        }
-        return chain;
-    }
-
-    private static ValueNode[] virtualState(VirtualObjectFieldNode vof) {
-        VirtualObjectNode vObj = vof.object();
-        int fieldsCount = vObj.fieldsCount();
-        int dicovered = 0;
-        ValueNode[] state = new ValueNode[fieldsCount];
-        ValueNode currentField = vof;
-        do {
-            if (currentField instanceof VirtualObjectFieldNode) {
-                int index = ((VirtualObjectFieldNode) currentField).index();
-                if (state[index] == null) {
-                    dicovered++;
-                    state[index] = ((VirtualObjectFieldNode) currentField).input();
-                    if (dicovered >= fieldsCount) {
-                        break;
-                    }
-                }
-                currentField = ((VirtualObjectFieldNode) currentField).lastState();
-            } else {
-                assert currentField instanceof PhiNode && ((PhiNode) currentField).type() == PhiType.Virtual : currentField;
-                currentField = ((PhiNode) currentField).valueAt(0);
-            }
-        } while (currentField != null);
-        return state;
-    }
-
-    private NodeBitMap computeNodes() {
-        NodeBitMap nodes = entry.graph().createNodeBitMap();
-        for (BeginNode b : blocks) {
-            for (Node n : b.getBlockNodes()) {
-                if (n instanceof Invoke) {
-                    nodes.mark(((Invoke) n).callTarget());
-                }
-                if (n instanceof StateSplit) {
-                    FrameState stateAfter = ((StateSplit) n).stateAfter();
-                    if (stateAfter != null) {
-                        nodes.mark(stateAfter);
-                    }
-                }
-                nodes.mark(n);
-            }
-        }
-        for (BeginNode earlyExit : earlyExits) {
-            FrameState stateAfter = earlyExit.stateAfter();
-            assert stateAfter != null;
-            nodes.mark(stateAfter);
-            nodes.mark(earlyExit);
-            for (ValueProxyNode proxy : earlyExit.proxies()) {
-                nodes.mark(proxy);
-            }
-        }
-
-        for (BeginNode b : blocks) {
-            for (Node n : b.getBlockNodes()) {
-                for (Node usage : n.usages()) {
-                    markFloating(usage, nodes, "");
-                }
-            }
-        }
-
-        if (entry instanceof LoopBeginNode) {
-            for (PhiNode phi : ((LoopBeginNode) entry).phis()) {
-                nodes.clear(phi);
-            }
-        }
-
-        return nodes;
-    }
-
-    private static boolean markFloating(Node n, NodeBitMap loopNodes, String ind) {
-        //System.out.println(ind + "markFloating(" + n + ")");
-        if (loopNodes.isMarked(n)) {
-            return true;
-        }
-        if (n instanceof FixedNode) {
-            return false;
-        }
-        boolean mark = false;
-        if (n instanceof PhiNode) {
-            mark = loopNodes.isMarked(((PhiNode) n).merge());
-            if (mark) {
-                loopNodes.mark(n);
-            } else {
-                return false;
-            }
-        }
-        for (Node usage : n.usages()) {
-            if (markFloating(usage, loopNodes, " " + ind)) {
-                mark = true;
-            }
-        }
-        if (mark) {
-            loopNodes.mark(n);
-            return true;
-        }
-        return false;
-    }
-
-    public void insertBefore(FixedNode fixed) {
-        assert entry.predecessor() == null;
-        assert exit.next() == null;
-        fixed.replaceAtPredecessors(entry);
-        exit.setNext(fixed);
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BoxingEliminationPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BoxingEliminationPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,13 +26,12 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
 
 public class BoxingEliminationPhase extends Phase {
@@ -63,16 +62,17 @@
         }
     }
 
-    private PhiNode getReplacementPhi(PhiNode phiNode, CiKind kind, Map<PhiNode, PhiNode> phiReplacements) {
+    private PhiNode getReplacementPhi(PhiNode phiNode, Kind kind, Map<PhiNode, PhiNode> phiReplacements) {
         if (!phiReplacements.containsKey(phiNode)) {
             PhiNode result = null;
-            if (phiNode.stamp().nonNull()) {
-                RiResolvedType exactType = phiNode.stamp().exactType();
-                if (exactType != null && exactType.toJava() == kind.toUnboxedJavaClass()) {
+            ObjectStamp stamp = phiNode.objectStamp();
+            if (stamp.nonNull() && stamp.isExactType()) {
+                ResolvedJavaType type = stamp.type();
+                if (type != null && type.toJava() == kind.toBoxedJavaClass()) {
                     StructuredGraph graph = (StructuredGraph) phiNode.graph();
-                    result = graph.add(new PhiNode(kind, phiNode.merge(), PhiType.Value));
+                    result = graph.add(new PhiNode(kind, phiNode.merge()));
                     phiReplacements.put(phiNode, result);
-                    virtualizeUsages(phiNode, result, exactType);
+                    virtualizeUsages(phiNode, result, type);
                     int i = 0;
                     for (ValueNode n : phiNode.values()) {
                         ValueNode unboxedValue = unboxedValue(n, kind, phiReplacements);
@@ -93,7 +93,7 @@
         return phiReplacements.get(phiNode);
     }
 
-    private ValueNode unboxedValue(ValueNode n, CiKind kind, Map<PhiNode, PhiNode> phiReplacements) {
+    private ValueNode unboxedValue(ValueNode n, Kind kind, Map<PhiNode, PhiNode> phiReplacements) {
         if (n instanceof BoxNode) {
             BoxNode boxNode = (BoxNode) n;
             return boxNode.source();
@@ -107,9 +107,10 @@
 
     private static void tryEliminate(BoxNode boxNode) {
 
-        virtualizeUsages(boxNode, boxNode.source(), boxNode.exactType());
+        assert boxNode.objectStamp().isExactType();
+        virtualizeUsages(boxNode, boxNode.source(), boxNode.objectStamp().type());
 
-        if (boxNode.usages().filter(isNotA(FrameState.class).nor(VirtualObjectFieldNode.class)).isNotEmpty()) {
+        if (boxNode.usages().filter(isNotA(VirtualState.class)).isNotEmpty()) {
             // Elimination failed, because boxing object escapes.
             return;
         }
@@ -121,10 +122,10 @@
         ((StructuredGraph) boxNode.graph()).removeFixed(boxNode);
     }
 
-    private static void virtualizeUsages(ValueNode boxNode, ValueNode replacement, RiResolvedType exactType) {
+    private static void virtualizeUsages(ValueNode boxNode, ValueNode replacement, ResolvedJavaType exactType) {
         ValueNode virtualValueNode = null;
         VirtualObjectNode virtualObjectNode = null;
-        for (Node n : boxNode.usages().filter(NodePredicates.isA(FrameState.class).or(VirtualObjectFieldNode.class)).snapshot()) {
+        for (Node n : boxNode.usages().filter(NodePredicates.isA(VirtualState.class)).snapshot()) {
             if (virtualValueNode == null) {
                 virtualObjectNode = n.graph().unique(new BoxedVirtualObjectNode(exactType, replacement));
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,57 +22,152 @@
  */
 package com.oracle.graal.compiler.phases;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Graph.InputChangedListener;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 
 public class CanonicalizerPhase extends Phase {
     private static final int MAX_ITERATION_PER_NODE = 10;
     private static final DebugMetric METRIC_CANONICALIZED_NODES = Debug.metric("CanonicalizedNodes");
     private static final DebugMetric METRIC_CANONICALIZATION_CONSIDERED_NODES = Debug.metric("CanonicalizationConsideredNodes");
+    private static final DebugMetric METRIC_INFER_STAMP_CALLED = Debug.metric("InferStampCalled");
+    private static final DebugMetric METRIC_STAMP_CHANGED = Debug.metric("StampChanged");
     private static final DebugMetric METRIC_SIMPLIFICATION_CONSIDERED_NODES = Debug.metric("SimplificationConsideredNodes");
+    public static final DebugMetric METRIC_GLOBAL_VALUE_NUMBERING_HITS = Debug.metric("GlobalValueNumberingHits");
 
-    private boolean newNodes;
-    private final CiTarget target;
-    private final CiAssumptions assumptions;
-    private final RiRuntime runtime;
+    private final int newNodesMark;
+    private final TargetDescription target;
+    private final Assumptions assumptions;
+    private final CodeCacheProvider runtime;
+    private final IsImmutablePredicate immutabilityPredicate;
+    private final Iterable<Node> initWorkingSet;
 
-    public CanonicalizerPhase(CiTarget target, RiRuntime runtime, CiAssumptions assumptions) {
-        this(target, runtime, false, assumptions);
+    private NodeWorkList workList;
+    private Tool tool;
+
+    public CanonicalizerPhase(TargetDescription target, CodeCacheProvider runtime, Assumptions assumptions) {
+        this(target, runtime, assumptions, null, 0, null);
     }
 
-    public CanonicalizerPhase(CiTarget target, RiRuntime runtime, boolean newNodes, CiAssumptions assumptions) {
-        this.newNodes = newNodes;
+    /**
+     * @param target
+     * @param runtime
+     * @param assumptions
+     * @param workingSet the initial working set of nodes on which the canonicalizer works, should be an auto-grow node bitmap
+     * @param immutabilityPredicate
+     */
+    public CanonicalizerPhase(TargetDescription target, CodeCacheProvider runtime, Assumptions assumptions, Iterable<Node> workingSet, IsImmutablePredicate immutabilityPredicate) {
+        this(target, runtime, assumptions, workingSet, 0, immutabilityPredicate);
+    }
+
+    /**
+     * @param newNodesMark only the {@linkplain Graph#getNewNodes(int) new nodes} specified by
+     *            this mark are processed otherwise all nodes in the graph are processed
+     */
+    public CanonicalizerPhase(TargetDescription target, CodeCacheProvider runtime, Assumptions assumptions, int newNodesMark, IsImmutablePredicate immutabilityPredicate) {
+        this(target, runtime, assumptions, null, newNodesMark, immutabilityPredicate);
+    }
+
+    private CanonicalizerPhase(TargetDescription target, CodeCacheProvider runtime, Assumptions assumptions, Iterable<Node> workingSet, int newNodesMark, IsImmutablePredicate immutabilityPredicate) {
+        this.newNodesMark = newNodesMark;
         this.target = target;
         this.assumptions = assumptions;
         this.runtime = runtime;
+        this.immutabilityPredicate = immutabilityPredicate;
+        this.initWorkingSet = workingSet;
     }
 
     @Override
     protected void run(StructuredGraph graph) {
-        NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE);
-        if (newNodes) {
-            nodeWorkList.addAll(graph.getNewNodes());
+        if (initWorkingSet == null) {
+            workList = graph.createNodeWorkList(newNodesMark == 0, MAX_ITERATION_PER_NODE);
+            if (newNodesMark > 0) {
+                workList.addAll(graph.getNewNodes(newNodesMark));
+            }
+        } else {
+            workList = graph.createNodeWorkList(newNodesMark == 0, MAX_ITERATION_PER_NODE);
+            workList.addAll(initWorkingSet);
         }
+        tool = new Tool(workList, runtime, target, assumptions, immutabilityPredicate);
+        processWorkSet(graph);
 
-        canonicalize(graph, nodeWorkList, runtime, target, assumptions);
+        while (graph.getUsagesDroppedNodesCount() > 0) {
+            for (Node n : graph.getAndCleanUsagesDroppedNodes()) {
+                if (!n.isDeleted() && n.usages().size() == 0 && GraphUtil.isFloatingNode().apply(n)) {
+                    n.safeDelete();
+                }
+            }
+        }
+    }
+
+    public interface IsImmutablePredicate {
+        /**
+         * Determines if a given constant is an object/array whose current
+         * fields/elements will never change.
+         */
+        boolean apply(Constant constant);
     }
 
-    public static void canonicalize(StructuredGraph graph, NodeWorkList nodeWorkList, RiRuntime runtime, CiTarget target, CiAssumptions assumptions) {
-        graph.trackInputChange(nodeWorkList);
-        Tool tool = new Tool(nodeWorkList, runtime, target, assumptions);
-        for (Node node : nodeWorkList) {
+    private void processWorkSet(StructuredGraph graph) {
+        graph.trackInputChange(new InputChangedListener() {
+            @Override
+            public void inputChanged(Node node) {
+                workList.addAgain(node);
+            }
+        });
+
+        for (Node n : workList) {
+            processNode(n, graph);
+        }
+
+        graph.stopTrackingInputChange();
+    }
+
+    private void processNode(Node node, StructuredGraph graph) {
+        if (node.isAlive()) {
             METRIC_PROCESSED_NODES.increment();
-            if (node instanceof Canonicalizable) {
-                METRIC_CANONICALIZATION_CONSIDERED_NODES.increment();
-                Debug.log("Canonicalizer: work on %s", node);
-                graph.mark();
-                ValueNode canonical = ((Canonicalizable) node).canonical(tool);
+
+            if (tryGlobalValueNumbering(node, graph)) {
+                return;
+            }
+            int mark = graph.getMark();
+            tryCanonicalize(node, graph, tool);
+            tryInferStamp(node, graph);
+
+            for (Node newNode : graph.getNewNodes(mark)) {
+                workList.add(newNode);
+            }
+        }
+    }
+
+    public static boolean tryGlobalValueNumbering(Node node, StructuredGraph graph) {
+        if (node.getNodeClass().valueNumberable()) {
+            Node newNode = graph.findDuplicate(node);
+            if (newNode != null) {
+                assert !(node instanceof FixedNode || newNode instanceof FixedNode);
+                node.replaceAtUsages(newNode);
+                node.safeDelete();
+                METRIC_GLOBAL_VALUE_NUMBERING_HITS.increment();
+                Debug.log("GVN applied and new node is %1s", newNode);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static void tryCanonicalize(final Node node, final StructuredGraph graph, final SimplifierTool tool) {
+        if (node instanceof Canonicalizable) {
+            METRIC_CANONICALIZATION_CONSIDERED_NODES.increment();
+            Debug.scope("CanonicalizeNode", node, new Runnable() {
+                public void run() {
+                    ValueNode canonical = ((Canonicalizable) node).canonical(tool);
 //     cases:                                           original node:
 //                                         |Floating|Fixed-unconnected|Fixed-connected|
 //                                         --------------------------------------------
@@ -85,53 +180,73 @@
 //                          Fixed-connected|   2    |        X        |       6       |
 //                                         --------------------------------------------
 //       X: must not happen (checked with assertions)
-                if (canonical != node) {
-                    METRIC_CANONICALIZED_NODES.increment();
-                    if (node instanceof FloatingNode) {
-                        if (canonical == null) {
-                            // case 1
-                            graph.removeFloating((FloatingNode) node);
-                        } else {
-                            // case 2
-                            assert !(canonical instanceof FixedNode) || canonical.predecessor() != null : node + " -> " + canonical +
-                                            " : replacement should be floating or fixed and connected";
-                            graph.replaceFloating((FloatingNode) node, canonical);
-                        }
+                    if (canonical == node) {
+                        Debug.log("Canonicalizer: work on %s", node);
                     } else {
-                        assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")";
-                        if (canonical == null) {
-                            // case 3
-                            graph.removeFixed((FixedWithNextNode) node);
-                        } else if (canonical instanceof FloatingNode) {
-                            // case 4
-                            graph.replaceFixedWithFloating((FixedWithNextNode) node, (FloatingNode) canonical);
+                        Debug.log("Canonicalizer: replacing %s with %s", node, canonical);
+
+                        METRIC_CANONICALIZED_NODES.increment();
+                        if (node instanceof FloatingNode) {
+                            if (canonical == null) {
+                                // case 1
+                                graph.removeFloating((FloatingNode) node);
+                            } else {
+                                // case 2
+                                assert !(canonical instanceof FixedNode) || canonical.predecessor() != null : node + " -> " + canonical +
+                                                " : replacement should be floating or fixed and connected";
+                                graph.replaceFloating((FloatingNode) node, canonical);
+                            }
                         } else {
-                            assert canonical instanceof FixedNode;
-                            if (canonical.predecessor() == null) {
-                                assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors";
-                                // case 5
-                                graph.replaceFixedWithFixed((FixedWithNextNode) node, (FixedWithNextNode) canonical);
+                            assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")";
+                            if (canonical == null) {
+                                // case 3
+                                graph.removeFixed((FixedWithNextNode) node);
+                            } else if (canonical instanceof FloatingNode) {
+                                // case 4
+                                graph.replaceFixedWithFloating((FixedWithNextNode) node, (FloatingNode) canonical);
                             } else {
-                                assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors";
-                                // case 6
-                                node.replaceAtUsages(canonical);
-                                graph.removeFixed((FixedWithNextNode) node);
+                                assert canonical instanceof FixedNode;
+                                if (canonical.predecessor() == null) {
+                                    assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors";
+                                    // case 5
+                                    graph.replaceFixedWithFixed((FixedWithNextNode) node, (FixedWithNextNode) canonical);
+                                } else {
+                                    assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors";
+                                    // case 6
+                                    node.replaceAtUsages(canonical);
+                                    graph.removeFixed((FixedWithNextNode) node);
+                                }
                             }
                         }
                     }
-                    nodeWorkList.addAll(graph.getNewNodes());
                 }
-            } else if (node instanceof Simplifiable) {
-                METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment();
-                ((Simplifiable) node).simplify(tool);
-            }
+            });
+        } else if (node instanceof Simplifiable) {
+            Debug.log("Canonicalizer: simplifying %s", node);
+            METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment();
+            ((Simplifiable) node).simplify(tool);
         }
-        graph.stopTrackingInputChange();
-        while (graph.getUsagesDroppedNodesCount() > 0) {
-            for (Node n : graph.getAndCleanUsagesDroppedNodes()) {
-                if (!n.isDeleted() && n.usages().size() == 0 && n instanceof FloatingNode) {
-                    n.clearInputs();
-                    n.safeDelete();
+    }
+
+    /**
+     * Calls {@link ValueNode#inferStamp()} on the node and, if it returns true (which means that the stamp has
+     * changed), re-queues the node's usages . If the stamp has changed then this method also checks if the stamp
+     * now describes a constant integer value, in which case the node is replaced with a constant.
+     */
+    private void tryInferStamp(Node node, StructuredGraph graph) {
+        if (node.isAlive() && node instanceof ValueNode) {
+            ValueNode valueNode = (ValueNode) node;
+            METRIC_INFER_STAMP_CALLED.increment();
+            if (valueNode.inferStamp()) {
+                METRIC_STAMP_CHANGED.increment();
+                if (valueNode.stamp() instanceof IntegerStamp && valueNode.integerStamp().lowerBound() == valueNode.integerStamp().upperBound()) {
+                    ValueNode replacement = ConstantNode.forIntegerKind(valueNode.kind(), valueNode.integerStamp().lowerBound(), graph);
+                    Debug.log("Canonicalizer: replacing %s with %s (inferStamp)", valueNode, replacement);
+                    valueNode.replaceAtUsages(replacement);
+                } else {
+                    for (Node usage : valueNode.usages()) {
+                        workList.addAgain(usage);
+                    }
                 }
             }
         }
@@ -139,16 +254,18 @@
 
     private static final class Tool implements SimplifierTool {
 
-        private final NodeWorkList nodeWorkList;
-        private final RiRuntime runtime;
-        private final CiTarget target;
-        private final CiAssumptions assumptions;
+        private final NodeWorkList nodeWorkSet;
+        private final CodeCacheProvider runtime;
+        private final TargetDescription target;
+        private final Assumptions assumptions;
+        private final IsImmutablePredicate immutabilityPredicate;
 
-        public Tool(NodeWorkList nodeWorkList, RiRuntime runtime, CiTarget target, CiAssumptions assumptions) {
-            this.nodeWorkList = nodeWorkList;
+        public Tool(NodeWorkList nodeWorkSet, CodeCacheProvider runtime, TargetDescription target, Assumptions assumptions, IsImmutablePredicate immutabilityPredicate) {
+            this.nodeWorkSet = nodeWorkSet;
             this.runtime = runtime;
             this.target = target;
             this.assumptions = assumptions;
+            this.immutabilityPredicate = immutabilityPredicate;
         }
 
         @Override
@@ -161,7 +278,7 @@
          * @return the current target or {@code null} if no target is available in the current context.
          */
         @Override
-        public CiTarget target() {
+        public TargetDescription target() {
             return target;
         }
 
@@ -169,18 +286,23 @@
          * @return an object that can be used for recording assumptions or {@code null} if assumptions are not allowed in the current context.
          */
         @Override
-        public CiAssumptions assumptions() {
+        public Assumptions assumptions() {
             return assumptions;
         }
 
         @Override
-        public RiRuntime runtime() {
+        public CodeCacheProvider runtime() {
             return runtime;
         }
 
         @Override
         public void addToWorkList(Node node) {
-            nodeWorkList.add(node);
+            nodeWorkSet.add(node);
+        }
+
+        @Override
+        public boolean isImmutable(Constant objectConstant) {
+            return immutabilityPredicate != null && immutabilityPredicate.apply(objectConstant);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CheckCastEliminationPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,394 @@
+/*
+ * 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.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.graph.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+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.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+
+public class CheckCastEliminationPhase extends Phase {
+
+    private static final DebugMetric metricInstanceOfRegistered = Debug.metric("InstanceOfRegistered");
+    private static final DebugMetric metricIsTypeRegistered = Debug.metric("IsTypeRegistered");
+    private static final DebugMetric metricNullCheckRegistered = Debug.metric("NullCheckRegistered");
+    private static final DebugMetric metricCheckCastRemoved = Debug.metric("CheckCastRemoved");
+    private static final DebugMetric metricInstanceOfRemoved = Debug.metric("InstanceOfRemoved");
+    private static final DebugMetric metricNullCheckRemoved = Debug.metric("NullCheckRemoved");
+    private static final DebugMetric metricNullCheckGuardRemoved = Debug.metric("NullCheckGuardRemoved");
+    private static final DebugMetric metricGuardsReplaced = Debug.metric("GuardsReplaced");
+
+    private StructuredGraph graph;
+
+    @Override
+    protected void run(StructuredGraph inputGraph) {
+        graph = inputGraph;
+        new EliminateCheckCasts(graph.start(), new State()).apply();
+    }
+
+    public static class State implements MergeableState<State> {
+
+        private IdentityHashMap<ValueNode, ResolvedJavaType> knownTypes;
+        private HashSet<ValueNode> knownNotNull;
+        private HashSet<ValueNode> knownNull;
+        private IdentityHashMap<BooleanNode, ValueNode> trueConditions;
+        private IdentityHashMap<BooleanNode, ValueNode> falseConditions;
+
+        public State() {
+            this.knownTypes = new IdentityHashMap<>();
+            this.knownNotNull = new HashSet<>();
+            this.knownNull = new HashSet<>();
+            this.trueConditions = new IdentityHashMap<>();
+            this.falseConditions = new IdentityHashMap<>();
+        }
+
+        public State(State other) {
+            this.knownTypes = new IdentityHashMap<>(other.knownTypes);
+            this.knownNotNull = new HashSet<>(other.knownNotNull);
+            this.knownNull = new HashSet<>(other.knownNull);
+            this.trueConditions = new IdentityHashMap<>(other.trueConditions);
+            this.falseConditions = new IdentityHashMap<>(other.falseConditions);
+        }
+
+        @Override
+        public boolean merge(MergeNode merge, List<State> withStates) {
+            IdentityHashMap<ValueNode, ResolvedJavaType> newKnownTypes = new IdentityHashMap<>();
+            HashSet<ValueNode> newKnownNotNull = new HashSet<>();
+            HashSet<ValueNode> newKnownNull = new HashSet<>();
+            IdentityHashMap<BooleanNode, ValueNode> newTrueConditions = new IdentityHashMap<>();
+            IdentityHashMap<BooleanNode, ValueNode> newFalseConditions = new IdentityHashMap<>();
+
+            for (Map.Entry<ValueNode, ResolvedJavaType> entry : knownTypes.entrySet()) {
+                ValueNode node = entry.getKey();
+                ResolvedJavaType type = entry.getValue();
+
+                for (State other : withStates) {
+                    ResolvedJavaType otherType = other.getNodeType(node);
+                    type = widen(type, otherType);
+                    if (type == null) {
+                        break;
+                    }
+                }
+                if (type == null && type != node.objectStamp().type()) {
+                    newKnownTypes.put(node, type);
+                }
+            }
+            for (ValueNode node : knownNotNull) {
+                boolean notNull = true;
+                for (State other : withStates) {
+                    if (!other.knownNotNull.contains(node)) {
+                        notNull = false;
+                        break;
+                    }
+                }
+                if (notNull) {
+                    newKnownNotNull.add(node);
+                }
+            }
+            for (ValueNode node : knownNull) {
+                boolean nul = true;
+                for (State other : withStates) {
+                    if (!other.knownNull.contains(node)) {
+                        nul = false;
+                        break;
+                    }
+                }
+                if (nul) {
+                    newKnownNull.add(node);
+                }
+            }
+            for (Map.Entry<BooleanNode, ValueNode> entry : trueConditions.entrySet()) {
+                BooleanNode check = entry.getKey();
+                ValueNode guard = entry.getValue();
+
+                for (State other : withStates) {
+                    ValueNode otherGuard = other.trueConditions.get(check);
+                    if (otherGuard == null) {
+                        guard = null;
+                        break;
+                    }
+                    if (otherGuard != guard) {
+                        guard = merge;
+                    }
+                }
+                if (guard != null) {
+                    newTrueConditions.put(check, guard);
+                }
+            }
+            for (Map.Entry<BooleanNode, ValueNode> entry : falseConditions.entrySet()) {
+                BooleanNode check = entry.getKey();
+                ValueNode guard = entry.getValue();
+
+                for (State other : withStates) {
+                    ValueNode otherGuard = other.falseConditions.get(check);
+                    if (otherGuard == null) {
+                        guard = null;
+                        break;
+                    }
+                    if (otherGuard != guard) {
+                        guard = merge;
+                    }
+                }
+                if (guard != null) {
+                    newFalseConditions.put(check, guard);
+                }
+            }
+
+            /*
+            // this piece of code handles phis (merges the types and knownNull/knownNotNull of the values)
+            if (!(merge instanceof LoopBeginNode)) {
+                for (PhiNode phi : merge.phis()) {
+                    if (phi.type() == PhiType.Value && phi.kind() == CiKind.Object) {
+                        ValueNode firstValue = phi.valueAt(0);
+                        RiResolvedType type = getNodeType(firstValue);
+                        boolean notNull = knownNotNull.contains(firstValue);
+                        boolean nul = knownNull.contains(firstValue);
+
+                        for (int i = 0; i < withStates.size(); i++) {
+                            State otherState = withStates.get(i);
+                            ValueNode value = phi.valueAt(i + 1);
+                            RiResolvedType otherType = otherState.getNodeType(value);
+                            type = widen(type, otherType);
+                            notNull &= otherState.knownNotNull.contains(value);
+                            nul &= otherState.knownNull.contains(value);
+                        }
+                        if (type == null && type != phi.declaredType()) {
+                            newKnownTypes.put(phi, type);
+                        }
+                        if (notNull) {
+                            newKnownNotNull.add(phi);
+                        }
+                        if (nul) {
+                            newKnownNull.add(phi);
+                        }
+                    }
+                }
+            }
+            */
+            this.knownTypes = newKnownTypes;
+            this.knownNotNull = newKnownNotNull;
+            this.knownNull = newKnownNull;
+            this.trueConditions = newTrueConditions;
+            this.falseConditions = newFalseConditions;
+            return true;
+        }
+
+        public ResolvedJavaType getNodeType(ValueNode node) {
+            ResolvedJavaType result = knownTypes.get(node);
+            return result == null ? node.objectStamp().type() : result;
+        }
+
+        @Override
+        public void loopBegin(LoopBeginNode loopBegin) {
+        }
+
+        @Override
+        public void loopEnds(LoopBeginNode loopBegin, List<State> loopEndStates) {
+        }
+
+        @Override
+        public void afterSplit(FixedNode node) {
+        }
+
+        @Override
+        public State clone() {
+            return new State(this);
+        }
+    }
+
+    public static ResolvedJavaType widen(ResolvedJavaType a, ResolvedJavaType b) {
+        if (a == null || b == null) {
+            return null;
+        } else if (a == b) {
+            return a;
+        } else {
+            return a.leastCommonAncestor(b);
+        }
+    }
+
+    public static ResolvedJavaType tighten(ResolvedJavaType a, ResolvedJavaType b) {
+        if (a == null) {
+            return b;
+        } else if (b == null) {
+            return a;
+        } else if (a == b) {
+            return a;
+        } else if (a.isSubtypeOf(b)) {
+            return a;
+        } else if (b.isSubtypeOf(a)) {
+            return b;
+        } else {
+            return a;
+        }
+    }
+
+    public class EliminateCheckCasts extends PostOrderNodeIterator<State> {
+        private BeginNode lastBegin = null;
+
+        public EliminateCheckCasts(FixedNode start, State initialState) {
+            super(start, initialState);
+        }
+
+        @Override
+        protected void node(FixedNode node) {
+            if (node instanceof BeginNode) {
+                BeginNode begin = (BeginNode) node;
+                lastBegin = begin;
+                Node pred = node.predecessor();
+                if (pred != null && pred instanceof IfNode) {
+                    IfNode ifNode = (IfNode) pred;
+                    if (!(ifNode.compare() instanceof ConstantNode)) {
+                        boolean isTrue = (node == ifNode.trueSuccessor());
+                        if (isTrue) {
+                            state.trueConditions.put(ifNode.compare(), begin);
+                        } else {
+                            state.falseConditions.put(ifNode.compare(), begin);
+                        }
+                    }
+                    if (ifNode.compare() instanceof InstanceOfNode) {
+                        InstanceOfNode instanceOf = (InstanceOfNode) ifNode.compare();
+                        if ((node == ifNode.trueSuccessor())) {
+                            ValueNode object = instanceOf.object();
+                            state.knownNotNull.add(object);
+                            state.knownTypes.put(object, tighten(instanceOf.targetClass(), state.getNodeType(object)));
+                            metricInstanceOfRegistered.increment();
+                        }
+                    } else if (ifNode.compare() instanceof IsNullNode) {
+                        IsNullNode nullCheck = (IsNullNode) ifNode.compare();
+                        boolean isNull = (node == ifNode.trueSuccessor());
+                        if (isNull) {
+                            state.knownNull.add(nullCheck.object());
+                        } else {
+                            state.knownNotNull.add(nullCheck.object());
+                        }
+                        metricNullCheckRegistered.increment();
+                    } else if (ifNode.compare() instanceof IsTypeNode) {
+                        IsTypeNode isType = (IsTypeNode) ifNode.compare();
+                        if (isType.objectClass() instanceof ReadHubNode && (node == ifNode.trueSuccessor())) {
+                            ReadHubNode readHub = (ReadHubNode) isType.objectClass();
+                            ValueNode object = readHub.object();
+                            state.knownNotNull.add(object);
+                            state.knownTypes.put(object, tighten(isType.type(), state.getNodeType(object)));
+                            metricIsTypeRegistered.increment();
+                        }
+                    }
+                }
+                for (GuardNode guard : begin.guards().snapshot()) {
+                    BooleanNode condition = guard.condition();
+                    ValueNode existingGuards = guard.negated() ? state.falseConditions.get(condition) : state.trueConditions.get(condition);
+                    if (existingGuards != null) {
+                        guard.replaceAtUsages(existingGuards);
+                        GraphUtil.killWithUnusedFloatingInputs(guard);
+                        metricGuardsReplaced.increment();
+                    } else {
+                        boolean removeCheck = false;
+                        if (condition instanceof IsNullNode) {
+                            IsNullNode isNull = (IsNullNode) condition;
+                            if (guard.negated() && state.knownNotNull.contains(isNull.object())) {
+                                removeCheck = true;
+                            } else if (!guard.negated() && state.knownNull.contains(isNull.object())) {
+                                removeCheck = true;
+                            }
+                            if (removeCheck) {
+                                metricNullCheckGuardRemoved.increment();
+                            }
+                        }
+                        if (removeCheck) {
+                            guard.replaceAtUsages(begin);
+                            GraphUtil.killWithUnusedFloatingInputs(guard);
+                        } else {
+                            if (guard.negated()) {
+                                state.falseConditions.put(condition, guard);
+                            } else {
+                                state.trueConditions.put(condition, guard);
+                            }
+                        }
+                    }
+                }
+            } else if (node instanceof CheckCastNode) {
+                CheckCastNode checkCast = (CheckCastNode) node;
+                ResolvedJavaType type = state.getNodeType(checkCast.object());
+                if (checkCast.targetClass() != null && type != null && type.isSubtypeOf(checkCast.targetClass())) {
+                    PiNode piNode;
+                    boolean nonNull = state.knownNotNull.contains(checkCast.object());
+                    piNode = graph.unique(new PiNode(checkCast.object(), lastBegin, nonNull ? StampFactory.declaredNonNull(type) : StampFactory.declared(type)));
+                    checkCast.replaceAtUsages(piNode);
+                    graph.removeFixed(checkCast);
+                    metricCheckCastRemoved.increment();
+                }
+            } else if (node instanceof IfNode) {
+                IfNode ifNode = (IfNode) node;
+                BooleanNode replaceWith = null;
+                BooleanNode compare = ifNode.compare();
+
+                if (state.trueConditions.containsKey(compare)) {
+                    replaceWith = ConstantNode.forBoolean(true, graph);
+                } else if (state.falseConditions.containsKey(compare)) {
+                    replaceWith = ConstantNode.forBoolean(false, graph);
+                } else {
+                    if (compare instanceof InstanceOfNode) {
+                        InstanceOfNode instanceOf = (InstanceOfNode) compare;
+                        ValueNode object = instanceOf.object();
+                        if (state.knownNull.contains(object)) {
+                            replaceWith = ConstantNode.forBoolean(false, graph);
+                        } else if (state.knownNotNull.contains(object)) {
+                            ResolvedJavaType type = state.getNodeType(object);
+                            if (type != null && type.isSubtypeOf(instanceOf.targetClass())) {
+                                replaceWith = ConstantNode.forBoolean(true, graph);
+                            }
+                        }
+                        if (replaceWith != null) {
+                            metricInstanceOfRemoved.increment();
+                        }
+                    } else if (compare instanceof IsNullNode) {
+                        IsNullNode isNull = (IsNullNode) compare;
+                        ValueNode object = isNull.object();
+                        if (state.knownNull.contains(object)) {
+                            replaceWith = ConstantNode.forBoolean(true, graph);
+                        } else if (state.knownNotNull.contains(object)) {
+                            replaceWith = ConstantNode.forBoolean(false, graph);
+                        }
+                        if (replaceWith != null) {
+                            metricNullCheckRemoved.increment();
+                        }
+                    }
+                }
+                if (replaceWith != null) {
+                    ifNode.setCompare(replaceWith);
+                    if (compare.usages().isEmpty()) {
+                        GraphUtil.killWithUnusedFloatingInputs(compare);
+                    }
+                }
+            }
+        }
+    }
+
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ComputeProbabilityPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ComputeProbabilityPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -58,7 +58,7 @@
 
         if (GraalOptions.LoopFrequencyPropagationPolicy < 0) {
             ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
-            BitMap visitedBlocks = new BitMap(cfg.getBlocks().length);
+            BitSet visitedBlocks = new BitSet(cfg.getBlocks().length);
             for (Loop loop : cfg.getLoops()) {
                 if (loop.parent == null) {
                     correctLoopFrequencies(loop, 1, visitedBlocks);
@@ -67,7 +67,7 @@
         }
     }
 
-    private void correctLoopFrequencies(Loop loop, double parentFrequency, BitMap visitedBlocks) {
+    private void correctLoopFrequencies(Loop loop, double parentFrequency, BitSet visitedBlocks) {
         LoopBeginNode loopBegin = ((LoopBeginNode) loop.header.getBeginNode());
         double frequency = parentFrequency * loopBegin.loopFrequency();
         for (Loop child : loop.children) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ConvertDeoptimizeToGuardPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ConvertDeoptimizeToGuardPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -78,18 +78,19 @@
             IfNode ifNode = (IfNode) deoptBegin.predecessor();
             BeginNode otherBegin = ifNode.trueSuccessor();
             BooleanNode conditionNode = ifNode.compare();
+            boolean negated = false;
             if (deoptBegin == ifNode.trueSuccessor()) {
-                conditionNode = conditionNode.negate();
+                negated = true;
                 otherBegin = ifNode.falseSuccessor();
             }
             BeginNode ifBlockBegin = findBeginNode(ifNode);
             Debug.log("Converting %s on %-5s branch of %s to guard for remaining branch %s. IfBegin=%s", deopt, deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin, ifBlockBegin);
-            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), deopt.leafGraphId()));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), negated, deopt.leafGraphId()));
             otherBegin.replaceAtUsages(ifBlockBegin);
             FixedNode next = otherBegin.next();
             otherBegin.setNext(null);
             guard.setNext(next);
-            ifNode.replaceAtPredecessors(guard);
+            ifNode.replaceAtPredecessor(guard);
             GraphUtil.killCFG(ifNode);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ConvertUnreachedToGuardPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.compiler.phases;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.util.*;
+
+
+public class ConvertUnreachedToGuardPhase extends Phase {
+    private OptimisticOptimizations opt;
+
+    public ConvertUnreachedToGuardPhase(OptimisticOptimizations opt) {
+        this.opt = opt;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        if (!opt.removeNeverExecutedCode()) {
+            return;
+        }
+        for (Node node : graph.getNodes()) {
+            if (node instanceof IfNode) {
+                IfNode ifNode = (IfNode) node;
+                BeginNode insertGuard = null;
+                BeginNode delete = null;
+                boolean inverted = false;
+                if (ifNode.probability(IfNode.TRUE_EDGE) == 0) {
+                    insertGuard = ifNode.falseSuccessor();
+                    delete = ifNode.trueSuccessor();
+                    inverted = true;
+                } else if (ifNode.probability(IfNode.FALSE_EDGE) == 0) {
+                    insertGuard = ifNode.trueSuccessor();
+                    delete = ifNode.falseSuccessor();
+                }
+                if (insertGuard != null) {
+                    GuardNode guard = graph.unique(new GuardNode(ifNode.compare(), BeginNode.prevBegin(ifNode), DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, inverted, ifNode.leafGraphId()));
+                    graph.addBeforeFixed(ifNode, graph.add(new ValueAnchorNode(guard)));
+                    GraphUtil.killCFG(delete);
+                    graph.removeSplit(ifNode, inverted ? IfNode.FALSE_EDGE : IfNode.TRUE_EDGE);
+                }
+            }
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CullFrameStatesPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,115 @@
+/*
+ * 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.compiler.phases;
+
+import java.util.*;
+
+import com.oracle.graal.compiler.graph.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.util.*;
+
+/**
+ * This phase culls unused FrameStates from the graph.
+ * It does a post order iteration over the graph, and
+ */
+public class CullFrameStatesPhase extends Phase {
+
+    private static final DebugMetric metricFrameStatesCulled = Debug.metric("FrameStatesCulled");
+    private static final DebugMetric metricMergesTraversed = Debug.metric("MergesTraversed");
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        new CullFrameStates(graph.start(), new State(null)).apply();
+    }
+
+    public static class State implements MergeableState<State> {
+
+        private FrameState lastFrameState;
+
+        public State(FrameState lastFrameState) {
+            this.lastFrameState = lastFrameState;
+        }
+
+        @Override
+        public boolean merge(MergeNode merge, List<State> withStates) {
+            FrameState stateAfter = merge.stateAfter();
+            if (merge instanceof LoopBeginNode) {
+                if (stateAfter != null) {
+                    lastFrameState = stateAfter;
+                }
+                return true;
+            }
+            metricMergesTraversed.increment();
+            if (stateAfter != null) {
+                for (State other : withStates) {
+                    if (other.lastFrameState != lastFrameState) {
+                        lastFrameState = stateAfter;
+                        return true;
+                    }
+                }
+                metricFrameStatesCulled.increment();
+                merge.setStateAfter(null);
+                if (stateAfter.usages().isEmpty()) {
+                    GraphUtil.killWithUnusedFloatingInputs(stateAfter);
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public void loopBegin(LoopBeginNode loopBegin) {
+        }
+
+        @Override
+        public void loopEnds(LoopBeginNode loopBegin, List<State> loopEndStates) {
+        }
+
+        @Override
+        public void afterSplit(FixedNode node) {
+        }
+
+        @Override
+        public State clone() {
+            return new State(lastFrameState);
+        }
+    }
+
+    public static class CullFrameStates extends PostOrderNodeIterator<State> {
+
+        public CullFrameStates(FixedNode start, State initialState) {
+            super(start, initialState);
+        }
+
+        @Override
+        protected void node(FixedNode node) {
+            if (node instanceof StateSplit) {
+                FrameState stateAfter = ((StateSplit) node).stateAfter();
+                if (stateAfter != null) {
+                    state.lastFrameState = stateAfter;
+                }
+            }
+        }
+    }
+
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,7 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.graph.*;
 import com.oracle.graal.compiler.util.*;
@@ -38,38 +37,34 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.virtual.*;
+import com.oracle.max.criutils.*;
 
 
 public class EscapeAnalysisPhase extends Phase {
 
+    /**
+     * Encapsulates the state of the virtual object, which is updated while traversing the control flow graph.
+     */
     public static class BlockExitState implements MergeableState<BlockExitState> {
         public final ValueNode[] fieldState;
         public final VirtualObjectNode virtualObject;
-        public ValueNode virtualObjectField;
         public final Graph graph;
 
         public BlockExitState(EscapeField[] fields, VirtualObjectNode virtualObject) {
             this.fieldState = new ValueNode[fields.length];
             this.virtualObject = virtualObject;
-            this.virtualObjectField = null;
             this.graph = virtualObject.graph();
             for (int i = 0; i < fields.length; i++) {
-                fieldState[i] = ConstantNode.defaultForKind(fields[i].type().kind(true), virtualObject.graph());
-                virtualObjectField = graph.add(new VirtualObjectFieldNode(virtualObject, virtualObjectField, fieldState[i], i));
+                fieldState[i] = ConstantNode.defaultForKind(fields[i].type().kind(), virtualObject.graph());
             }
         }
 
         public BlockExitState(BlockExitState state) {
             this.fieldState = state.fieldState.clone();
             this.virtualObject = state.virtualObject;
-            this.virtualObjectField = state.virtualObjectField;
             this.graph = state.graph;
         }
 
-        public void updateField(int fieldIndex) {
-            virtualObjectField = graph.add(new VirtualObjectFieldNode(virtualObject, virtualObjectField, fieldState[fieldIndex], fieldIndex));
-        }
-
         @Override
         public BlockExitState clone() {
             return new BlockExitState(this);
@@ -77,68 +72,38 @@
 
         @Override
         public boolean merge(MergeNode merge, List<BlockExitState> withStates) {
-            PhiNode vobjPhi = null;
             PhiNode[] valuePhis = new PhiNode[fieldState.length];
             for (BlockExitState other : withStates) {
-                if (virtualObjectField != other.virtualObjectField && vobjPhi == null) {
-                    vobjPhi = graph.add(new PhiNode(CiKind.Illegal, merge, PhiType.Virtual));
-                    vobjPhi.addInput(virtualObjectField);
-                    virtualObjectField = vobjPhi;
-                }
                 for (int i2 = 0; i2 < fieldState.length; i2++) {
                     if (fieldState[i2] != other.fieldState[i2] && valuePhis[i2] == null) {
-                        valuePhis[i2] = graph.add(new PhiNode(fieldState[i2].kind(), merge, PhiType.Value));
+                        valuePhis[i2] = graph.add(new PhiNode(fieldState[i2].kind(), merge));
                         valuePhis[i2].addInput(fieldState[i2]);
                         fieldState[i2] = valuePhis[i2];
                     }
                 }
             }
             for (BlockExitState other : withStates) {
-                if (vobjPhi != null) {
-                    vobjPhi.addInput(other.virtualObjectField);
-                }
                 for (int i2 = 0; i2 < fieldState.length; i2++) {
                     if (valuePhis[i2] != null) {
                         valuePhis[i2].addInput(other.fieldState[i2]);
                     }
                 }
             }
-            assert vobjPhi == null || vobjPhi.valueCount() == withStates.size() + 1;
-            for (int i2 = 0; i2 < fieldState.length; i2++) {
-                if (valuePhis[i2] != null) {
-                    virtualObjectField = graph.add(new VirtualObjectFieldNode(virtualObject, virtualObjectField, valuePhis[i2], i2));
-                    assert valuePhis[i2].valueCount() == withStates.size() + 1;
-                }
-            }
             return true;
         }
 
         @Override
         public void loopBegin(LoopBeginNode loopBegin) {
-            assert virtualObjectField != null : "unexpected null virtualObjectField";
-            PhiNode vobjPhi = null;
-            vobjPhi = graph.add(new PhiNode(CiKind.Illegal, loopBegin, PhiType.Virtual));
-            vobjPhi.addInput(virtualObjectField);
-            virtualObjectField = vobjPhi;
             for (int i2 = 0; i2 < fieldState.length; i2++) {
-                PhiNode valuePhi = graph.add(new PhiNode(fieldState[i2].kind(), loopBegin, PhiType.Value));
+                PhiNode valuePhi = graph.add(new PhiNode(fieldState[i2].kind(), loopBegin));
                 valuePhi.addInput(fieldState[i2]);
                 fieldState[i2] = valuePhi;
-                updateField(i2);
             }
         }
 
         @Override
         public void loopEnds(LoopBeginNode loopBegin, List<BlockExitState> loopEndStates) {
-            while (!loopBegin.isPhiAtMerge(virtualObjectField)) {
-                if (virtualObjectField instanceof PhiNode) {
-                    virtualObjectField = ((PhiNode) virtualObjectField).valueAt(0);
-                } else {
-                    virtualObjectField = ((VirtualObjectFieldNode) virtualObjectField).lastState();
-                }
-            }
             for (BlockExitState loopEndState : loopEndStates) {
-                ((PhiNode) virtualObjectField).addInput(loopEndState.virtualObjectField);
                 for (int i2 = 0; i2 < fieldState.length; i2++) {
                     ((PhiNode) fieldState[i2]).addInput(loopEndState.fieldState[i2]);
                 }
@@ -175,12 +140,19 @@
             }
         }
 
+        private void process() {
+            for (Node usage : node.usages().snapshot()) {
+                op.beforeUpdate(node, usage);
+            }
+        }
+
         public void removeAllocation() {
             escapeFields = op.fields(node);
             for (int i = 0; i < escapeFields.length; i++) {
                 fields.put(escapeFields[i].representation(), i);
             }
-            final VirtualObjectNode virtual = graph.add(new VirtualObjectNode(((ValueNode) node).exactType(), escapeFields));
+            assert node.objectStamp().isExactType();
+            final VirtualObjectNode virtual = graph.add(new VirtualObjectNode(node.objectStamp().type(), escapeFields));
             if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
                 TTY.println("new virtual object: " + virtual);
             }
@@ -188,9 +160,12 @@
             FixedNode next = node.next();
             graph.removeFixed(node);
 
-            for (ValueProxyNode vpn : virtual.usages().filter(ValueProxyNode.class).snapshot()) {
-                assert vpn.value() == virtual;
-                graph.replaceFloating(vpn, virtual);
+            List<ValueProxyNode> proxies;
+            while (!(proxies = virtual.usages().filter(ValueProxyNode.class).snapshot()).isEmpty()) {
+                for (ValueProxyNode vpn : proxies) {
+                    assert vpn.value() == virtual;
+                    graph.replaceFloating(vpn, virtual);
+                }
             }
 
             if (virtual.fieldsCount() > 0) {
@@ -198,52 +173,31 @@
                 final PostOrderNodeIterator<?> iterator = new PostOrderNodeIterator<BlockExitState>(next, startState) {
                     @Override
                     protected void node(FixedNode curNode) {
-                        int changedField = op.updateState(virtual, curNode, fields, state.fieldState);
-                        if (changedField != -1) {
-                            state.updateField(changedField);
-                        }
+                        op.updateState(virtual, curNode, fields, state.fieldState);
                         if (curNode instanceof LoopExitNode) {
-                            state.virtualObjectField = graph.unique(new ValueProxyNode(state.virtualObjectField, (LoopExitNode) curNode, PhiType.Virtual));
                             for (int i = 0; i < state.fieldState.length; i++) {
                                 state.fieldState[i] = graph.unique(new ValueProxyNode(state.fieldState[i], (LoopExitNode) curNode, PhiType.Value));
                             }
                         }
                         if (!curNode.isDeleted() && curNode instanceof StateSplit && ((StateSplit) curNode).stateAfter() != null) {
-                            if (state.virtualObjectField != null) {
-                                ValueNode v = state.virtualObjectField;
-                                if (curNode instanceof LoopBeginNode) {
-                                    while (!((LoopBeginNode) curNode).isPhiAtMerge(v)) {
-                                        if (v instanceof PhiNode) {
-                                            v = ((PhiNode) v).valueAt(0);
-                                        } else {
-                                            v = ((VirtualObjectFieldNode) v).lastState();
-                                        }
-                                    }
-                                }
-                                ((StateSplit) curNode).stateAfter().addVirtualObjectMapping(v);
-                            }
+                            VirtualObjectState v = graph.add(new VirtualObjectState(virtual, state.fieldState));
+                            ((StateSplit) curNode).stateAfter().addVirtualObjectMapping(v);
                         }
                     }
                 };
                 iterator.apply();
             }
         }
-
-        private void process() {
-            for (Node usage : node.usages().snapshot()) {
-                op.beforeUpdate(node, usage);
-            }
-        }
     }
 
-    private final CiTarget target;
-    private final GraalRuntime runtime;
-    private final CiAssumptions assumptions;
+    private final TargetDescription target;
+    private final ExtendedRiRuntime runtime;
+    private final Assumptions assumptions;
     private final RiGraphCache cache;
     private final PhasePlan plan;
     private final OptimisticOptimizations optimisticOpts;
 
-    public EscapeAnalysisPhase(CiTarget target, GraalRuntime runtime, CiAssumptions assumptions, RiGraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
+    public EscapeAnalysisPhase(TargetDescription target, ExtendedRiRuntime runtime, Assumptions assumptions, RiGraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
         this.runtime = runtime;
         this.target = target;
         this.assumptions = assumptions;
@@ -274,15 +228,15 @@
 
     private static Node escape(EscapeRecord record, Node usage) {
         final Node node = record.node;
-        if (usage instanceof FrameState) {
+        if (usage instanceof VirtualState) {
             assert usage.inputs().contains(node);
             return null;
         } else {
             if (usage instanceof FixedNode) {
                 record.localWeight += ((FixedNode) usage).probability();
             }
-            if (usage instanceof NullCheckNode) {
-                assert ((NullCheckNode) usage).object() == node;
+            if (usage instanceof IsNullNode) {
+                assert ((IsNullNode) usage).object() == node;
                 return null;
             } else if (usage instanceof IsTypeNode) {
                 assert ((IsTypeNode) usage).objectClass() == node;
@@ -314,8 +268,6 @@
                     // in order to not escape, the access needs to have a valid constant index and either a store into node or be self-referencing
                     return EscapeOp.isValidConstantIndex(x) && x.value() != node ? null : x.array();
                 }
-            } else if (usage instanceof VirtualObjectFieldNode) {
-                return null;
             } else if (usage instanceof RegisterFinalizerNode) {
                 assert ((RegisterFinalizerNode) usage).object() == node;
                 return null;
@@ -382,7 +334,7 @@
             double weight = analyze(op, node, exits, invokes);
             if (exits.size() != 0) {
                 if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
-                    TTY.println("%n####### escaping object: %s (%s)", node, node.exactType());
+                    TTY.println("%n####### escaping object: %s (%s)", node, node.stamp());
                     if (GraalOptions.TraceEscapeAnalysis) {
                         TTY.print("%d: new value: %s, weight %f, escapes at ", iterations, node, weight);
                         for (Node n : exits) {
@@ -399,7 +351,7 @@
             if (invokes.size() == 0) {
 
                 Debug.dump(graph, "Before escape %s", node);
-                Debug.log("!!!!!!!! non-escaping object: %s (%s)", node, node.exactType());
+                Debug.log("!!!!!!!! non-escaping object: %s (%s)", node, node.stamp());
                 removeAllocation(node, op);
                 Debug.dump(graph, "After escape", graph);
                 break;
@@ -420,7 +372,7 @@
             new DeadCodeEliminationPhase().apply(graph);
             if (node.isDeleted()) {
                 if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
-                    TTY.println("!!!!!!!! object died while performing escape analysis: %s (%s)", node, node.exactType());
+                    TTY.println("!!!!!!!! object died while performing escape analysis: %s (%s)", node, node.stamp());
                 }
                 break;
             }
@@ -463,7 +415,7 @@
         for (Node usage : node.usages().snapshot()) {
             boolean escapes = op.escape(node, usage);
             if (escapes) {
-                if (usage instanceof FrameState) {
+                if (usage instanceof VirtualState) {
                     // nothing to do...
                 } else if (usage instanceof MethodCallTargetNode) {
                     if (usage.usages().size() == 0) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/FloatingReadPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/FloatingReadPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.cfg.*;
@@ -50,7 +49,7 @@
             map.putAll(other.map);
         }
 
-        public void mergeLoopEntryWith(MemoryMap otherMemoryMap, LoopBeginNode begin) {
+        public void mergeLoopEntryWith(MemoryMap otherMemoryMap, LoopBeginNode begin, EndNode pred) {
             for (Object keyInOther : otherMemoryMap.map.keySet()) {
                 assert loopEntryMap.containsKey(keyInOther) || map.get(keyInOther) == otherMemoryMap.map.get(keyInOther) : keyInOther + ", " + map.get(keyInOther) + " vs " + otherMemoryMap.map.get(keyInOther) + " " + begin;
             }
@@ -65,7 +64,10 @@
                     other = otherMemoryMap.map.get(LocationNode.ANY_LOCATION);
                 }
 
-                phiNode.addInput((ValueNode) other);
+                // this explicitly honors the phi input index, since the iteration order will not always adhere to the end index ordering.
+                // TODO(ls) check for instances of this problem in other places.
+                int index = begin.phiPredecessorIndex(pred);
+                phiNode.initializeValueAt(index, (ValueNode) other);
             }
         }
 
@@ -113,7 +115,8 @@
                 Debug.log("Add new input to %s: %s.", original, newValue);
                 assert phi.valueCount() <= phi.merge().forwardEndCount() : phi.merge();
             } else {
-                PhiNode phi = m.graph().unique(new PhiNode(CiKind.Illegal, m, PhiType.Memory));
+                PhiNode phi = m.graph().unique(new PhiNode(PhiType.Memory, m));
+                // TODO(ls) how does this work? add documentation ...
                 for (int i = 0; i < mergeOperationCount + 1; ++i) {
                     phi.addInput((ValueNode) original);
                 }
@@ -135,6 +138,9 @@
         }
 
         public void processWrite(WriteNode writeNode) {
+            if (writeNode.location().locationIdentity() == LocationNode.ANY_LOCATION) {
+                map.clear();
+            }
             map.put(writeNode.location().locationIdentity(), writeNode);
         }
 
@@ -145,9 +151,20 @@
             Debug.log("Register read to node %s.", readNode);
             FloatingReadNode floatingRead;
             if (readNode.location().locationIdentity() == LocationNode.FINAL_LOCATION) {
-                floatingRead = graph.unique(new FloatingReadNode(readNode.object(), readNode.guard(), readNode.location(), readNode.stamp()));
+                floatingRead = graph.unique(new FloatingReadNode(readNode.object(), readNode.location(), null, readNode.stamp(), readNode.dependencies()));
             } else {
-                floatingRead = graph.unique(new FloatingReadNode(readNode.object(), readNode.guard(), readNode.location(), readNode.stamp(), getLocationForRead(readNode)));
+                floatingRead = graph.unique(new FloatingReadNode(readNode.object(), readNode.location(), getLocationForRead(readNode), readNode.stamp(), readNode.dependencies()));
+            }
+            floatingRead.setNullCheck(readNode.getNullCheck());
+            ValueAnchorNode anchor = null;
+            for (GuardNode guard : readNode.dependencies().filter(GuardNode.class)) {
+                if (anchor == null) {
+                    anchor = graph.add(new ValueAnchorNode());
+                }
+                anchor.addAnchoredNode(guard);
+            }
+            if (anchor != null) {
+                graph.addAfterFixed(readNode, anchor);
             }
             graph.replaceFixedWithFloating(readNode, floatingRead);
         }
@@ -185,7 +202,7 @@
         }
 
         private void createLoopEntryPhi(Object modifiedLocation, Node other, Loop loop) {
-            PhiNode phi = other.graph().unique(new PhiNode(CiKind.Illegal, (MergeNode) loop.header.getBeginNode(), PhiType.Memory));
+            PhiNode phi = other.graph().unique(new PhiNode(PhiType.Memory, (MergeNode) loop.header.getBeginNode()));
             phi.addInput((ValueNode) other);
             map.put(modifiedLocation, phi);
             loopEntryMap.put(modifiedLocation, phi);
@@ -293,7 +310,7 @@
             MemoryMap memoryMap = memoryMaps[beginBlock.getId()];
             assert memoryMap != null;
             assert memoryMap.getLoopEntryMap() != null;
-            memoryMap.mergeLoopEntryWith(map, begin);
+            memoryMap.mergeLoopEntryWith(map, begin, (EndNode) b.getEndNode());
         }
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IdentifyBoxingPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IdentifyBoxingPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,7 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -48,18 +47,18 @@
 
     public void tryIntrinsify(Invoke invoke) {
         MethodCallTargetNode callTarget = invoke.callTarget();
-        RiResolvedMethod targetMethod = callTarget.targetMethod();
+        ResolvedJavaMethod targetMethod = callTarget.targetMethod();
         if (pool.isSpecialMethod(targetMethod)) {
             assert callTarget.arguments().size() == 1 : "boxing/unboxing method must have exactly one argument";
-            CiKind returnKind = callTarget.returnKind();
+            Kind returnKind = callTarget.returnKind();
             ValueNode sourceValue = callTarget.arguments().get(0);
 
             // Check whether this is a boxing or an unboxing.
             Node newNode = null;
-            if (returnKind == CiKind.Object) {
+            if (returnKind == Kind.Object) {
                 // We have a boxing method here.
                 assert Modifier.isStatic(targetMethod.accessFlags()) : "boxing method must be static";
-                CiKind sourceKind = targetMethod.signature().argumentKindAt(0, false);
+                Kind sourceKind = targetMethod.signature().argumentKindAt(0);
                 newNode = invoke.graph().add(new BoxNode(sourceValue, targetMethod.holder(), sourceKind, invoke.bci()));
             } else {
                 // We have an unboxing method here.
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,6 +26,8 @@
 import java.util.*;
 import java.util.concurrent.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.compiler.util.*;
@@ -36,8 +38,6 @@
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 
 
 public class InliningPhase extends Phase implements InliningCallback {
@@ -47,13 +47,13 @@
      * - honor the result of overrideInliningDecision(0, caller, invoke.bci, method, true);
      */
 
-    private final CiTarget target;
-    private final GraalRuntime runtime;
+    private final TargetDescription target;
+    private final ExtendedRiRuntime runtime;
 
     private final Collection<? extends Invoke> hints;
 
     private final PriorityQueue<InlineInfo> inlineCandidates = new PriorityQueue<>();
-    private CiAssumptions assumptions;
+    private Assumptions assumptions;
 
     private final PhasePlan plan;
     private final RiGraphCache cache;
@@ -66,7 +66,7 @@
     private static final DebugMetric metricInliningConsidered = Debug.metric("InliningConsidered");
     private static final DebugMetric metricInliningStoppedByMaxDesiredSize = Debug.metric("InliningStoppedByMaxDesiredSize");
 
-    public InliningPhase(CiTarget target, GraalRuntime runtime, Collection<? extends Invoke> hints, CiAssumptions assumptions, RiGraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
+    public InliningPhase(TargetDescription target, ExtendedRiRuntime runtime, Collection<? extends Invoke> hints, Assumptions assumptions, RiGraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
         this.target = target;
         this.runtime = runtime;
         this.hints = hints;
@@ -80,33 +80,46 @@
 
     @SuppressWarnings("unchecked")
     @Override
-    protected void run(StructuredGraph graph) {
+    protected void run(final StructuredGraph graph) {
         graph.createNodeMap();
 
         if (hints != null) {
-            scanInvokes((Iterable<? extends Node>) Util.uncheckedCast(this.hints), -1, graph);
+            scanInvokes((Iterable<? extends Node>) Util.uncheckedCast(this.hints), -1);
         } else {
-            scanInvokes(graph.getNodes(InvokeNode.class), 0, graph);
-            scanInvokes(graph.getNodes(InvokeWithExceptionNode.class), 0, graph);
+            scanInvokes(graph.getNodes(InvokeNode.class), 0);
+            scanInvokes(graph.getNodes(InvokeWithExceptionNode.class), 0);
         }
 
         while (!inlineCandidates.isEmpty() && graph.getNodeCount() < GraalOptions.MaximumDesiredSize) {
-            InlineInfo info = inlineCandidates.remove();
-            if (info.invoke.node().isAlive() && inliningPolicy.isWorthInlining(graph, info)) {
+            InlineInfo candidate = inlineCandidates.remove();
+            if (!candidate.invoke.node().isAlive()) {
+                continue;
+            }
+            // refresh infos
+            final InlineInfo info = InliningUtil.getInlineInfo(candidate.invoke, candidate.level, runtime, assumptions, this, optimisticOpts);
+
+            boolean inline = Debug.scope("InliningDecisions", new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return info != null && inliningPolicy.isWorthInlining(graph, info);
+                }
+            });
+
+            if (inline) {
+                int mark = graph.getMark();
                 Iterable<Node> newNodes = null;
                 try {
                     info.inline(graph, runtime, this);
                     Debug.dump(graph, "after %s", info);
-                    // get the new nodes here, the canonicalizer phase will reset the mark
-                    newNodes = graph.getNewNodes();
+                    newNodes = graph.getNewNodes(mark);
                     if (GraalOptions.OptCanonicalizer) {
-                        new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph);
+                        new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph);
                     }
 //                    if (GraalOptions.Intrinsify) {
 //                        new IntrinsificationPhase(runtime).apply(graph);
 //                    }
                     metricInliningPerformed.increment();
-                } catch (CiBailout bailout) {
+                } catch (BailoutException bailout) {
                     // TODO determine if we should really bail out of the whole compilation.
                     throw bailout;
                 } catch (AssertionError e) {
@@ -118,30 +131,40 @@
                 }
 
                 if (newNodes != null && info.level < GraalOptions.MaximumInlineLevel) {
-                    scanInvokes(newNodes, info.level + 1, graph);
+                    scanInvokes(newNodes, info.level + 1);
                 }
             }
         }
 
         if (GraalOptions.Debug && graph.getNodeCount() >= GraalOptions.MaximumDesiredSize) {
-            Debug.log("inlining cut off by MaximumDesiredSize");
+            Debug.scope("InliningDecisions", new Runnable() {
+                public void run() {
+                    for (InlineInfo info : inlineCandidates) {
+                        Debug.log("not inlining %s because inlining cut off by MaximumDesiredSize", InliningUtil.methodName(info));
+                    }
+                }
+            });
+
             metricInliningStoppedByMaxDesiredSize.increment();
         }
     }
 
-    private void scanInvokes(Iterable<? extends Node> newNodes, int level, StructuredGraph graph) {
-        graph.mark();
-        for (Node node : newNodes) {
-            if (node != null) {
-                if (node instanceof Invoke) {
-                    Invoke invoke = (Invoke) node;
-                    scanInvoke(invoke, level);
-                }
-                for (Node usage : node.usages().filterInterface(Invoke.class).snapshot()) {
-                    scanInvoke((Invoke) usage, level);
+    private void scanInvokes(final Iterable<? extends Node> nodes, final int level) {
+        Debug.scope("InliningDecisions", new Runnable() {
+            public void run() {
+                for (Node node : nodes) {
+                    if (node != null) {
+                        if (node instanceof Invoke) {
+                            Invoke invoke = (Invoke) node;
+                            scanInvoke(invoke, level);
+                        }
+                        for (Node usage : node.usages().filterInterface(Invoke.class).snapshot()) {
+                            scanInvoke((Invoke) usage, level);
+                        }
+                    }
                 }
             }
-        }
+        });
     }
 
     private void scanInvoke(Invoke invoke, int level) {
@@ -153,14 +176,14 @@
         }
     }
 
-    public static final Map<RiMethod, Integer> parsedMethods = new HashMap<>();
+    public static final Map<JavaMethod, Integer> parsedMethods = new HashMap<>();
 
 
 
     private static final DebugMetric metricInliningRuns = Debug.metric("Runs");
 
     @Override
-    public StructuredGraph buildGraph(final RiResolvedMethod method) {
+    public StructuredGraph buildGraph(final ResolvedJavaMethod method) {
         final StructuredGraph newGraph = new StructuredGraph(method);
 
         return Debug.scope("buildInlineGraph", this, new Callable<StructuredGraph>() {
@@ -190,6 +213,9 @@
                 if (GraalOptions.Intrinsify) {
                     new IntrinsificationPhase(runtime).apply(newGraph);
                 }
+                if (GraalOptions.CullFrameStates) {
+                    new CullFrameStatesPhase().apply(newGraph);
+                }
                 if (GraalOptions.CacheGraphs && cache != null) {
                     cache.put(newGraph);
                 }
@@ -199,7 +225,7 @@
     }
 
     @Override
-    public double inliningWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke) {
+    public double inliningWeight(ResolvedJavaMethod caller, ResolvedJavaMethod method, Invoke invoke) {
         boolean preferred = hints != null && hints.contains(invoke);
         return weightComputationPolicy.computeWeight(caller, method, invoke, preferred);
     }
@@ -224,12 +250,12 @@
 
 
     @Override
-    public void recordConcreteMethodAssumption(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl) {
+    public void recordConcreteMethodAssumption(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
         assumptions.recordConcreteMethod(method, context, impl);
     }
 
     @Override
-    public void recordMethodContentsAssumption(RiResolvedMethod method) {
+    public void recordMethodContentsAssumption(ResolvedJavaMethod method) {
         if (assumptions != null) {
             assumptions.recordMethodContents(method);
         }
@@ -282,11 +308,11 @@
 
             double penalty = Math.pow(GraalOptions.InliningSizePenaltyExp, callerGraph.getNodeCount() / (double) GraalOptions.MaximumDesiredSize) / GraalOptions.InliningSizePenaltyExp;
             if (info.weight > GraalOptions.MaximumInlineWeight / (1 + penalty * GraalOptions.InliningSizePenalty)) {
-                Debug.log("not inlining (cut off by weight %e): %s", info.weight, info);
+                Debug.log("not inlining %s (cut off by weight %e)", InliningUtil.methodName(info), info.weight);
                 return false;
             }
 
-            Debug.log("inlining (weight %f): %s", info.weight, info);
+            Debug.log("inlining %s (weight %f): %s", InliningUtil.methodName(info), info.weight);
             return true;
         }
     }
@@ -342,9 +368,9 @@
 
             double maxSize = GraalOptions.MaximumGreedyInlineSize;
             if (GraalOptions.InliningBonusPerTransferredValue != 0) {
-                RiSignature signature = info.invoke.callTarget().targetMethod().signature();
+                Signature signature = info.invoke.callTarget().targetMethod().signature();
                 int transferredValues = signature.argumentCount(!Modifier.isStatic(info.invoke.callTarget().targetMethod().accessFlags()));
-                if (signature.returnKind(false) != CiKind.Void) {
+                if (signature.returnKind() != Kind.Void) {
                     transferredValues++;
                 }
                 maxSize += transferredValues * GraalOptions.InliningBonusPerTransferredValue;
@@ -361,15 +387,15 @@
     private static boolean decideSizeBasedInlining(InlineInfo info, double maxSize) {
         boolean success = info.weight <= maxSize;
         if (DebugScope.getInstance().isLogEnabled()) {
-            String formatterString = success ? "inlining invoke at %s@%d (size %f <= %f): %s" : "not inlining invoke at %s@%d (too large %f > %f): %s";
-            Debug.log(formatterString, CiUtil.format("%H.%n(%p):%r", info.invoke.stateAfter().method()), info.invoke.bci(), info.weight, maxSize, info);
+            String formatterString = success ? "inlining %s (size %f <= %f)" : "not inlining %s (too large %f > %f)";
+            Debug.log(formatterString, InliningUtil.methodName(info), info.weight, maxSize);
         }
         return success;
     }
 
     private static boolean checkCompiledCodeSize(InlineInfo info) {
         if (GraalOptions.SmallCompiledCodeSize >= 0 && info.compiledCodeSize() > GraalOptions.SmallCompiledCodeSize) {
-            Debug.log("not inlining invoke at %s@%d (CompiledCodeSize %d > %d): %s", CiUtil.format("%H.%n(%p):%r", info.invoke.stateAfter().method()), info.invoke.bci(), info.compiledCodeSize(), GraalOptions.SmallCompiledCodeSize, info);
+            Debug.log("not inlining %s (CompiledCodeSize %d > %d)", InliningUtil.methodName(info), info.compiledCodeSize(), GraalOptions.SmallCompiledCodeSize);
             return false;
         }
         return true;
@@ -377,12 +403,12 @@
 
 
     private interface WeightComputationPolicy {
-        double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke);
+        double computeWeight(ResolvedJavaMethod caller, ResolvedJavaMethod method, Invoke invoke, boolean preferredInvoke);
     }
 
     private static class BytecodeSizeBasedWeightComputationPolicy implements WeightComputationPolicy {
         @Override
-        public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) {
+        public double computeWeight(ResolvedJavaMethod caller, ResolvedJavaMethod method, Invoke invoke, boolean preferredInvoke) {
             double codeSize = method.codeSize();
             if (preferredInvoke) {
                 codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis;
@@ -393,7 +419,7 @@
 
     private static class ComplexityBasedWeightComputationPolicy implements WeightComputationPolicy {
         @Override
-        public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) {
+        public double computeWeight(ResolvedJavaMethod caller, ResolvedJavaMethod method, Invoke invoke, boolean preferredInvoke) {
             double complexity = method.compilationComplexity();
             if (preferredInvoke) {
                 complexity = complexity / GraalOptions.BoostInliningForEscapeAnalysis;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -29,22 +29,35 @@
 
 public class InsertStateAfterPlaceholderPhase extends Phase {
 
-    private static class PlaceholderNode extends AbstractStateSplit implements Node.IterableNodeType, LIRLowerable {
+    private static class PlaceholderNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, LIRLowerable, Canonicalizable {
         public PlaceholderNode() {
-            super(StampFactory.illegal());
+            super(StampFactory.forVoid());
         }
 
         @Override
         public void generate(LIRGeneratorTool gen) {
             // nothing to do
         }
+
+        @Override
+        public boolean hasSideEffect() {
+            return false;
+        }
+
+        @Override
+        public ValueNode canonical(CanonicalizerTool tool) {
+            if (stateAfter() == null) {
+                return null;
+            }
+            return this;
+        }
     }
 
     @Override
     protected void run(StructuredGraph graph) {
         for (ReturnNode ret : graph.getNodes(ReturnNode.class)) {
             PlaceholderNode p = graph.add(new PlaceholderNode());
-            p.setStateAfter(graph.add(new FrameState(null, FrameState.AFTER_BCI, 0, 0, false, false)));
+            p.setStateAfter(graph.add(new FrameState(FrameState.AFTER_BCI)));
             graph.addBeforeFixed(ret, p);
         }
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IntrinsificationPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/IntrinsificationPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.phases;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.util.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.debug.*;
@@ -31,9 +31,9 @@
 
 public class IntrinsificationPhase extends Phase {
 
-    private final GraalRuntime runtime;
+    private final ExtendedRiRuntime runtime;
 
-    public IntrinsificationPhase(GraalRuntime runtime) {
+    public IntrinsificationPhase(ExtendedRiRuntime runtime) {
         this.runtime = runtime;
     }
 
@@ -47,18 +47,18 @@
         }
     }
 
-    public static boolean canIntrinsify(Invoke invoke, RiResolvedMethod target, GraalRuntime runtime) {
+    public static boolean canIntrinsify(Invoke invoke, ResolvedJavaMethod target, ExtendedRiRuntime runtime) {
         return getIntrinsicGraph(invoke, target, runtime) != null;
     }
 
-    private static void tryIntrinsify(Invoke invoke, GraalRuntime runtime) {
-        RiResolvedMethod target = invoke.callTarget().targetMethod();
+    private static void tryIntrinsify(Invoke invoke, ExtendedRiRuntime runtime) {
+        ResolvedJavaMethod target = invoke.callTarget().targetMethod();
         if (target != null) {
             tryIntrinsify(invoke, target, runtime);
         }
     }
 
-    private static void tryIntrinsify(Invoke invoke, RiResolvedMethod target, GraalRuntime runtime) {
+    private static void tryIntrinsify(Invoke invoke, ResolvedJavaMethod target, ExtendedRiRuntime runtime) {
         StructuredGraph intrinsicGraph = getIntrinsicGraph(invoke, target, runtime);
         if (intrinsicGraph != null) {
             Debug.log(" > Intrinsify %s", target);
@@ -66,7 +66,7 @@
         }
     }
 
-    private static StructuredGraph getIntrinsicGraph(Invoke invoke, RiResolvedMethod target, GraalRuntime runtime) {
+    private static StructuredGraph getIntrinsicGraph(Invoke invoke, ResolvedJavaMethod target, ExtendedRiRuntime runtime) {
         StructuredGraph intrinsicGraph = (StructuredGraph) target.compilerStorage().get(Graph.class);
         if (intrinsicGraph == null) {
             // TODO remove once all intrinsics are available via compilerStorage
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopFullUnrollPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 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.compiler.phases;
+
+import com.oracle.graal.compiler.loop.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+
+
+public class LoopFullUnrollPhase extends Phase {
+    private static final DebugMetric FULLY_UNROLLED_LOOPS = Debug.metric("FullUnrolls");
+    private final ExtendedRiRuntime runtime;
+
+    public LoopFullUnrollPhase(ExtendedRiRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        if (graph.hasLoops()) {
+            boolean peeled;
+            do {
+                peeled = false;
+                final LoopsData dataCounted = new LoopsData(graph);
+                dataCounted.detectedCountedLoops();
+                for (LoopEx loop : dataCounted.countedLoops()) {
+                    if (LoopPolicies.shouldFullUnroll(loop)) {
+                        Debug.log("FullUnroll %s", loop);
+                        LoopTransformations.fullUnroll(loop, runtime);
+                        FULLY_UNROLLED_LOOPS.increment();
+                        Debug.dump(graph, "After fullUnroll %s", loop);
+                        peeled = true;
+                        break;
+                    }
+                }
+            } while(peeled);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformHighPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 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.compiler.phases;
+
+import com.oracle.graal.compiler.loop.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+
+public class LoopTransformHighPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        if (graph.hasLoops()) {
+            LoopsData data = new LoopsData(graph);
+            for (LoopEx loop : data.outterFirst()) {
+                if (LoopPolicies.shouldPeel(loop)) {
+                    Debug.log("Peeling %s", loop);
+                    LoopTransformations.peel(loop);
+                    Debug.dump(graph, "After peeling %s", loop);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2012, 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.compiler.phases;
+
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.loop.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+
+public class LoopTransformLowPhase extends Phase {
+    private static final DebugMetric UNSWITCHED = Debug.metric("Unswitched");
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        if (graph.hasLoops()) {
+            if (GraalOptions.ReassociateInvariants) {
+                final LoopsData dataReassociate = new LoopsData(graph);
+                Debug.scope("ReassociateInvariants", new Runnable() {
+                    @Override
+                    public void run() {
+                        for (LoopEx loop : dataReassociate.loops()) {
+                            loop.reassociateInvariants();
+                        }
+                    }
+                });
+            }
+            if (GraalOptions.LoopUnswitch) {
+                NodeBitMap unswitchedDebug = graph.createNodeBitMap();
+                boolean unswitched;
+                do {
+                    unswitched = false;
+                    final LoopsData dataUnswitch = new LoopsData(graph);
+                    for (LoopEx loop : dataUnswitch.loops()) {
+                        if (LoopPolicies.shouldTryUnswitch(loop)) {
+                            IfNode ifNode = LoopTransformations.findUnswitchableIf(loop);
+                            if (ifNode != null && !unswitchedDebug.isMarked(ifNode)) {
+                                unswitchedDebug.mark(ifNode);
+                                Debug.log("Unswitching %s at %s [%f - %f]", loop, ifNode, ifNode.probability(0), ifNode.probability(1));
+                                //LoopTransformations.unswitch(loop, ifNode);
+                                UNSWITCHED.increment();
+                                //Debug.dump(graph, "After unswitch %s", loop);
+                                unswitched = true;
+                                break;
+                            }
+                        }
+                    }
+                } while(unswitched);
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,9 @@
  */
 package com.oracle.graal.compiler.phases;
 
-import java.util.*;
-
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.loop.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 
 public class LoopTransformPhase extends Phase {
@@ -35,21 +32,13 @@
     @Override
     protected void run(StructuredGraph graph) {
         if (graph.hasLoops()) {
-            ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
-            Loop[] loops = cfg.getLoops();
-            // outermost first
-            Arrays.sort(loops, new Comparator<Loop>() {
-                @Override
-                public int compare(Loop o1, Loop o2) {
-                    return o1.depth - o2.depth;
-                }
-            });
-            for (Loop loop : loops) {
+            LoopsData data = new LoopsData(graph);
+            for (LoopEx loop : data.outterFirst()) {
                 double entryProbability = loop.loopBegin().forwardEnd().probability();
                 if (entryProbability > GraalOptions.MinimumPeelProbability
-                                && LoopTransformUtil.estimateSize(loop) + graph.getNodeCount() < GraalOptions.MaximumDesiredSize) {
+                                && loop.size() + graph.getNodeCount() < GraalOptions.MaximumDesiredSize) {
                     Debug.log("Peeling %s", loop);
-                    LoopTransformUtil.peel(loop);
+                    LoopTransformations.peel(loop);
                     Debug.dump(graph, "After peeling %s", loop);
                 }
             }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,55 +22,89 @@
  */
 package com.oracle.graal.compiler.phases;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.cri.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.max.cri.ri.*;
 
 /**
  * Processes all {@link Lowerable} nodes to do their lowering.
  */
 public class LoweringPhase extends Phase {
 
-    private final GraalRuntime runtime;
+    private class LoweringToolBase implements CiLoweringTool {
+
+        @Override
+        public ExtendedRiRuntime getRuntime() {
+            return runtime;
+        }
+
+        @Override
+        public ValueNode getGuardAnchor() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ValueNode createNullCheckGuard(ValueNode object, long leafGraphId) {
+            return createGuard(object.graph().unique(new IsNullNode(object)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true, leafGraphId);
+        }
 
-    public LoweringPhase(GraalRuntime runtime) {
+        @Override
+        public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, long leafGraphId) {
+            return createGuard(condition, deoptReason, action, false, leafGraphId);
+        }
+
+        @Override
+        public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+            // TODO (thomaswue): Document why this must not be called on floating nodes.
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Assumptions assumptions() {
+            return assumptions;
+        }
+    }
+
+    private final ExtendedRiRuntime runtime;
+    private final Assumptions assumptions;
+
+    public LoweringPhase(ExtendedRiRuntime runtime, Assumptions assumptions) {
         this.runtime = runtime;
+        this.assumptions = assumptions;
     }
 
     @Override
     protected void run(final StructuredGraph graph) {
-        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, false, true, true);
-
+        // Step 1: repeatedly lower fixed nodes until no new ones are created
         NodeBitMap processed = graph.createNodeBitMap();
-        NodeBitMap activeGuards = graph.createNodeBitMap();
-        processBlock(cfg.getStartBlock(), activeGuards, processed, null);
+        int  i = 0;
+        while (true) {
+            int mark = graph.getMark();
+            ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, false, true, true);
+            processBlock(cfg.getStartBlock(), graph.createNodeBitMap(), processed, null);
+            Debug.dump(graph, "Lowering iteration %d", i++);
+            new CanonicalizerPhase(null, runtime, assumptions, mark, null).apply(graph);
 
-        processed.negate();
-        final CiLoweringTool loweringTool = new CiLoweringTool() {
-
-            @Override
-            public Node getGuardAnchor() {
-                throw new UnsupportedOperationException();
+            if (graph.getNewNodes(mark).filter(FixedNode.class).isEmpty()) {
+                break;
             }
-
-            @Override
-            public GraalRuntime getRuntime() {
-                return runtime;
-            }
+            assert graph.verify();
+            processed.grow();
+        }
 
-            @Override
-            public Node createGuard(Node condition, RiDeoptReason deoptReason, RiDeoptAction action, long leafGraphId) {
-                // TODO (thomaswue): Document why this must not be called on floating nodes.
-                throw new UnsupportedOperationException();
-            }
-        };
+        // Step 2: lower the floating nodes
+        processed.negate();
+        final CiLoweringTool loweringTool = new LoweringToolBase();
         for (Node node : processed) {
             if (node instanceof Lowerable) {
-                assert !(node instanceof FixedNode) || node.predecessor() == null;
+                assert !(node instanceof FixedNode) || node.predecessor() == null : node;
                 ((Lowerable) node).lower(loweringTool);
             }
         }
@@ -99,49 +133,48 @@
             }
         }
 
-        if (parentAnchor == null) {
+        if (parentAnchor == null && GraalOptions.OptEliminateGuards) {
             for (GuardNode guard : anchor.usages().filter(GuardNode.class)) {
                 activeGuards.clear(guard);
             }
         }
     }
 
-    private void process(final Block b, final NodeBitMap activeGuards, NodeBitMap processed, final Node anchor) {
+    private void process(final Block b, final NodeBitMap activeGuards, NodeBitMap processed, final ValueNode anchor) {
 
-        final CiLoweringTool loweringTool = new CiLoweringTool() {
+        final CiLoweringTool loweringTool = new LoweringToolBase() {
 
             @Override
-            public Node getGuardAnchor() {
+            public ValueNode getGuardAnchor() {
                 return anchor;
             }
 
             @Override
-            public GraalRuntime getRuntime() {
-                return runtime;
-            }
-
-            @Override
-            public Node createGuard(Node condition, RiDeoptReason deoptReason, RiDeoptAction action, long leafGraphId) {
+            public ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId) {
                 FixedNode guardAnchor = (FixedNode) getGuardAnchor();
                 if (GraalOptions.OptEliminateGuards) {
                     for (Node usage : condition.usages()) {
-                        if (activeGuards.isMarked(usage)) {
-                            return usage;
+                        if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage)) {
+                            return (ValueNode) usage;
                         }
                     }
                 }
-                GuardNode newGuard = guardAnchor.graph().unique(new GuardNode((BooleanNode) condition, guardAnchor, deoptReason, action, leafGraphId));
-                activeGuards.grow();
-                activeGuards.mark(newGuard);
+                GuardNode newGuard = guardAnchor.graph().unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated, leafGraphId));
+                if (GraalOptions.OptEliminateGuards) {
+                    activeGuards.grow();
+                    activeGuards.mark(newGuard);
+                }
                 return newGuard;
             }
         };
 
         // Lower the instructions of this block.
         for (Node node : b.getNodes()) {
-            processed.mark(node);
-            if (node instanceof Lowerable) {
-                ((Lowerable) node).lower(loweringTool);
+            if (!processed.isMarked(node)) {
+                processed.mark(node);
+                if (node instanceof Lowerable) {
+                    ((Lowerable) node).lower(loweringTool);
+                }
             }
         }
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/PhiStampPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/PhiStampPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -43,7 +43,7 @@
     }
 
     private void iterativeInferPhi(PhiNode phi) {
-        if (phi.inferStamp()) {
+        if (phi.inferPhiStamp()) {
             for (PhiNode phiUsage : phi.usages().filter(PhiNode.class)) {
                 iterativeInferPhi(phiUsage);
             }
@@ -56,6 +56,6 @@
                 inferPhi(phiInput);
             }
         }
-        phi.inferStamp();
+        phi.inferPhiStamp();
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ReadEliminationPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/ReadEliminationPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -32,9 +32,8 @@
     @Override
     protected void run(StructuredGraph graph) {
         for (FloatingReadNode n : graph.getNodes(FloatingReadNode.class)) {
-            if (n.dependencies().size() > 0) {
-                assert n.dependencies().size() == 1;
-                Node memoryInput = n.dependencies().get(0);
+            if (n.lastLocationAccess() != null) {
+                Node memoryInput = n.lastLocationAccess();
                 if (memoryInput instanceof WriteNode) {
                     WriteNode other = (WriteNode) memoryInput;
                     if (other.object() == n.object() && other.location() == n.location()) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2011, 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.compiler.phases;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.ConstantNodeParameter;
-import com.oracle.graal.graph.Node.Fold;
-import com.oracle.graal.graph.Node.NodeIntrinsic;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-
-public class SnippetIntrinsificationPhase extends Phase {
-
-    private final RiRuntime runtime;
-    private final BoxingMethodPool pool;
-
-    public SnippetIntrinsificationPhase(RiRuntime runtime, BoxingMethodPool pool) {
-        this.runtime = runtime;
-        this.pool = pool;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (Invoke i : graph.getInvokes()) {
-            tryIntrinsify(i);
-        }
-    }
-
-    private void tryIntrinsify(Invoke invoke) {
-        RiResolvedMethod target = invoke.callTarget().targetMethod();
-        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
-        if (intrinsic != null) {
-            assert target.getAnnotation(Node.Fold.class) == null;
-
-            Class< ? >[] parameterTypes = CiUtil.signatureToTypes(target.signature(), target.holder());
-
-            // Prepare the arguments for the reflective constructor call on the node class.
-            Object[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target, false);
-
-            // Create the new node instance.
-            Class< ? > c = getNodeClass(target, intrinsic);
-            Node newInstance = createNodeInstance(c, parameterTypes, nodeConstructorArguments);
-
-            // Replace the invoke with the new node.
-            invoke.node().graph().add(newInstance);
-            invoke.intrinsify(newInstance);
-
-            // Clean up checkcast instructions inserted by javac if the return type is generic.
-            cleanUpReturnCheckCast(newInstance);
-        } else if (target.getAnnotation(Node.Fold.class) != null) {
-            Class< ? >[] parameterTypes = CiUtil.signatureToTypes(target.signature(), target.holder());
-
-            // Prepare the arguments for the reflective method call
-            Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
-            Object receiver = null;
-            if (!invoke.callTarget().isStatic()) {
-                receiver = arguments[0];
-                arguments = Arrays.asList(arguments).subList(1, arguments.length).toArray();
-            }
-
-            // Call the method
-            CiConstant constant = callMethod(target.signature().returnKind(false), target.holder().toJava(), target.name(), parameterTypes, receiver, arguments);
-
-            if (constant != null) {
-                // Replace the invoke with the result of the call
-                ConstantNode node = ConstantNode.forCiConstant(constant, runtime, invoke.node().graph());
-                invoke.intrinsify(node);
-
-                // Clean up checkcast instructions inserted by javac if the return type is generic.
-                cleanUpReturnCheckCast(node);
-            } else {
-                // Remove the invoke
-                invoke.intrinsify(null);
-            }
-        }
-    }
-
-    /**
-     * Converts the arguments of an invoke node to object values suitable for use as the arguments
-     * to a reflective invocation of a Java constructor or method.
-     *
-     * @param folding specifies if the invocation is for handling a {@link Fold} annotation
-     */
-    private Object[] prepareArguments(Invoke invoke, Class< ? >[] parameterTypes, RiResolvedMethod target, boolean folding) {
-        NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
-        Object[] reflectionCallArguments = new Object[arguments.size()];
-        for (int i = 0; i < reflectionCallArguments.length; ++i) {
-            int parameterIndex = i;
-            if (!invoke.callTarget().isStatic()) {
-                parameterIndex--;
-            }
-            ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
-            if (folding || CiUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) {
-                assert argument instanceof ConstantNode : "parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + ": " + argument;
-                ConstantNode constantNode = (ConstantNode) argument;
-                Object o = constantNode.asConstant().boxedValue();
-                if (o instanceof Class< ? >) {
-                    reflectionCallArguments[i] = runtime.getType((Class< ? >) o);
-                    parameterTypes[i] = RiResolvedType.class;
-                } else {
-                    reflectionCallArguments[i] = o;
-                }
-            } else {
-                reflectionCallArguments[i] = argument;
-                parameterTypes[i] = ValueNode.class;
-            }
-        }
-        return reflectionCallArguments;
-    }
-
-    private static Class< ? > getNodeClass(RiResolvedMethod target, NodeIntrinsic intrinsic) {
-        Class< ? > result = intrinsic.value();
-        if (result == NodeIntrinsic.class) {
-            result = target.holder().toJava();
-        }
-        assert Node.class.isAssignableFrom(result);
-        return result;
-    }
-
-    private ValueNode tryBoxingElimination(int parameterIndex, RiResolvedMethod target, ValueNode node) {
-        if (parameterIndex >= 0) {
-            Type type = target.getGenericParameterTypes()[parameterIndex];
-            if (type instanceof TypeVariable) {
-                TypeVariable typeVariable = (TypeVariable) type;
-                if (typeVariable.getBounds().length == 1) {
-                    Type boundType = typeVariable.getBounds()[0];
-                    if (boundType instanceof Class && ((Class) boundType).getSuperclass() == null) {
-                        // Unbound generic => try boxing elimination
-                        if (node.usages().size() == 2) {
-                            if (node instanceof Invoke) {
-                                Invoke invokeNode = (Invoke) node;
-                                MethodCallTargetNode callTarget = invokeNode.callTarget();
-                                if (pool.isBoxingMethod(callTarget.targetMethod())) {
-                                    FrameState stateAfter = invokeNode.stateAfter();
-                                    assert stateAfter.usages().size() == 1;
-                                    invokeNode.node().replaceAtUsages(null);
-                                    ValueNode result = callTarget.arguments().get(0);
-                                    StructuredGraph graph = (StructuredGraph) node.graph();
-                                    if (invokeNode instanceof InvokeWithExceptionNode) {
-                                        // Destroy exception edge & clear stateAfter.
-                                        InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
-
-                                        invokeWithExceptionNode.killExceptionEdge();
-                                        graph.removeSplit(invokeWithExceptionNode, InvokeWithExceptionNode.NORMAL_EDGE);
-                                    } else {
-                                        graph.removeFixed((InvokeNode) invokeNode);
-                                    }
-                                    stateAfter.safeDelete();
-                                    GraphUtil.propagateKill(callTarget);
-                                    return result;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return node;
-    }
-
-    private static Node createNodeInstance(Class< ? > nodeClass, Class< ? >[] parameterTypes, Object[] nodeConstructorArguments) {
-
-        Constructor< ? > constructor;
-        try {
-            constructor = nodeClass.getDeclaredConstructor(parameterTypes);
-            constructor.setAccessible(true);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        try {
-            return (ValueNode) constructor.newInstance(nodeConstructorArguments);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Calls a Java method via reflection.
-     */
-    private static CiConstant callMethod(CiKind returnKind, Class< ? > holder, String name, Class< ? >[] parameterTypes, Object receiver, Object[] arguments) {
-        Method method;
-        try {
-            method = holder.getDeclaredMethod(name, parameterTypes);
-            method.setAccessible(true);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        try {
-            Object result = method.invoke(receiver, arguments);
-            if (result == null) {
-                return null;
-            }
-            return CiConstant.forBoxed(returnKind, result);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void cleanUpReturnCheckCast(Node newInstance) {
-        if (newInstance instanceof ValueNode && ((ValueNode) newInstance).kind() != CiKind.Object) {
-            StructuredGraph graph = (StructuredGraph) newInstance.graph();
-            for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) {
-                for (ValueProxyNode vpn : checkCastNode.usages().filter(ValueProxyNode.class).snapshot()) {
-                    graph.replaceFloating(vpn, checkCastNode);
-                }
-                for (Node checkCastUsage : checkCastNode.usages().snapshot()) {
-                    if (checkCastUsage instanceof ValueAnchorNode) {
-                        ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage;
-                        graph.removeFixed(valueAnchorNode);
-                    } else if (checkCastUsage instanceof MethodCallTargetNode) {
-                        MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage;
-                        assert pool.isUnboxingMethod(checkCastCallTarget.targetMethod());
-                        Invoke invokeNode = checkCastCallTarget.invoke();
-                        invokeNode.node().replaceAtUsages(newInstance);
-                        if (invokeNode instanceof InvokeWithExceptionNode) {
-                            // Destroy exception edge & clear stateAfter.
-                            InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
-
-                            invokeWithExceptionNode.killExceptionEdge();
-                            graph.removeSplit(invokeWithExceptionNode, InvokeWithExceptionNode.NORMAL_EDGE);
-                        } else {
-                            graph.removeFixed((InvokeNode) invokeNode);
-                        }
-                        checkCastCallTarget.safeDelete();
-                    } else if (checkCastUsage instanceof FrameState) {
-                        checkCastUsage.replaceFirstInput(checkCastNode, null);
-                    } else {
-                        assert false : "unexpected checkcast usage: " + checkCastUsage;
-                    }
-                }
-                checkCastNode.safeDelete();
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/schedule/SchedulePhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/schedule/SchedulePhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -41,7 +41,7 @@
     /**
      * Map from blocks to the nodes in each block.
      */
-    private BlockMap<List<Node>> blockToNodesMap;
+    private BlockMap<List<ScheduledNode>> blockToNodesMap;
 
     public SchedulePhase() {
         super("Schedule");
@@ -57,17 +57,20 @@
         sortNodesWithinBlocks(graph);
     }
 
+    /**
+     * Sets {@link ScheduledNode#scheduledNext} on all scheduled nodes in all blocks using the scheduling built by @link {@link #run(StructuredGraph)}.
+     * This method should thus only be called when run has been successfully executed.
+     */
     public void scheduleGraph() {
+        assert blockToNodesMap != null : "cannot set scheduledNext before run has been executed";
         for (Block block : cfg.getBlocks()) {
-            List<Node> nodeList = blockToNodesMap.get(block);
+            List<ScheduledNode> nodeList = blockToNodesMap.get(block);
             ScheduledNode last = null;
-            for (Node node : nodeList) {
-                if (!(node instanceof FrameState)) {
-                    if (last != null) {
-                        last.setScheduledNext((ScheduledNode) node);
-                    }
-                    last = (ScheduledNode) node;
+            for (ScheduledNode node : nodeList) {
+                if (last != null) {
+                    last.setScheduledNext(node);
                 }
+                last = node;
             }
         }
     }
@@ -79,79 +82,86 @@
     /**
      * Gets the map from each block to the nodes in the block.
      */
-    public BlockMap<List<Node>> getBlockToNodesMap() {
+    public BlockMap<List<ScheduledNode>> getBlockToNodesMap() {
         return blockToNodesMap;
     }
 
     /**
      * Gets the nodes in a given block.
      */
-    public List<Node> nodesFor(Block block) {
+    public List<ScheduledNode> nodesFor(Block block) {
         return blockToNodesMap.get(block);
     }
 
     private void assignBlockToNodes(StructuredGraph graph) {
         for (Block block : cfg.getBlocks()) {
-            List<Node> nodes = new ArrayList<>();
+            List<ScheduledNode> nodes = new ArrayList<>();
             assert blockToNodesMap.get(block) == null;
             blockToNodesMap.put(block, nodes);
-            for (Node node : block.getNodes()) {
+            for (FixedNode node : block.getNodes()) {
                 nodes.add(node);
             }
         }
 
         for (Node n : graph.getNodes()) {
-            assignBlockToNode(n);
+            if (n instanceof ScheduledNode) {
+                assignBlockToNode((ScheduledNode) n);
+            }
         }
     }
 
-    private void assignBlockToNode(Node n) {
-        if (n == null) {
-            return;
-        }
+    /**
+     * Assigns a block to the given node. This method expects that PhiNodes and FixedNodes are already assigned to a
+     * block, since they should already have been placed by {@link ControlFlowGraph#identifyBlocks()}.
+     * This method will also try to
+     */
+    private void assignBlockToNode(ScheduledNode node) {
+        assert !node.isDeleted();
 
-        assert !n.isDeleted();
-
-        Block prevBlock = cfg.getNodeToBlock().get(n);
+        Block prevBlock = cfg.getNodeToBlock().get(node);
         if (prevBlock != null) {
             return;
         }
-        assert !(n instanceof PhiNode) : n;
-        assert !(n instanceof MergeNode);
+        // PhiNodes and FixedNodes should already have been placed in blocks by ControlFlowGraph.identifyBlocks
+        assert !(node instanceof PhiNode) : node;
+        assert !(node instanceof FixedNode) : node;
         // if in CFG, schedule at the latest position possible in the outermost loop possible
-        Block latestBlock = latestBlock(n);
+        Block latestBlock = latestBlock(node);
         Block block;
         if (latestBlock == null) {
-            block = earliestBlock(n);
-        } else if (GraalOptions.ScheduleOutOfLoops && !(n instanceof VirtualObjectFieldNode) && !(n instanceof VirtualObjectNode)) {
-            Block earliestBlock = earliestBlock(n);
-            block = scheduleOutOfLoops(n, latestBlock, earliestBlock);
-            assert earliestBlock.dominates(block) : "Graph can not be scheduled : inconsistent for " + n;
+            block = earliestBlock(node);
+        } else if (GraalOptions.ScheduleOutOfLoops && !(node instanceof VirtualObjectNode)) {
+            Block earliestBlock = earliestBlock(node);
+            block = scheduleOutOfLoops(node, latestBlock, earliestBlock);
+            assert earliestBlock.dominates(block) : "Graph can not be scheduled : inconsistent for " + node + " (" + earliestBlock + " needs to dominate " + block + ")";
         } else {
             block = latestBlock;
         }
-        cfg.getNodeToBlock().set(n, block);
-        blockToNodesMap.get(block).add(n);
+        cfg.getNodeToBlock().set(node, block);
+        blockToNodesMap.get(block).add(node);
     }
 
-    private Block latestBlock(Node n) {
-        Block block = null;
-        for (Node succ : n.successors()) {
-            if (succ == null) {
-                continue;
-            }
-            assignBlockToNode(succ);
-            block = getCommonDominator(block, cfg.getNodeToBlock().get(succ));
+    /**
+     * Calculates the last block that the given node could be scheduled in, i.e., the common dominator of all usages.
+     * To do so all usages are also assigned to blocks.
+     */
+    private Block latestBlock(ScheduledNode node) {
+        CommonDominatorBlockClosure cdbc = new CommonDominatorBlockClosure(null);
+        for (Node succ : node.successors().nonNull()) {
+            assert cfg.getNodeToBlock().get(succ) != null;
+            cdbc.apply(cfg.getNodeToBlock().get(succ));
         }
-        ensureScheduledUsages(n);
-        CommonDominatorBlockClosure cdbc = new CommonDominatorBlockClosure(block);
-        for (Node usage : n.usages()) {
-            blocksForUsage(n, usage, cdbc);
+        ensureScheduledUsages(node);
+        for (Node usage : node.usages()) {
+            blocksForUsage(node, usage, cdbc);
         }
         return cdbc.block;
     }
 
-    private class CommonDominatorBlockClosure implements BlockClosure {
+    /**
+     * A closure that will calculate the common dominator of all blocks passed to its {@link #apply(Block)} method.
+     */
+    private static class CommonDominatorBlockClosure implements BlockClosure {
         public Block block;
         public CommonDominatorBlockClosure(Block block) {
             this.block = block;
@@ -162,42 +172,45 @@
         }
     }
 
-    private Block earliestBlock(Node n) {
-        Block earliest = cfg.getNodeToBlock().get(n);
+    /**
+     * Determines the earliest block in which the given node can be scheduled.
+     */
+    private Block earliestBlock(Node node) {
+        Block earliest = cfg.getNodeToBlock().get(node);
         if (earliest != null) {
             return earliest;
         }
-        earliest = earliestCache.get(n);
+        earliest = earliestCache.get(node);
         if (earliest != null) {
             return earliest;
         }
-        BitMap bits = new BitMap(cfg.getBlocks().length);
-        ArrayList<Node> before = new ArrayList<>();
-        if (n.predecessor() != null) {
-            before.add(n.predecessor());
-        }
-        for (Node input : n.inputs()) {
-            before.add(input);
-        }
-        for (Node pred : before) {
-            if (pred == null) {
-                continue;
-            }
-            Block b = earliestBlock(pred);
-            if (!bits.get(b.getId())) {
-                earliest = b;
+        /*
+         * All inputs must be in a dominating block, otherwise the graph cannot be scheduled. This implies that the
+         * inputs' blocks have a total ordering via their dominance relation. So in order to find the earliest block
+         * placement for this node we need to find the input block that is dominated by all other input blocks.
+         *
+         * While iterating over the inputs a set of dominator blocks of the current earliest placement is maintained.
+         * When the block of an input is not within this set, it becomes the current earliest placement and the list of
+         * dominator blocks is updated.
+         */
+        BitSet dominators = new BitSet(cfg.getBlocks().length);
+
+        assert node.predecessor() == null;
+        for (Node input : node.inputs().nonNull()) {
+            assert input instanceof ValueNode;
+            Block inputEarliest = earliestBlock(input);
+            if (!dominators.get(inputEarliest.getId())) {
+                earliest = inputEarliest;
                 do {
-                    bits.set(b.getId());
-                    b = b.getDominator();
-                } while(b != null && !bits.get(b.getId()));
+                    dominators.set(inputEarliest.getId());
+                    inputEarliest = inputEarliest.getDominator();
+                } while(inputEarliest != null && !dominators.get(inputEarliest.getId()));
             }
         }
         if (earliest == null) {
-            Block start = cfg.getNodeToBlock().get(((StructuredGraph) n.graph()).start());
-            assert start != null;
-            return start;
+            earliest = cfg.getStartBlock();
         }
-        earliestCache.set(n, earliest);
+        earliestCache.set(node, earliest);
         return earliest;
     }
 
@@ -216,8 +229,20 @@
         return result;
     }
 
-    private void blocksForUsage(Node node, Node usage, BlockClosure closure) {
+    /**
+     * Passes all blocks that a specific usage of a node is in to a given closure.
+     * This is more complex than just taking the usage's block because of of PhiNodes and FrameStates.
+     *
+     * @param node the node that needs to be scheduled
+     * @param usage the usage whose blocks need to be considered
+     * @param closure the closure that will be called for each block
+     */
+    private void blocksForUsage(ScheduledNode node, Node usage, BlockClosure closure) {
+        assert !(node instanceof PhiNode);
+
         if (usage instanceof PhiNode) {
+            // An input to a PhiNode is used at the end of the predecessor block that corresponds to the PhiNode input.
+            // One PhiNode can use an input multiple times, the closure will be called for each usage.
             PhiNode phi = (PhiNode) usage;
             MergeNode merge = phi.merge();
             Block mergeBlock = cfg.getNodeToBlock().get(merge);
@@ -235,22 +260,38 @@
                     closure.apply(mergeBlock.getPredecessors().get(i));
                 }
             }
-        } else if (usage instanceof FrameState && ((FrameState) usage).block() != null) {
-            MergeNode merge = ((FrameState) usage).block();
-            Block block = null;
-            for (Node pred : merge.cfgPredecessors()) {
-                block = getCommonDominator(block, cfg.getNodeToBlock().get(pred));
+        } else if (usage instanceof VirtualState) {
+            // The following logic does not work if node is a PhiNode, but this method is never called for PhiNodes.
+            for (Node unscheduledUsage : usage.usages()) {
+                if (unscheduledUsage instanceof VirtualState) {
+                    // If a FrameState is an outer FrameState this method behaves as if the inner FrameState was the actual usage, by recursing.
+                    blocksForUsage(node, unscheduledUsage, closure);
+                } else if (unscheduledUsage instanceof MergeNode) {
+                    // Only FrameStates can be connected to MergeNodes.
+                    assert usage instanceof FrameState;
+                    // If a FrameState belongs to a MergeNode then it's inputs will be placed at the common dominator of all EndNodes.
+                    for (Node pred : unscheduledUsage.cfgPredecessors()) {
+                        closure.apply(cfg.getNodeToBlock().get(pred));
+                    }
+                } else {
+                    // For the time being, only FrameStates can be connected to StateSplits.
+                    assert usage instanceof FrameState;
+                    assert unscheduledUsage instanceof StateSplit;
+                    // Otherwise: Put the input into the same block as the usage.
+                    assignBlockToNode((ScheduledNode) unscheduledUsage);
+                    closure.apply(cfg.getNodeToBlock().get(unscheduledUsage));
+                }
             }
-            closure.apply(block);
         } else {
-            assignBlockToNode(usage);
+            // All other types of usages: Put the input into the same block as the usage.
+            assignBlockToNode((ScheduledNode) usage);
             closure.apply(cfg.getNodeToBlock().get(usage));
         }
     }
 
     private void ensureScheduledUsages(Node node) {
-        for (Node usage : node.usages().snapshot()) {
-            assignBlockToNode(usage);
+        for (Node usage : node.usages().filter(ScheduledNode.class)) {
+            assignBlockToNode((ScheduledNode) usage);
         }
         // now true usages are ready
     }
@@ -266,21 +307,25 @@
     }
 
     private void sortNodesWithinBlocks(StructuredGraph graph) {
-        NodeBitMap map = graph.createNodeBitMap();
+        NodeBitMap visited = graph.createNodeBitMap();
         for (Block b : cfg.getBlocks()) {
-            sortNodesWithinBlocks(b, map);
+            sortNodesWithinBlock(b, visited);
         }
     }
 
-    private void sortNodesWithinBlocks(Block b, NodeBitMap map) {
-        List<Node> instructions = blockToNodesMap.get(b);
-        List<Node> sortedInstructions = new ArrayList<>(instructions.size() + 2);
+    /**
+     * Sorts the nodes within a block by adding the nodes to a list in a post-order iteration over all inputs.
+     * This means that a node is added to the list after all its inputs have been processed.
+     */
+    private void sortNodesWithinBlock(Block b, NodeBitMap visited) {
+        List<ScheduledNode> instructions = blockToNodesMap.get(b);
+        List<ScheduledNode> sortedInstructions = new ArrayList<>(instructions.size() + 2);
 
-        assert !map.isMarked(b.getBeginNode()) && cfg.blockFor(b.getBeginNode()) == b;
-        assert !map.isMarked(b.getEndNode()) && cfg.blockFor(b.getEndNode()) == b;
+        assert !visited.isMarked(b.getBeginNode()) && cfg.blockFor(b.getBeginNode()) == b;
+        assert !visited.isMarked(b.getEndNode()) && cfg.blockFor(b.getEndNode()) == b;
 
-        for (Node i : instructions) {
-            addToSorting(b, i, sortedInstructions, map);
+        for (ScheduledNode i : instructions) {
+            addToSorting(b, i, sortedInstructions, visited);
         }
 
         // Make sure that last node gets really last (i.e. when a frame state successor hangs off it).
@@ -310,32 +355,45 @@
         blockToNodesMap.put(b, sortedInstructions);
     }
 
-    private void addToSorting(Block b, Node i, List<Node> sortedInstructions, NodeBitMap map) {
-        if (i == null || map.isMarked(i) || cfg.getNodeToBlock().get(i) != b || i instanceof PhiNode || i instanceof LocalNode) {
+    private void addUnscheduledToSorting(Block b, VirtualState state, List<ScheduledNode> sortedInstructions, NodeBitMap visited) {
+        if (state != null) {
+            // UnscheduledNodes should never be marked as visited.
+            assert !visited.isMarked(state);
+
+            for (Node input : state.inputs()) {
+                if (input instanceof VirtualState) {
+                    addUnscheduledToSorting(b, (VirtualState) input, sortedInstructions, visited);
+                } else {
+                    addToSorting(b, (ScheduledNode) input, sortedInstructions, visited);
+                }
+            }
+        }
+    }
+
+    private void addToSorting(Block b, ScheduledNode i, List<ScheduledNode> sortedInstructions, NodeBitMap visited) {
+        if (i == null || visited.isMarked(i) || cfg.getNodeToBlock().get(i) != b || i instanceof PhiNode || i instanceof LocalNode) {
             return;
         }
 
         FrameState state = null;
-        WriteNode writeNode = null;
+        WriteNode write = null;
         for (Node input : i.inputs()) {
-            if (input instanceof WriteNode && !map.isMarked(input) && cfg.getNodeToBlock().get(input) == b) {
-                writeNode = (WriteNode) input;
+            if (input instanceof WriteNode && !visited.isMarked(input) && cfg.getNodeToBlock().get(input) == b) {
+                assert write == null;
+                write = (WriteNode) input;
             } else if (input instanceof FrameState) {
+                assert state == null;
                 state = (FrameState) input;
             } else {
-                addToSorting(b, input, sortedInstructions, map);
+                addToSorting(b, (ScheduledNode) input, sortedInstructions, visited);
             }
         }
 
-        if (i.predecessor() != null) {
-            addToSorting(b, i.predecessor(), sortedInstructions, map);
-        }
-
-        map.mark(i);
-
-        addToSorting(b, state, sortedInstructions, map);
-        assert writeNode == null || !map.isMarked(writeNode);
-        addToSorting(b, writeNode, sortedInstructions, map);
+        addToSorting(b, (ScheduledNode) i.predecessor(), sortedInstructions, visited);
+        visited.mark(i);
+        addUnscheduledToSorting(b, state, sortedInstructions, visited);
+        assert write == null || !visited.isMarked(write);
+        addToSorting(b, write, sortedInstructions, visited);
 
         // Now predecessors and inputs are scheduled => we can add this node.
         sortedInstructions.add(i);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/schedule/UnscheduleNodes.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2012, 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.compiler.schedule;
-
-import java.util.*;
-
-import com.oracle.graal.compiler.graph.*;
-import com.oracle.graal.compiler.types.*;
-import com.oracle.graal.nodes.*;
-
-class UnscheduleState implements MergeableState<UnscheduleState> {
-
-    public FixedWithNextNode last;
-
-    @Override
-    public boolean merge(MergeNode merge, List<UnscheduleState> withStates) {
-        last = null;
-        return true;
-    }
-
-    @Override
-    public void loopBegin(LoopBeginNode loop) {
-        last = null;
-    }
-
-    @Override
-    public void loopEnds(LoopBeginNode loop, List<UnscheduleState> loopEndStates) {
-        last = null;
-    }
-
-    @Override
-    public void afterSplit(FixedNode node) {
-        last = null;
-    }
-
-    @Override
-    public UnscheduleState clone() {
-        return new UnscheduleState();
-    }
-}
-
-public class UnscheduleNodes extends ScheduledNodeIterator<UnscheduleState> {
-
-    public UnscheduleNodes(FixedNode start) {
-        super(start, new UnscheduleState());
-    }
-
-    @Override
-    protected void node(ScheduledNode node) {
-        if (node instanceof FixedNode) {
-            if (state.last != null) {
-                state.last.setNext((FixedNode) node);
-            }
-            if (node instanceof FixedWithNextNode) {
-                state.last = (FixedWithNextNode) node;
-            }
-        } else {
-            node.setScheduledNext(null);
-        }
-    }
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,13 +24,13 @@
 
 import java.lang.reflect.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 
 /**
@@ -40,14 +40,14 @@
 
     /**
      * The name of the system property whose value (if non-null) specifies the fully qualified
-     * name of the class to be instantiated by {@link #create(RiRuntime, CiTarget)}.
+     * name of the class to be instantiated by {@link #create(CodeCacheProvider, TargetDescription)}.
      */
     public static final String BACKEND_CLASS_PROPERTY = "graal.compiler.backend.class";
 
-    public final RiRuntime runtime;
-    public final CiTarget target;
+    public final CodeCacheProvider runtime;
+    public final TargetDescription target;
 
-    protected Backend(RiRuntime runtime, CiTarget target) {
+    protected Backend(CodeCacheProvider runtime, TargetDescription target) {
         this.runtime = runtime;
         this.target = target;
     }
@@ -56,23 +56,23 @@
      * Creates the architecture and runtime specific back-end object.
      * The class of the object instantiated must be in the {@link #BACKEND_CLASS_PROPERTY} system property.
      */
-    public static Backend create(RiRuntime runtime, CiTarget target) {
+    public static Backend create(CodeCacheProvider runtime, TargetDescription target) {
         String className = System.getProperty(BACKEND_CLASS_PROPERTY);
         assert className != null : "System property must be defined: " + BACKEND_CLASS_PROPERTY;
         try {
             Class<?> c = Class.forName(className);
-            Constructor<?> cons = c.getDeclaredConstructor(RiRuntime.class, CiTarget.class);
+            Constructor<?> cons = c.getDeclaredConstructor(CodeCacheProvider.class, TargetDescription.class);
             return (Backend) cons.newInstance(runtime, target);
         } catch (Exception e) {
             throw new Error("Could not instantiate " + className, e);
         }
     }
 
-    public FrameMap newFrameMap(RiRegisterConfig registerConfig) {
+    public FrameMap newFrameMap(RegisterConfig registerConfig) {
         return new FrameMap(runtime, target, registerConfig);
     }
 
-    public abstract LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir);
+    public abstract LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir, RiXirGenerator xir, Assumptions assumptions);
 
     public abstract TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir);
 
@@ -110,5 +110,5 @@
      * @param the method associated with {@code lir}
      * @param lir the LIR of {@code method}
      */
-    public abstract void emitCode(TargetMethodAssembler tasm, RiResolvedMethod method, LIR lir);
+    public abstract void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/LIRGenLowerable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2011, 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.compiler.target;
+
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * An alternative to {@link LIRLowerable} for lowering that is tightly coupled
+ * to {@link LIRGenerator} and {@link LIRInstruction}.
+ */
+public interface LIRGenLowerable {
+
+    void generate(LIRGenerator generator);
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,23 +24,23 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 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 AMD64Code {
     public final Label label = new Label();
     public final LIRDebugInfo info;
-    public final RiDeoptAction action;
-    public final RiDeoptReason reason;
+    public final DeoptimizationAction action;
+    public final DeoptimizationReason reason;
     public final Object deoptInfo;
 
-    public AMD64DeoptimizationStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo) {
+    public AMD64DeoptimizationStub(DeoptimizationAction action, DeoptimizationReason reason, LIRDebugInfo info, Object deoptInfo) {
         this.action = action;
         this.reason = reason;
         this.info = info;
@@ -52,20 +52,20 @@
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         // TODO (cwimmer): we want to get rid of a generally reserved scratch register.
-        CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
+        Register scratch = tasm.frameMap.registerConfig.getScratchRegister();
 
         masm.bind(label);
         if (GraalOptions.CreateDeoptInfo && deoptInfo != null) {
             masm.nop();
             keepAlive.add(deoptInfo.toString());
-            AMD64Move.move(tasm, masm, scratch.asValue(), CiConstant.forObject(deoptInfo));
+            AMD64Move.move(tasm, masm, scratch.asValue(), Constant.forObject(deoptInfo));
             // TODO Make this an explicit calling convention instead of using a scratch register
-            AMD64Call.directCall(tasm, masm, CiRuntimeCall.SetDeoptInfo, info);
+            AMD64Call.directCall(tasm, masm, RuntimeCall.SetDeoptInfo, info);
         }
 
         masm.movl(scratch, tasm.runtime.encodeDeoptActionAndReason(action, reason));
         // TODO Make this an explicit calling convention instead of using a scratch register
-        AMD64Call.directCall(tasm, masm, CiRuntimeCall.Deoptimize, info);
+        AMD64Call.directCall(tasm, masm, RuntimeCall.Deoptimize, info);
         AMD64Call.shouldNotReachHere(tasm, masm);
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,7 +23,7 @@
 
 package com.oracle.graal.compiler.target.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*;
 import static com.oracle.graal.lir.amd64.AMD64Compare.*;
 
@@ -31,17 +31,20 @@
 
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.Mark;
-import com.oracle.max.cri.ri.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
 import com.oracle.max.cri.xir.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.util.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.StandardOp.LabelOp;
+import com.oracle.graal.lir.LIRValueUtil;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.DivOp;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Reg;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op1Stack;
@@ -51,12 +54,7 @@
 import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp;
 import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp;
 import com.oracle.graal.lir.amd64.AMD64Compare.CompareOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.BranchOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatBranchOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.FloatCondMoveOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.ReturnOp;
-import com.oracle.graal.lir.amd64.AMD64ControlFlow.TableSwitchOp;
+import com.oracle.graal.lir.amd64.AMD64ControlFlow.*;
 import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LeaOp;
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
@@ -76,41 +74,41 @@
  */
 public abstract class AMD64LIRGenerator extends LIRGenerator {
 
-    private static final CiRegisterValue RAX_I = AMD64.rax.asValue(CiKind.Int);
-    private static final CiRegisterValue RAX_L = AMD64.rax.asValue(CiKind.Long);
-    private static final CiRegisterValue RDX_I = AMD64.rdx.asValue(CiKind.Int);
-    private static final CiRegisterValue RDX_L = AMD64.rdx.asValue(CiKind.Long);
-    private static final CiRegisterValue RCX_I = AMD64.rcx.asValue(CiKind.Int);
+    private static final RegisterValue RAX_I = AMD64.rax.asValue(Kind.Int);
+    private static final RegisterValue RAX_L = AMD64.rax.asValue(Kind.Long);
+    private static final RegisterValue RDX_I = AMD64.rdx.asValue(Kind.Int);
+    private static final RegisterValue RDX_L = AMD64.rdx.asValue(Kind.Long);
+    private static final RegisterValue RCX_I = AMD64.rcx.asValue(Kind.Int);
 
     public static class AMD64SpillMoveFactory implements LIR.SpillMoveFactory {
         @Override
-        public LIRInstruction createMove(CiValue result, CiValue input) {
+        public LIRInstruction createMove(Value result, Value input) {
             return new SpillMoveOp(result, input);
         }
 
         @Override
-        public LIRInstruction createExchange(CiValue input1, CiValue input2) {
+        public LIRInstruction createExchange(Value input1, Value input2) {
             // TODO (cwimmer) implement XCHG operation for LIR
             return null;
         }
     }
 
-    public AMD64LIRGenerator(Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
-        super(graph, runtime, target, frameMap, method, lir, xir);
+    public AMD64LIRGenerator(Graph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir, RiXirGenerator xir, Assumptions assumptions) {
+        super(graph, runtime, target, frameMap, method, lir, xir, assumptions);
         lir.spillMoveFactory = new AMD64SpillMoveFactory();
     }
 
     @Override
     protected void emitNode(ValueNode node) {
-        if (node instanceof AMD64LIRLowerable) {
-            ((AMD64LIRLowerable) node).generateAmd64(this);
+        if (node instanceof LIRGenLowerable) {
+            ((LIRGenLowerable) node).generate(this);
         } else {
             super.emitNode(node);
         }
     }
 
     @Override
-    public boolean canStoreConstant(CiConstant c) {
+    public boolean canStoreConstant(Constant c) {
         // there is no immediate move of 64-bit constants on Intel
         switch (c.kind) {
             case Long:   return Util.isInt(c.asLong());
@@ -121,7 +119,7 @@
     }
 
     @Override
-    public boolean canInlineConstant(CiConstant c) {
+    public boolean canInlineConstant(Constant c) {
         switch (c.kind) {
             case Long:   return NumUtil.isInt(c.asLong());
             case Object: return c.isNull();
@@ -130,17 +128,22 @@
     }
 
     @Override
-    public CiAddress makeAddress(LocationNode location, ValueNode object) {
-        CiValue base = operand(object);
-        CiValue index = CiValue.IllegalValue;
+    public Address makeAddress(LocationNode location, ValueNode object) {
+        Value base = operand(object);
+        Value index = Value.IllegalValue;
         int scale = 1;
-        long displacement = location.displacement();
+        int displacement = location.displacement();
 
         if (isConstant(base)) {
-            if (!asConstant(base).isNull()) {
-                displacement += asConstant(base).asLong();
+            if (asConstant(base).isNull()) {
+                base = Value.IllegalValue;
+            } else if (asConstant(base).kind != Kind.Object) {
+                long newDisplacement = displacement + asConstant(base).asLong();
+                if (NumUtil.isInt(newDisplacement)) {
+                    displacement = (int) newDisplacement;
+                    base = Value.IllegalValue;
+                }
             }
-            base = CiValue.IllegalValue;
         }
 
         if (location instanceof IndexedLocationNode) {
@@ -154,29 +157,29 @@
                 long newDisplacement = displacement + asConstant(index).asLong() * scale;
                 // only use the constant index if the resulting displacement fits into a 32 bit offset
                 if (NumUtil.isInt(newDisplacement)) {
-                    displacement = newDisplacement;
-                    index = CiValue.IllegalValue;
+                    displacement = (int) newDisplacement;
+                    index = Value.IllegalValue;
                 } else {
                     // create a temporary variable for the index, the pointer load cannot handle a constant index
-                    CiValue newIndex = newVariable(CiKind.Long);
+                    Value newIndex = newVariable(Kind.Long);
                     emitMove(index, newIndex);
                     index = newIndex;
                 }
             }
         }
 
-        return new CiAddress(location.getValueKind(), base, index, CiAddress.Scale.fromInt(scale), (int) displacement);
+        return new Address(location.getValueKind(), base, index, Address.Scale.fromInt(scale), displacement);
     }
 
     @Override
-    public Variable emitMove(CiValue input) {
+    public Variable emitMove(Value input) {
         Variable result = newVariable(input.kind);
         emitMove(input, result);
         return result;
     }
 
     @Override
-    public void emitMove(CiValue src, CiValue dst) {
+    public void emitMove(Value src, Value dst) {
         if (isRegister(src) || isStackSlot(dst)) {
             append(new MoveFromRegOp(dst, src));
         } else {
@@ -185,20 +188,20 @@
     }
 
     @Override
-    public Variable emitLoad(CiValue loadAddress, boolean canTrap) {
+    public Variable emitLoad(Value loadAddress, boolean canTrap) {
         Variable result = newVariable(loadAddress.kind);
         append(new LoadOp(result, loadAddress, canTrap ? state() : null));
         return result;
     }
 
     @Override
-    public void emitStore(CiValue storeAddress, CiValue inputVal, boolean canTrap) {
-        CiValue input = loadForStore(inputVal, storeAddress.kind);
+    public void emitStore(Value storeAddress, Value inputVal, boolean canTrap) {
+        Value input = loadForStore(inputVal, storeAddress.kind);
         append(new StoreOp(storeAddress, input, canTrap ? state() : null));
     }
 
     @Override
-    public Variable emitLea(CiValue address) {
+    public Variable emitLea(Value address) {
         Variable result = newVariable(target().wordKind);
         append(new LeaOp(result, address));
         return result;
@@ -215,40 +218,57 @@
     }
 
     @Override
-    public void emitBranch(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info) {
-        emitCompare(left, right);
-        switch (left.kind) {
-            case Boolean:
+    public void emitBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRDebugInfo info) {
+        boolean mirrored = emitCompare(left, right);
+        Condition finalCondition = mirrored ? cond.mirror() : cond;
+        switch (left.kind.stackKind()) {
             case Int:
             case Long:
-            case Object: append(new BranchOp(cond, label, info)); break;
+            case Object: append(new BranchOp(finalCondition, label, info)); break;
             case Float:
-            case Double: append(new FloatBranchOp(cond, unorderedIsTrue, label, info)); break;
+            case Double: append(new FloatBranchOp(finalCondition, unorderedIsTrue, label, info)); break;
             default: throw GraalInternalError.shouldNotReachHere("" + left.kind);
         }
     }
 
     @Override
-    public Variable emitCMove(CiValue left, CiValue right, Condition cond, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue) {
-        emitCompare(left, right);
+    public Variable emitCMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+        boolean mirrored = emitCompare(left, right);
+        Condition finalCondition = mirrored ? cond.mirror() : cond;
 
         Variable result = newVariable(trueValue.kind);
-        switch (left.kind) {
-            case Boolean:
+        switch (left.kind.stackKind()) {
             case Int:
             case Long:
-            case Object: append(new CondMoveOp(result, cond, load(trueValue), loadNonConst(falseValue))); break;
+            case Object: append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); break;
             case Float:
-            case Double: append(new FloatCondMoveOp(result, cond, unorderedIsTrue, load(trueValue), load(falseValue))); break;
+            case Double: append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); break;
 
         }
         return result;
     }
 
-    private void emitCompare(CiValue a, CiValue b) {
-        Variable left = load(a);
-        CiValue right = loadNonConst(b);
-        switch (left.kind) {
+    /**
+     * This method emits the compare instruction, and may reorder the operands. It returns true if it did so.
+     *
+     * @param a the left operand of the comparison
+     * @param b the right operand of the comparison
+     * @return true if the left and right operands were switched, false otherwise
+     */
+    private boolean emitCompare(Value a, Value b) {
+        Variable left;
+        Value right;
+        boolean mirrored;
+        if (LIRValueUtil.isVariable(b)) {
+            left = load(b);
+            right = loadNonConst(a);
+            mirrored = true;
+        } else {
+            left = load(a);
+            right = loadNonConst(b);
+            mirrored = false;
+        }
+        switch (left.kind.stackKind()) {
             case Jsr:
             case Int: append(new CompareOp(ICMP, left, right)); break;
             case Long: append(new CompareOp(LCMP, left, right)); break;
@@ -257,23 +277,24 @@
             case Double: append(new CompareOp(DCMP, left, right)); break;
             default: throw GraalInternalError.shouldNotReachHere();
         }
+        return mirrored;
     }
 
     @Override
-    public Variable emitNegate(CiValue input) {
+    public Variable emitNegate(Value input) {
         Variable result = newVariable(input.kind);
         switch (input.kind) {
             case Int:    append(new Op1Stack(INEG, result, input)); break;
             case Long:   append(new Op1Stack(LNEG, result, input)); break;
-            case Float:  append(new Op2Reg(FXOR, result, input, CiConstant.forFloat(Float.intBitsToFloat(0x80000000)))); break;
-            case Double: append(new Op2Reg(DXOR, result, input, CiConstant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); break;
+            case Float:  append(new Op2Reg(FXOR, result, input, Constant.forFloat(Float.intBitsToFloat(0x80000000)))); break;
+            case Double: append(new Op2Reg(DXOR, result, input, Constant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); break;
             default: throw GraalInternalError.shouldNotReachHere();
         }
         return result;
     }
 
     @Override
-    public Variable emitAdd(CiValue a, CiValue b) {
+    public Variable emitAdd(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
             case Int:    append(new Op2Stack(IADD, result, a, loadNonConst(b))); break;
@@ -286,7 +307,7 @@
     }
 
     @Override
-    public Variable emitSub(CiValue a, CiValue b) {
+    public Variable emitSub(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
             case Int:    append(new Op2Stack(ISUB, result, a, loadNonConst(b))); break;
@@ -299,7 +320,7 @@
     }
 
     @Override
-    public Variable emitMul(CiValue a, CiValue b) {
+    public Variable emitMul(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
             case Int:    append(new Op2Reg(IMUL, result, a, loadNonConst(b))); break;
@@ -312,7 +333,7 @@
     }
 
     @Override
-    public Variable emitDiv(CiValue a, CiValue b) {
+    public Variable emitDiv(Value a, Value b) {
         switch(a.kind) {
             case Int:
                 emitMove(a, RAX_I);
@@ -338,7 +359,7 @@
     }
 
     @Override
-    public Variable emitRem(CiValue a, CiValue b) {
+    public Value emitRem(Value a, Value b) {
         switch(a.kind) {
             case Int:
                 emitMove(a, RAX_I);
@@ -349,16 +370,16 @@
                 append(new DivOp(LREM, RDX_L, RAX_L, load(b), state()));
                 return emitMove(RDX_L);
             case Float:
-                return emitCallToRuntime(CiRuntimeCall.ArithmeticFrem, false, a, b);
+                return emitCall(RuntimeCall.ArithmeticFrem, false, a, b);
             case Double:
-                return emitCallToRuntime(CiRuntimeCall.ArithmeticDrem, false, a, b);
+                return emitCall(RuntimeCall.ArithmeticDrem, false, a, b);
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
 
     @Override
-    public Variable emitUDiv(CiValue a, CiValue b) {
+    public Variable emitUDiv(Value a, Value b) {
         switch(a.kind) {
             case Int:
                 emitMove(a, RAX_I);
@@ -374,7 +395,7 @@
     }
 
     @Override
-    public Variable emitURem(CiValue a, CiValue b) {
+    public Variable emitURem(Value a, Value b) {
         switch(a.kind) {
             case Int:
                 emitMove(a, RAX_I);
@@ -391,7 +412,7 @@
 
 
     @Override
-    public Variable emitAnd(CiValue a, CiValue b) {
+    public Variable emitAnd(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
             case Int:    append(new Op2Stack(IAND, result, a, loadNonConst(b))); break;
@@ -402,7 +423,7 @@
     }
 
     @Override
-    public Variable emitOr(CiValue a, CiValue b) {
+    public Variable emitOr(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
             case Int:    append(new Op2Stack(IOR, result, a, loadNonConst(b))); break;
@@ -413,7 +434,7 @@
     }
 
     @Override
-    public Variable emitXor(CiValue a, CiValue b) {
+    public Variable emitXor(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch(a.kind) {
             case Int:    append(new Op2Stack(IXOR, result, a, loadNonConst(b))); break;
@@ -425,7 +446,7 @@
 
 
     @Override
-    public Variable emitShl(CiValue a, CiValue b) {
+    public Variable emitShl(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch (a.kind) {
             case Int:    append(new ShiftOp(ISHL, result, a, loadShiftCount(b))); break;
@@ -436,7 +457,7 @@
     }
 
     @Override
-    public Variable emitShr(CiValue a, CiValue b) {
+    public Variable emitShr(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch (a.kind) {
             case Int:    append(new ShiftOp(ISHR, result, a, loadShiftCount(b))); break;
@@ -447,7 +468,7 @@
     }
 
     @Override
-    public Variable emitUShr(CiValue a, CiValue b) {
+    public Variable emitUShr(Value a, Value b) {
         Variable result = newVariable(a.kind);
         switch (a.kind) {
             case Int:    append(new ShiftOp(IUSHR, result, a, loadShiftCount(b))); break;
@@ -457,7 +478,7 @@
         return result;
     }
 
-    private CiValue loadShiftCount(CiValue value) {
+    private Value loadShiftCount(Value value) {
         if (isConstant(value)) {
             return value;
         }
@@ -468,7 +489,7 @@
 
 
     @Override
-    public Variable emitConvert(ConvertNode.Op opcode, CiValue inputVal) {
+    public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) {
         Variable input = load(inputVal);
         Variable result = newVariable(opcode.to);
         switch (opcode) {
@@ -498,16 +519,15 @@
 
 
     @Override
-    public void emitDeoptimizeOn(Condition cond, RiDeoptAction action, RiDeoptReason reason, Object deoptInfo) {
-        assert cond != null;
+    public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo) {
         LIRDebugInfo info = state();
         LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo);
-        append(new BranchOp(cond, stubEntry, info));
+        append(new BranchOp(ConditionFlag.overflow, stubEntry, info));
     }
 
 
     @Override
-    public void emitDeoptimize(RiDeoptAction action, RiDeoptReason reason, Object deoptInfo, long leafGraphId) {
+    public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo, long leafGraphId) {
         LIRDebugInfo info = state(leafGraphId);
         LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo);
         append(new JumpOp(stubEntry, info));
@@ -522,73 +542,87 @@
     }
 
     @Override
-    protected void emitCall(Object targetMethod, CiValue result, List<CiValue> arguments, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+    protected void emitCall(Object targetMethod, Value result, List<Value> arguments, Value targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
         if (isConstant(targetAddress)) {
-            assert asConstant(targetAddress).isDefaultValue() : "destination address should be zero";
-            append(new DirectCallOp(targetMethod, result, arguments.toArray(new CiValue[arguments.size()]), info, marks));
+            append(new DirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), info, marks));
         } else {
-            append(new IndirectCallOp(targetMethod, result, arguments.toArray(new CiValue[arguments.size()]), targetAddress, info, marks));
+            append(new IndirectCallOp(targetMethod, result, arguments.toArray(new Value[arguments.size()]), targetAddress, info, marks));
         }
     }
 
     @Override
-    protected void emitReturn(CiValue input) {
+    protected void emitReturn(Value input) {
         append(new ReturnOp(input));
     }
 
     @Override
-    protected void emitXir(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+    protected void emitXir(XirSnippet snippet, Value[] operands, Value outputOperand, Value[] inputs, Value[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
                     LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor) {
         append(new AMD64XirOp(snippet, operands, outputOperand, inputs, temps, inputOperandIndices, tempOperandIndices, outputOperandIndex, info, infoAfter, trueSuccessor, falseSuccessor));
     }
 
     @Override
-    protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiValue index) {
+    protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) {
         // Making a copy of the switch value is necessary because jump table destroys the input value
-        Variable tmp = emitMove(index);
+        if (key.kind == Kind.Int) {
+            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key));
+        } else {
+            assert key.kind == Kind.Object;
+            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object)));
+        }
+    }
+
+    @Override
+    protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) {
+        append(new SwitchRangesOp(lowKeys, highKeys, targets, defaultTarget, key));
+    }
+
+    @Override
+    protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) {
+        // Making a copy of the switch value is necessary because jump table destroys the input value
+        Variable tmp = emitMove(key);
         append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
     }
 
     @Override
-    protected LabelRef createDeoptStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo) {
-        assert info.topFrame.bci >= 0 : "invalid bci for deopt framestate";
+    protected LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRDebugInfo info, Object deoptInfo) {
+        assert info.topFrame.getBCI() >= 0 : "invalid bci for deopt framestate";
         AMD64DeoptimizationStub stub = new AMD64DeoptimizationStub(action, reason, info, deoptInfo);
         lir.stubs.add(stub);
         return LabelRef.forLabel(stub.label);
     }
 
     @Override
-    protected void emitNullCheckGuard(NullCheckNode node, long leafGraphId) {
-        assert !node.expectedNull;
-        Variable value = load(operand(node.object()));
+    protected void emitNullCheckGuard(ValueNode object, long leafGraphId) {
+        Variable value = load(operand(object));
         LIRDebugInfo info = state(leafGraphId);
         append(new NullCheckOp(value, info));
     }
 
     @Override
     public void visitCompareAndSwap(CompareAndSwapNode node) {
-        CiKind kind = node.newValue().kind();
+        Kind kind = node.newValue().kind();
         assert kind == node.expected().kind();
 
-        CiValue expected = loadNonConst(operand(node.expected()));
+        Value expected = loadNonConst(operand(node.expected()));
         Variable newValue = load(operand(node.newValue()));
 
-        CiAddress address;
+        Address address;
         int displacement = node.displacement();
-        CiValue index = operand(node.offset());
-        if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong())) {
+        Value index = operand(node.offset());
+        if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) {
             displacement += (int) asConstant(index).asLong();
-            address = new CiAddress(kind, load(operand(node.object())), displacement);
+            address = new Address(kind, load(operand(node.object())), displacement);
         } else {
-            address = new CiAddress(kind, load(operand(node.object())), load(index), CiAddress.Scale.Times1, displacement);
+            address = new Address(kind, load(operand(node.object())), load(index), Address.Scale.Times1, displacement);
         }
 
-        CiRegisterValue rax = AMD64.rax.asValue(kind);
+        RegisterValue rax = AMD64.rax.asValue(kind);
         emitMove(expected, rax);
         append(new CompareAndSwapOp(rax, address, rax, newValue));
 
         Variable result = newVariable(node.kind());
-        append(new CondMoveOp(result, Condition.EQ, load(CiConstant.TRUE), CiConstant.FALSE));
+        append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE));
         setResult(node, result);
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRLowerable.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2011, 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.compiler.target.amd64;
-
-public interface AMD64LIRLowerable {
-
-    void generateAmd64(AMD64LIRGenerator generator);
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirAssembler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirAssembler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,8 +26,9 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.xir.*;
 
 /**
@@ -35,7 +36,7 @@
  *
  */
 public class AMD64XirAssembler extends CiXirAssembler {
-    public AMD64XirAssembler(CiTarget target) {
+    public AMD64XirAssembler(TargetDescription target) {
         super(target);
     }
 
@@ -79,11 +80,11 @@
                     XirOperand xOp = i.x();
                     if (i.op == XirOp.Div || i.op == XirOp.Mod) {
                         if (fixedRDX == null) {
-                            fixedRDX = createRegisterTemp("divModTemp", CiKind.Int, AMD64.rdx);
+                            fixedRDX = createRegisterTemp("divModTemp", Kind.Int, AMD64.rdx);
                         }
                         // Special treatment to make sure that the left input of % and / is in RAX
                         if (fixedRAX == null) {
-                            fixedRAX = createRegisterTemp("divModLeftInput", CiKind.Int, AMD64.rax);
+                            fixedRAX = createRegisterTemp("divModLeftInput", Kind.Int, AMD64.rax);
                         }
                         currentList.add(new XirInstruction(i.x().kind, XirOp.Mov, fixedRAX, i.x()));
                         xOp = fixedRAX;
@@ -141,7 +142,7 @@
                     currentList.add(new XirInstruction(target.wordKind, XirOp.Mov, fixedRSI, i.x()));
                     currentList.add(new XirInstruction(target.wordKind, XirOp.Mov, fixedRDI, i.y()));
                     currentList.add(new XirInstruction(target.wordKind, XirOp.Mov, fixedRCX, i.z()));
-                    currentList.add(new XirInstruction(CiKind.Illegal, i.op, i.result, fixedRSI, fixedRDI, fixedRCX));
+                    currentList.add(new XirInstruction(Kind.Illegal, i.op, i.result, fixedRSI, fixedRDI, fixedRCX));
                     appended = true;
                     break;
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirOp.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64XirOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,15 @@
  */
 package com.oracle.graal.compiler.target.amd64;
 
-import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
-import static com.oracle.max.cri.ci.CiValue.*;
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.api.meta.Value.*;
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
@@ -35,8 +38,6 @@
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.Mark;
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.cri.xir.CiXirAssembler.RuntimeCallInformation;
 import com.oracle.max.cri.xir.CiXirAssembler.XirInstruction;
@@ -44,7 +45,7 @@
 import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
 
 public class AMD64XirOp extends LIRXirInstruction {
-    public AMD64XirOp(XirSnippet snippet, CiValue[] operands, CiValue outputOperand, CiValue[] inputs, CiValue[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
+    public AMD64XirOp(XirSnippet snippet, Value[] operands, Value outputOperand, Value[] inputs, Value[] temps, int[] inputOperandIndices, int[] tempOperandIndices, int outputOperandIndex,
                         LIRDebugInfo info, LIRDebugInfo infoAfter, LabelRef trueSuccessor, LabelRef falseSuccessor) {
         super("XIR", snippet, operands, outputOperand, inputs, temps, inputOperandIndices, tempOperandIndices, outputOperandIndex, info, infoAfter, trueSuccessor, falseSuccessor);
     }
@@ -105,7 +106,7 @@
     }
 
 
-    protected void emitXirInstructions(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction[] instructions, Label[] labels, CiValue[] operands, Map<XirMark, Mark> marks) {
+    protected void emitXirInstructions(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction[] instructions, Label[] labels, Value[] operands, Map<XirMark, Mark> marks) {
         for (XirInstruction inst : instructions) {
             switch (inst.op) {
                 case Add:
@@ -153,27 +154,27 @@
                     break;
 
                 case Mov: {
-                    CiValue result = operands[inst.result.index];
-                    CiValue source = operands[inst.x().index];
+                    Value result = operands[inst.result.index];
+                    Value source = operands[inst.x().index];
                     AMD64Move.move(tasm, masm, result, source);
                     break;
                 }
 
                 case PointerLoad: {
-                    CiValue result = operands[inst.result.index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiRegisterValue register = assureInRegister(tasm, masm, pointer);
+                    Value result = operands[inst.result.index];
+                    Value pointer = operands[inst.x().index];
+                    RegisterValue register = assureInRegister(tasm, masm, pointer);
 
-                    AMD64Move.load(tasm, masm, result, new CiAddress(inst.kind, register), (Boolean) inst.extra ? info : null);
+                    AMD64Move.load(tasm, masm, result, new Address(inst.kind, register), (Boolean) inst.extra ? info : null);
                     break;
                 }
 
                 case PointerStore: {
-                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.y().index]);
-                    CiValue pointer = operands[inst.x().index];
+                    Value value = assureNot64BitConstant(tasm, masm, operands[inst.y().index]);
+                    Value pointer = operands[inst.x().index];
                     assert isRegister(pointer);
 
-                    AMD64Move.store(tasm, masm, new CiAddress(inst.kind, pointer), value, (Boolean) inst.extra ? info : null);
+                    AMD64Move.store(tasm, masm, new Address(inst.kind, pointer), value, (Boolean) inst.extra ? info : null);
                     break;
                 }
 
@@ -181,23 +182,23 @@
                     CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
                     boolean canTrap = addressInformation.canTrap;
 
-                    CiAddress.Scale scale = addressInformation.scale;
+                    Address.Scale scale = addressInformation.scale;
                     int displacement = addressInformation.disp;
 
-                    CiValue result = operands[inst.result.index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue index = operands[inst.y().index];
+                    Value result = operands[inst.result.index];
+                    Value pointer = operands[inst.x().index];
+                    Value index = operands[inst.y().index];
 
                     pointer = assureInRegister(tasm, masm, pointer);
                     assert isRegister(pointer);
 
-                    CiAddress src;
+                    Address src;
                     if (isConstant(index)) {
-                        assert index.kind == CiKind.Int;
-                        CiConstant constantIndex = (CiConstant) index;
-                        src = new CiAddress(inst.kind, pointer, constantIndex.asInt() * scale.value + displacement);
+                        assert index.kind == Kind.Int;
+                        Constant constantIndex = (Constant) index;
+                        src = new Address(inst.kind, pointer, constantIndex.asInt() * scale.value + displacement);
                     } else {
-                        src = new CiAddress(inst.kind, pointer, index, scale, displacement);
+                        src = new Address(inst.kind, pointer, index, scale, displacement);
                     }
 
                     AMD64Move.load(tasm, masm, result, src, canTrap ? info : null);
@@ -207,16 +208,16 @@
                 case LoadEffectiveAddress: {
                     CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
 
-                    CiAddress.Scale scale = addressInformation.scale;
+                    Address.Scale scale = addressInformation.scale;
                     int displacement = addressInformation.disp;
 
-                    CiValue result = operands[inst.result.index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue index = operands[inst.y().index];
+                    Value result = operands[inst.result.index];
+                    Value pointer = operands[inst.x().index];
+                    Value index = operands[inst.y().index];
 
                     pointer = assureInRegister(tasm, masm, pointer);
                     assert isRegister(pointer);
-                    CiAddress src = new CiAddress(CiKind.Illegal, pointer, index, scale, displacement);
+                    Address src = new Address(Kind.Illegal, pointer, index, scale, displacement);
                     masm.leaq(asRegister(result), src);
                     break;
                 }
@@ -225,23 +226,23 @@
                     CiXirAssembler.AddressAccessInformation addressInformation = (CiXirAssembler.AddressAccessInformation) inst.extra;
                     boolean canTrap = addressInformation.canTrap;
 
-                    CiAddress.Scale scale = addressInformation.scale;
+                    Address.Scale scale = addressInformation.scale;
                     int displacement = addressInformation.disp;
 
-                    CiValue value = assureNot64BitConstant(tasm, masm, operands[inst.z().index]);
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue index = operands[inst.y().index];
+                    Value value = assureNot64BitConstant(tasm, masm, operands[inst.z().index]);
+                    Value pointer = operands[inst.x().index];
+                    Value index = operands[inst.y().index];
 
                     pointer = assureInRegister(tasm, masm, pointer);
                     assert isRegister(pointer);
 
-                    CiAddress dst;
+                    Address dst;
                     if (isConstant(index)) {
-                        assert index.kind == CiKind.Int;
-                        CiConstant constantIndex = (CiConstant) index;
-                        dst = new CiAddress(inst.kind, pointer, IllegalValue, scale, constantIndex.asInt() * scale.value + displacement);
+                        assert index.kind == Kind.Int;
+                        Constant constantIndex = (Constant) index;
+                        dst = new Address(inst.kind, pointer, IllegalValue, scale, constantIndex.asInt() * scale.value + displacement);
                     } else {
-                        dst = new CiAddress(inst.kind, pointer, index, scale, displacement);
+                        dst = new Address(inst.kind, pointer, index, scale, displacement);
                     }
 
                     AMD64Move.store(tasm, masm, dst, value, canTrap ? info : null);
@@ -265,10 +266,10 @@
                 case PointerCAS:
                     assert asRegister(operands[inst.x().index]).equals(AMD64.rax) : "wrong input x: " + operands[inst.x().index];
 
-                    CiValue exchangedVal = operands[inst.y().index];
-                    CiValue exchangedAddress = operands[inst.x().index];
-                    CiRegisterValue pointerRegister = assureInRegister(tasm, masm, exchangedAddress);
-                    CiAddress addr = new CiAddress(tasm.target.wordKind, pointerRegister);
+                    Value exchangedVal = operands[inst.y().index];
+                    Value exchangedAddress = operands[inst.x().index];
+                    RegisterValue pointerRegister = assureInRegister(tasm, masm, exchangedAddress);
+                    Address addr = new Address(tasm.target.wordKind, pointerRegister);
 
                     if ((Boolean) inst.extra && info != null) {
                         tasm.recordImplicitException(masm.codeBuffer.position(), info);
@@ -278,15 +279,15 @@
                     break;
 
                 case CallRuntime: {
-                    CiKind[] signature = new CiKind[inst.arguments.length];
+                    Kind[] signature = new Kind[inst.arguments.length];
                     for (int i = 0; i < signature.length; i++) {
                         signature[i] = inst.arguments[i].kind;
                     }
 
-                    CiCallingConvention cc = tasm.frameMap.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false);
+                    CallingConvention cc = tasm.frameMap.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false);
                     for (int i = 0; i < inst.arguments.length; i++) {
-                        CiValue argumentLocation = cc.locations[i];
-                        CiValue argumentSourceLocation = operands[inst.arguments[i].index];
+                        Value argumentLocation = cc.locations[i];
+                        Value argumentSourceLocation = operands[inst.arguments[i].index];
                         if (argumentLocation != argumentSourceLocation) {
                             AMD64Move.move(tasm, masm, argumentLocation, argumentSourceLocation);
                         }
@@ -295,9 +296,9 @@
                     RuntimeCallInformation runtimeCallInformation = (RuntimeCallInformation) inst.extra;
                     AMD64Call.directCall(tasm, masm, runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info);
 
-                    if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) {
-                        CiRegister returnRegister = tasm.frameMap.registerConfig.getReturnRegister(inst.result.kind);
-                        CiValue resultLocation = returnRegister.asValue(inst.result.kind.stackKind());
+                    if (inst.result != null && inst.result.kind != Kind.Illegal && inst.result.kind != Kind.Void) {
+                        Register returnRegister = tasm.frameMap.registerConfig.getReturnRegister(inst.result.kind);
+                        Value resultLocation = returnRegister.asValue(inst.result.kind.stackKind());
                         AMD64Move.move(tasm, masm, operands[inst.result.index], resultLocation);
                     }
                     break;
@@ -313,11 +314,11 @@
                 }
                 case DecAndJumpNotZero: {
                     Label label = labels[((XirLabel) inst.extra).index];
-                    CiValue value = operands[inst.x().index];
-                    if (value.kind == CiKind.Long) {
+                    Value value = operands[inst.x().index];
+                    if (value.kind == Kind.Long) {
                         masm.decq(asRegister(value));
                     } else {
-                        assert value.kind == CiKind.Int;
+                        assert value.kind == Kind.Int;
                         masm.decl(asRegister(value));
                     }
                     masm.jcc(ConditionFlag.notZero, label);
@@ -366,13 +367,13 @@
 
                 case Jbset: {
                     Label label = labels[((XirLabel) inst.extra).index];
-                    CiValue pointer = operands[inst.x().index];
-                    CiValue offset = operands[inst.y().index];
-                    CiValue bit = operands[inst.z().index];
+                    Value pointer = operands[inst.x().index];
+                    Value offset = operands[inst.y().index];
+                    Value bit = operands[inst.z().index];
                     assert isConstant(offset) && isConstant(bit);
-                    CiConstant constantOffset = (CiConstant) offset;
-                    CiConstant constantBit = (CiConstant) bit;
-                    CiAddress src = new CiAddress(inst.kind, pointer, constantOffset.asInt());
+                    Constant constantOffset = (Constant) offset;
+                    Constant constantBit = (Constant) bit;
+                    Address src = new Address(inst.kind, pointer, constantOffset.asInt());
                     masm.btli(src, constantBit.asInt());
                     masm.jcc(ConditionFlag.aboveEqual, label);
                     break;
@@ -391,21 +392,21 @@
                 }
                 case NullCheck: {
                     tasm.recordImplicitException(masm.codeBuffer.position(), info);
-                    CiValue pointer = operands[inst.x().index];
+                    Value pointer = operands[inst.x().index];
                     masm.nullCheck(asRegister(pointer));
                     break;
                 }
                 case Push: {
-                    CiRegisterValue value = assureInRegister(tasm, masm, operands[inst.x().index]);
+                    RegisterValue value = assureInRegister(tasm, masm, operands[inst.x().index]);
                     masm.push(asRegister(value));
                     break;
                 }
                 case Pop: {
-                    CiValue result = operands[inst.result.index];
+                    Value result = operands[inst.result.index];
                     if (isRegister(result)) {
                         masm.pop(asRegister(result));
                     } else {
-                        CiRegister rscratch = tasm.frameMap.registerConfig.getScratchRegister();
+                        Register rscratch = tasm.frameMap.registerConfig.getScratchRegister();
                         masm.pop(rscratch);
                         AMD64Move.move(tasm, masm, result, rscratch.asValue());
                     }
@@ -439,7 +440,7 @@
     }
 
     private static void emitXirViaLir(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic intOp, AMD64Arithmetic longOp, AMD64Arithmetic floatOp,
-                    AMD64Arithmetic doubleOp, CiValue left, CiValue right, CiValue result) {
+                    AMD64Arithmetic doubleOp, Value left, Value right, Value result) {
         AMD64Arithmetic code;
         switch (result.kind) {
             case Int: code = intOp; break;
@@ -457,9 +458,9 @@
         }
     }
 
-    private static void emitXirCompare(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction inst, ConditionFlag cflag, CiValue[] ops, Label label) {
-        CiValue x = ops[inst.x().index];
-        CiValue y = ops[inst.y().index];
+    private static void emitXirCompare(TargetMethodAssembler tasm, AMD64MacroAssembler masm, XirInstruction inst, ConditionFlag cflag, Value[] ops, Label label) {
+        Value x = ops[inst.x().index];
+        Value y = ops[inst.y().index];
         AMD64Compare code;
         switch (x.kind) {
             case Int: code = AMD64Compare.ICMP; break;
@@ -473,23 +474,23 @@
         masm.jcc(cflag, label);
     }
 
-    private static CiValue assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue value) {
-        if (isConstant(value) && (value.kind == CiKind.Long || value.kind == CiKind.Object)) {
-            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind);
+    private static Value assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value value) {
+        if (isConstant(value) && (value.kind == Kind.Long || value.kind == Kind.Object)) {
+            RegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind);
             AMD64Move.move(tasm, masm, register, value);
             return register;
         }
         return value;
     }
 
-    private static CiRegisterValue assureInRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue pointer) {
+    private static RegisterValue assureInRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value pointer) {
         if (isConstant(pointer)) {
-            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(pointer.kind);
+            RegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(pointer.kind);
             AMD64Move.move(tasm, masm, register, pointer);
             return register;
         }
 
         assert isRegister(pointer) : "should be register, but is: " + pointer;
-        return (CiRegisterValue) pointer;
+        return (RegisterValue) pointer;
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/NegateObjectTypeFeedback.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/NegateObjectTypeFeedback.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.compiler.types;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.types.*;
@@ -38,7 +37,7 @@
     }
 
     @Override
-    public void constantBound(Condition condition, CiConstant constant) {
+    public void constantBound(Condition condition, Constant constant) {
         delegate.constantBound(condition.negate(), constant);
     }
 
@@ -48,22 +47,22 @@
     }
 
     @Override
-    public void declaredType(RiResolvedType type, boolean nonNull) {
+    public void declaredType(ResolvedJavaType type, boolean nonNull) {
         delegate.notDeclaredType(type, nonNull);
     }
 
     @Override
-    public void exactType(RiResolvedType type) {
+    public void exactType(ResolvedJavaType type) {
         delegate.notExactType(type);
     }
 
     @Override
-    public void notDeclaredType(RiResolvedType type, boolean includesNull) {
+    public void notDeclaredType(ResolvedJavaType type, boolean includesNull) {
         delegate.declaredType(type, includesNull);
     }
 
     @Override
-    public void notExactType(RiResolvedType type) {
+    public void notExactType(ResolvedJavaType type) {
         delegate.exactType(type);
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/NegateScalarTypeFeedback.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/NegateScalarTypeFeedback.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.types;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.types.*;
@@ -37,7 +37,7 @@
     }
 
     @Override
-    public void constantBound(Condition condition, CiConstant constant) {
+    public void constantBound(Condition condition, Constant constant) {
         delegate.constantBound(condition.negate(), constant);
     }
 
@@ -47,7 +47,7 @@
     }
 
     @Override
-    public void setTranslated(CiConstant delta, ScalarTypeQuery old) {
+    public void setTranslated(Constant delta, ScalarTypeQuery old) {
         throw new UnsupportedOperationException();
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/PropagateTypeCachePhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/PropagateTypeCachePhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,11 +25,11 @@
 import java.io.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.compiler.schedule.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.Graph.InputChangedListener;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
@@ -41,11 +41,10 @@
 
     private static final boolean DUMP = false;
 
-    private final CiTarget target;
-    private final RiRuntime runtime;
-    private final CiAssumptions assumptions;
+    private final TargetDescription target;
+    private final CodeCacheProvider runtime;
+    private final Assumptions assumptions;
 
-    private NodeWorkList changedNodes;
     private StructuredGraph currentGraph;
     private SchedulePhase schedule;
 
@@ -65,7 +64,7 @@
 //        });
 //    }
 
-    public PropagateTypeCachePhase(CiTarget target, RiRuntime runtime, CiAssumptions assumptions) {
+    public PropagateTypeCachePhase(TargetDescription target, CodeCacheProvider runtime, Assumptions assumptions) {
         this.target = target;
         this.runtime = runtime;
         this.assumptions = assumptions;
@@ -99,32 +98,40 @@
             }
         }
         for (FixedGuardNode guard : graph.getNodes(FixedGuardNode.class)) {
-            for (int i = 0; i < guard.conditions().size(); i++) {
-                BooleanNode condition = guard.conditions().get(i);
-                if (condition != null && condition.usages().size() > 1) {
-                    BooleanNode clone = (BooleanNode) condition.copyWithInputs();
-                    if (DUMP) {
-                        out.println("replaced!! " + clone);
-                    }
-                    guard.conditions().set(i, clone);
+            BooleanNode condition = guard.condition();
+            if (condition != null && condition.usages().size() > 1) {
+                BooleanNode clone = (BooleanNode) condition.copyWithInputs();
+                if (DUMP) {
+                    out.println("replaced!! " + clone);
                 }
+                guard.setCondition(clone);
             }
         }
 
-        changedNodes = graph.createNodeWorkList(false, 10);
 
         schedule = new SchedulePhase();
         schedule.apply(graph);
 
+        final NodeBitMap changedNodes = graph.createNodeBitMap(true);
+        graph.trackInputChange(new InputChangedListener() {
+            @Override
+            public void inputChanged(Node node) {
+                changedNodes.mark(node);
+            }
+        });
+
         new Iterator().apply(schedule.getCFG().getStartBlock());
 
+        graph.stopTrackingInputChange();
+
         Debug.dump(graph, "After PropagateType iteration");
         if (changes > 0) {
 //            totalChanges += changes;
 //            out.println(graph.method() + ": " + changes + " changes");
         }
 
-        CanonicalizerPhase.canonicalize(graph, changedNodes, runtime, target, assumptions);
+        new CanonicalizerPhase(target, runtime, assumptions, changedNodes, null).apply(graph);
+
 // outputGraph(graph);
     }
 
@@ -218,7 +225,7 @@
                             if (canonical.dependencies.length > 0) {
                                 for (Node usage : node.usages()) {
                                     if (usage instanceof ValueNode) {
-                                        for (Node dependency : canonical.dependencies) {
+                                        for (ValueNode dependency : canonical.dependencies) {
                                             // TODO(lstadler) dead dependencies should be handled differently
                                             if (dependency.isAlive()) {
                                                 ((ValueNode) usage).dependencies().add(dependency);
@@ -228,12 +235,16 @@
                                 }
                             }
                             ValueNode replacement = canonical.replacement;
-                            currentGraph.replaceFloating((FloatingNode) node, replacement);
-                            changedNodes.addAll(replacement.usages());
+                            if (node instanceof FloatingNode) {
+                                currentGraph.replaceFloating((FloatingNode) node, replacement);
+                            } else {
+                                assert node instanceof FixedWithNextNode;
+                                currentGraph.replaceFixed((FixedWithNextNode) node, replacement);
+                            }
                         }
                     }
                     if (node.isAlive() && node instanceof TypeFeedbackProvider) {
-                        changed.node = node;
+                        changed.node = (ValueNode) node;
                         ((TypeFeedbackProvider) node).typeFeedback(cache);
                         if (DUMP) {
                             out.println("  " + cache);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/TypeFeedbackCache.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/TypeFeedbackCache.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,25 +25,24 @@
 import java.util.*;
 import java.util.Map.Entry;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.types.*;
-import com.oracle.graal.nodes.type.*;
 
 public class TypeFeedbackCache implements TypeFeedbackTool, Cloneable {
 
     public static final boolean NO_OBJECT_TYPES = false;
     public static final boolean NO_SCALAR_TYPES = false;
 
-    private final RiRuntime runtime;
+    private final CodeCacheProvider runtime;
     private final StructuredGraph graph;
     private final HashMap<ValueNode, ScalarTypeFeedbackStore> scalarTypeFeedback;
     private final HashMap<ValueNode, ObjectTypeFeedbackStore> objectTypeFeedback;
     private final TypeFeedbackChanged changed;
     private final boolean negated;
 
-    public TypeFeedbackCache(RiRuntime runtime, StructuredGraph graph, TypeFeedbackChanged changed) {
+    public TypeFeedbackCache(CodeCacheProvider runtime, StructuredGraph graph, TypeFeedbackChanged changed) {
         this.runtime = runtime;
         this.graph = graph;
         scalarTypeFeedback = new HashMap<>();
@@ -52,7 +51,8 @@
         this.changed = changed;
     }
 
-    public TypeFeedbackCache(RiRuntime runtime, StructuredGraph graph, HashMap<ValueNode, ScalarTypeFeedbackStore> scalarTypeFeedback, HashMap<ValueNode, ObjectTypeFeedbackStore> objectTypeFeedback, boolean negated, TypeFeedbackChanged changed) {
+    public TypeFeedbackCache(CodeCacheProvider runtime, StructuredGraph graph, HashMap<ValueNode, ScalarTypeFeedbackStore> scalarTypeFeedback, HashMap<ValueNode,
+                    ObjectTypeFeedbackStore> objectTypeFeedback, boolean negated, TypeFeedbackChanged changed) {
         this.runtime = runtime;
         this.graph = graph;
         this.scalarTypeFeedback = scalarTypeFeedback;
@@ -63,7 +63,7 @@
 
     @Override
     public ScalarTypeFeedbackTool addScalar(ValueNode value) {
-        assert value.kind() == CiKind.Int || value.kind() == CiKind.Long || value.kind() == CiKind.Float || value.kind() == CiKind.Double;
+        assert value.kind() == Kind.Int || value.kind() == Kind.Long || value.kind() == Kind.Float || value.kind() == Kind.Double;
         ScalarTypeFeedbackStore result = scalarTypeFeedback.get(value);
         if (result == null) {
             if (value.stamp().scalarType() != null) {
@@ -78,7 +78,7 @@
 
     @Override
     public ObjectTypeFeedbackTool addObject(ValueNode value) {
-        assert value.kind() == CiKind.Object;
+        assert value.kind() == Kind.Object;
         ObjectTypeFeedbackStore result = objectTypeFeedback.get(value);
         if (result == null) {
             if (value.stamp().objectType() != null) {
@@ -97,7 +97,7 @@
     }
 
     @Override
-    public RiRuntime runtime() {
+    public CodeCacheProvider runtime() {
         return runtime;
     }
 
@@ -169,7 +169,7 @@
         // meet the phi nodes
         for (PhiNode phi : phis) {
             assert phi.valueCount() == cacheList.length;
-            if (phi.kind() == CiKind.Int || phi.kind() == CiKind.Long) {
+            if (phi.kind() == Kind.Int || phi.kind() == Kind.Long) {
                 ScalarTypeFeedbackStore[] types = new ScalarTypeFeedbackStore[phi.valueCount()];
                 for (int i = 0; i < phi.valueCount(); i++) {
                     ScalarTypeFeedbackStore other = cacheList[i].scalarTypeFeedback.get(phi.valueAt(i));
@@ -181,9 +181,9 @@
                 ScalarTypeFeedbackStore scalar = ScalarTypeFeedbackStore.meet(types);
                 if (scalar != null && !scalar.isEmpty()) {
                     result.scalarTypeFeedback.put(phi, scalar);
-                    phi.setStamp(StampFactory.forKind(phi.kind(), scalar.query(), null));
+//                    phi.setStamp(StampFactory.forKind(phi.kind(), scalar.query(), null));
                 }
-            } else if (phi.kind() == CiKind.Object) {
+            } else if (phi.kind() == Kind.Object) {
                 ObjectTypeFeedbackStore[] types = new ObjectTypeFeedbackStore[phi.valueCount()];
                 for (int i = 0; i < phi.valueCount(); i++) {
                     ObjectTypeFeedbackStore other = cacheList[i].objectTypeFeedback.get(phi.valueAt(i));
@@ -195,7 +195,7 @@
                 ObjectTypeFeedbackStore object = ObjectTypeFeedbackStore.meet(types);
                 if (object != null && !object.isEmpty()) {
                     result.objectTypeFeedback.put(phi, object);
-                    phi.setStamp(StampFactory.forKind(phi.kind(), null, object.query()));
+//                    phi.setStamp(StampFactory.forKind(phi.kind(), null, object.query()));
                 }
             }
         }
@@ -204,7 +204,7 @@
 
     @Override
     public ScalarTypeQuery queryScalar(ValueNode value) {
-        assert value.kind() == CiKind.Int || value.kind() == CiKind.Long || value.kind() == CiKind.Float || value.kind() == CiKind.Double;
+        assert value.kind() == Kind.Int || value.kind() == Kind.Long || value.kind() == Kind.Float || value.kind() == Kind.Double;
         if (NO_SCALAR_TYPES) {
             return new ScalarTypeFeedbackStore(value.kind(), changed).query();
         }
@@ -222,7 +222,7 @@
     @Override
     public ObjectTypeQuery queryObject(ValueNode value) {
         assert value != null;
-        assert value.kind() == CiKind.Object;
+        assert value.kind() == Kind.Object;
         if (NO_OBJECT_TYPES) {
             return new ObjectTypeFeedbackStore(changed).query();
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/BitMap2D.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/BitMap2D.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,14 @@
  */
 package com.oracle.graal.compiler.util;
 
-import com.oracle.graal.graph.*;
+import java.util.*;
 
 /**
  * This class implements a two-dimensional bitmap.
  */
 public final class BitMap2D {
 
-    private BitMap map;
+    private BitSet map;
     private final int bitsPerSlot;
 
     private int bitIndex(int slotIndex, int bitWithinSlotIndex)  {
@@ -42,7 +42,7 @@
     }
 
     public BitMap2D(int sizeInSlots, int bitsPerSlot) {
-        map = new BitMap(sizeInSlots * bitsPerSlot);
+        map = new BitSet(sizeInSlots * bitsPerSlot);
         this.bitsPerSlot = bitsPerSlot;
     }
 
@@ -81,8 +81,8 @@
            while (size <= slotIndex) {
                size *= 2;
            }
-           BitMap newBitMap = new BitMap(size * bitsPerSlot);
-           newBitMap.setUnion(map);
+           BitSet newBitMap = new BitSet(size * bitsPerSlot);
+           newBitMap.or(map);
            map = newBitMap;
        }
 
@@ -94,6 +94,6 @@
     }
 
     public void clear() {
-        map.clearAll();
+        map.clear();
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,46 +26,61 @@
 import java.util.*;
 import java.util.concurrent.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.Representation;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaTypeProfile.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.PhiNode.PhiType;
+import com.oracle.graal.nodes.FrameState.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 
 public class InliningUtil {
 
     public interface InliningCallback {
-        StructuredGraph buildGraph(RiResolvedMethod method);
-        double inliningWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke);
-        void recordMethodContentsAssumption(RiResolvedMethod method);
-        void recordConcreteMethodAssumption(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl);
+        StructuredGraph buildGraph(ResolvedJavaMethod method);
+        double inliningWeight(ResolvedJavaMethod caller, ResolvedJavaMethod method, Invoke invoke);
+        void recordMethodContentsAssumption(ResolvedJavaMethod method);
+        void recordConcreteMethodAssumption(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl);
     }
 
-    private static String methodName(RiResolvedMethod method, Invoke invoke) {
-        if (Debug.isLogEnabled()) {
-            if (invoke != null && invoke.stateAfter() != null) {
-                RiMethod parent = invoke.stateAfter().method();
-                return parent.name() + "@" + invoke.bci() + ": " + methodNameAndCodeSize(method);
-            } else {
-                return methodNameAndCodeSize(method);
-            }
+    public static String methodName(ResolvedJavaMethod method, Invoke invoke) {
+        if (!Debug.isLogEnabled()) {
+            return null;
+        } else if (invoke != null && invoke.stateAfter() != null) {
+            return methodName(invoke.stateAfter(), invoke.bci()) + ": " + CodeUtil.format("%H.%n(%p):%r", method) + " (" + method.codeSize() + " bytes)";
         } else {
-            return null;
+            return CodeUtil.format("%H.%n(%p):%r", method) + " (" + method.codeSize() + " bytes)";
         }
     }
 
-    private static String methodNameAndCodeSize(RiResolvedMethod method) {
-        return CiUtil.format("%H.%n(%p):%r", method) + " (" + method.codeSize() + " bytes)";
+    public static String methodName(InlineInfo info) {
+        if (!Debug.isLogEnabled()) {
+            return null;
+        } else if (info.invoke != null && info.invoke.stateAfter() != null) {
+            return methodName(info.invoke.stateAfter(), info.invoke.bci()) + ": " + info.toString();
+        } else {
+            return info.toString();
+        }
+    }
+
+    private static String methodName(FrameState frameState, int bci) {
+        StringBuilder sb = new StringBuilder();
+        if (frameState.outerFrameState() != null) {
+            sb.append(methodName(frameState.outerFrameState(), frameState.outerFrameState().bci));
+            sb.append("->");
+        }
+        sb.append(CodeUtil.format("%h.%n", frameState.method()));
+        sb.append("@").append(bci);
+        return sb.toString();
     }
 
     /**
@@ -91,7 +106,7 @@
             return (weight < o.weight) ? -1 : (weight > o.weight) ? 1 : 0;
         }
 
-        protected static StructuredGraph getGraph(final RiResolvedMethod concrete, final InliningCallback callback) {
+        protected static StructuredGraph getGraph(final ResolvedJavaMethod concrete, final InliningCallback callback) {
             return Debug.scope("Inlining", concrete, new Callable<StructuredGraph>() {
                 @Override
                 public StructuredGraph call() throws Exception {
@@ -110,7 +125,7 @@
          * @param runtime
          * @param callback
          */
-        public abstract void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback);
+        public abstract void inline(StructuredGraph graph, ExtendedRiRuntime runtime, InliningCallback callback);
     }
 
     /**
@@ -118,15 +133,15 @@
      * therefore is able to determine the called method exactly.
      */
     private static class ExactInlineInfo extends InlineInfo {
-        public final RiResolvedMethod concrete;
+        public final ResolvedJavaMethod concrete;
 
-        public ExactInlineInfo(Invoke invoke, double weight, int level, RiResolvedMethod concrete) {
+        public ExactInlineInfo(Invoke invoke, double weight, int level, ResolvedJavaMethod concrete) {
             super(invoke, weight, level);
             this.concrete = concrete;
         }
 
         @Override
-        public void inline(StructuredGraph compilerGraph, GraalRuntime runtime, final InliningCallback callback) {
+        public void inline(StructuredGraph compilerGraph, ExtendedRiRuntime runtime, final InliningCallback callback) {
             StructuredGraph graph = getGraph(concrete, callback);
             assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime);
             callback.recordMethodContentsAssumption(concrete);
@@ -140,7 +155,7 @@
 
         @Override
         public String toString() {
-            return "exact " + CiUtil.format("%H.%n(%p):%r", concrete);
+            return "exact " + CodeUtil.format("%H.%n(%p):%r", concrete);
         }
 
         @Override
@@ -154,10 +169,10 @@
      * the receiver type cannot be proven. A type check guard will be generated if this inlining is performed.
      */
     private static class TypeGuardInlineInfo extends InlineInfo {
-        public final RiResolvedMethod concrete;
-        public final RiResolvedType type;
+        public final ResolvedJavaMethod concrete;
+        public final ResolvedJavaType type;
 
-        public TypeGuardInlineInfo(Invoke invoke, double weight, int level, RiResolvedMethod concrete, RiResolvedType type) {
+        public TypeGuardInlineInfo(Invoke invoke, double weight, int level, ResolvedJavaMethod concrete, ResolvedJavaType type) {
             super(invoke, weight, level);
             this.concrete = concrete;
             this.type = type;
@@ -169,18 +184,18 @@
         }
 
         @Override
-        public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
+        public void inline(StructuredGraph graph, ExtendedRiRuntime runtime, InliningCallback callback) {
             // receiver null check must be before the type check
             InliningUtil.receiverNullCheck(invoke);
             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, RiDeoptAction.InvalidateReprofile, invoke.leafGraphId()));
-            AnchorNode anchor = graph.add(new AnchorNode());
+            FixedGuardNode guard = graph.add(new FixedGuardNode(isTypeNode, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile, invoke.leafGraphId()));
+            ValueAnchorNode anchor = graph.add(new ValueAnchorNode());
             assert invoke.predecessor() != null;
 
-            CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, anchor, type, receiver);
-            invoke.callTarget().replaceFirstInput(receiver, checkCast);
+            ValueNode anchoredReceiver = createAnchoredReceiver(graph, anchor, type, receiver);
+            invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver);
 
             graph.addBeforeFixed(invoke.node(), objectClass);
             graph.addBeforeFixed(invoke.node(), guard);
@@ -194,7 +209,7 @@
 
         @Override
         public String toString() {
-            return "type-checked " + CiUtil.format("%H.%n(%p):%r", concrete);
+            return "type-checked " + CodeUtil.format("%H.%n(%p):%r", concrete);
         }
 
         @Override
@@ -208,38 +223,36 @@
      * amounts of different receiver types and different methods. If an unknown type is encountered a deoptimization is triggered.
      */
     private static class MultiTypeGuardInlineInfo extends InlineInfo {
-        public final List<RiResolvedMethod> concretes;
-        public final RiResolvedType[] types;
+        public final List<ResolvedJavaMethod> concretes;
+        public final ProfiledType[] ptypes;
         public final int[] typesToConcretes;
-        public final double[] typeProbabilities;
         public final double notRecordedTypeProbability;
 
-        public MultiTypeGuardInlineInfo(Invoke invoke, double weight, int level, List<RiResolvedMethod> concretes, RiResolvedType[] types,
-                        int[] typesToConcretes, double[] typeProbabilities, double notRecordedTypeProbability) {
+        public MultiTypeGuardInlineInfo(Invoke invoke, double weight, int level, List<ResolvedJavaMethod> concretes, ProfiledType[] ptypes,
+                        int[] typesToConcretes, double notRecordedTypeProbability) {
             super(invoke, weight, level);
-            assert concretes.size() > 0 && concretes.size() <= types.length : "must have at least one method but no more than types methods";
-            assert types.length == typesToConcretes.length && types.length == typeProbabilities.length : "array length must match";
+            assert concretes.size() > 0 && concretes.size() <= ptypes.length : "must have at least one method but no more than types methods";
+            assert ptypes.length == typesToConcretes.length : "array lengths must match";
 
             this.concretes = concretes;
-            this.types = types;
+            this.ptypes = ptypes;
             this.typesToConcretes = typesToConcretes;
-            this.typeProbabilities = typeProbabilities;
             this.notRecordedTypeProbability = notRecordedTypeProbability;
         }
 
         @Override
         public int compiledCodeSize() {
             int result = 0;
-            for (RiResolvedMethod m: concretes) {
+            for (ResolvedJavaMethod m: concretes) {
                 result += m.compiledCodeSize();
             }
             return result;
         }
 
         @Override
-        public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
+        public void inline(StructuredGraph graph, ExtendedRiRuntime runtime, InliningCallback callback) {
             int numberOfMethods = concretes.size();
-            boolean hasReturnValue = invoke.node().kind() != CiKind.Void;
+            boolean hasReturnValue = invoke.node().kind() != Kind.Void;
 
             // receiver null check must be the first node
             InliningUtil.receiverNullCheck(invoke);
@@ -254,7 +267,7 @@
             return notRecordedTypeProbability > 0;
         }
 
-        private void inlineMultipleMethods(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback, int numberOfMethods, boolean hasReturnValue) {
+        private void inlineMultipleMethods(StructuredGraph graph, ExtendedRiRuntime runtime, InliningCallback callback, int numberOfMethods, boolean hasReturnValue) {
             FixedNode continuation = invoke.next();
 
             // setup merge and phi nodes for results and exceptions
@@ -264,14 +277,14 @@
 
             PhiNode returnValuePhi = null;
             if (hasReturnValue) {
-                returnValuePhi = graph.unique(new PhiNode(invoke.node().kind(), returnMerge, PhiType.Value));
+                returnValuePhi = graph.unique(new PhiNode(invoke.node().kind(), returnMerge));
             }
 
             MergeNode exceptionMerge = null;
             PhiNode exceptionObjectPhi = null;
             if (invoke instanceof InvokeWithExceptionNode) {
                 InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
-                BeginNode exceptionEdge = invokeWithException.exceptionEdge();
+                DispatchBeginNode exceptionEdge = invokeWithException.exceptionEdge();
                 ExceptionObjectNode exceptionObject = (ExceptionObjectNode) exceptionEdge.next();
 
                 exceptionMerge = graph.add(new MergeNode());
@@ -279,8 +292,8 @@
 
                 FixedNode exceptionSux = exceptionObject.next();
                 graph.addBeforeFixed(exceptionSux, exceptionMerge);
-                exceptionObjectPhi = graph.unique(new PhiNode(CiKind.Object, exceptionMerge, PhiType.Value));
-                exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, CiKind.Void, exceptionObjectPhi));
+                exceptionObjectPhi = graph.unique(new PhiNode(Kind.Object, exceptionMerge));
+                exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, Kind.Void, exceptionObjectPhi));
             }
 
             // create one separate block for each invoked method
@@ -291,7 +304,7 @@
                 for (int j = 0; j < typesToConcretes.length; j++) {
                     if (typesToConcretes[j] == i) {
                         predecessors++;
-                        probability += typeProbabilities[j];
+                        probability += ptypes[j].probability;
                     }
                 }
 
@@ -303,7 +316,7 @@
             if (shouldFallbackToInvoke()) {
                 unknownTypeNode = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, 1, notRecordedTypeProbability, false);
             } else {
-                unknownTypeNode = graph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.TypeCheckedInliningViolated, invoke.leafGraphId()));
+                unknownTypeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated, invoke.leafGraphId()));
             }
 
             // replace the invoke exception edge
@@ -332,12 +345,12 @@
                 BeginNode node = calleeEntryNodes[i];
                 Invoke invokeForInlining = (Invoke) node.next();
 
-                RiResolvedType commonType = getLeastCommonType(i);
+                ResolvedJavaType commonType = getLeastCommonType(i);
                 ValueNode receiver = invokeForInlining.callTarget().receiver();
-                CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, node, commonType, receiver);
-                invokeForInlining.callTarget().replaceFirstInput(receiver, checkCast);
+                ValueNode anchoredReceiver = createAnchoredReceiver(graph, node, commonType, receiver);
+                invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
 
-                RiResolvedMethod concrete = concretes.get(i);
+                ResolvedJavaMethod concrete = concretes.get(i);
                 StructuredGraph calleeGraph = getGraph(concrete, callback);
                 callback.recordMethodContentsAssumption(concrete);
                 assert !IntrinsificationPhase.canIntrinsify(invokeForInlining, concrete, runtime);
@@ -345,14 +358,14 @@
             }
         }
 
-        private RiResolvedType getLeastCommonType(int concreteMethodIndex) {
-            RiResolvedType commonType = null;
+        private ResolvedJavaType getLeastCommonType(int concreteMethodIndex) {
+            ResolvedJavaType commonType = null;
             for (int i = 0; i < typesToConcretes.length; i++) {
                 if (typesToConcretes[i] == concreteMethodIndex) {
                     if (commonType == null) {
-                        commonType = types[i];
+                        commonType = ptypes[i].type;
                     } else {
-                        commonType = commonType.leastCommonAncestor(types[i]);
+                        commonType = commonType.leastCommonAncestor(ptypes[i].type);
                     }
                 }
             }
@@ -360,22 +373,22 @@
             return commonType;
         }
 
-        private void inlineSingleMethod(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
-            assert concretes.size() == 1 && types.length > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
+        private void inlineSingleMethod(StructuredGraph graph, ExtendedRiRuntime runtime, InliningCallback callback) {
+            assert concretes.size() == 1 && ptypes.length > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
 
             MergeNode calleeEntryNode = graph.add(new MergeNode());
             calleeEntryNode.setProbability(invoke.probability());
             ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.callTarget().receiver()));
             graph.addBeforeFixed(invoke.node(), objectClassNode);
 
-            FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.TypeCheckedInliningViolated, invoke.leafGraphId()));
+            FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated, invoke.leafGraphId()));
             FixedNode dispatchOnType = createDispatchOnType(graph, objectClassNode, new BeginNode[] {calleeEntryNode}, unknownTypeNode);
 
             FixedWithNextNode pred = (FixedWithNextNode) invoke.node().predecessor();
             pred.setNext(dispatchOnType);
             calleeEntryNode.setNext(invoke.node());
 
-            RiResolvedMethod concrete = concretes.get(0);
+            ResolvedJavaMethod concrete = concretes.get(0);
             StructuredGraph calleeGraph = getGraph(concrete, callback);
             assert !IntrinsificationPhase.canIntrinsify(invoke, concrete, runtime);
             callback.recordMethodContentsAssumption(concrete);
@@ -383,43 +396,32 @@
         }
 
         private FixedNode createDispatchOnType(StructuredGraph graph, ReadHubNode objectClassNode, BeginNode[] calleeEntryNodes, FixedNode unknownTypeSux) {
-            assert types.length > 1;
-
-            int lastIndex = types.length - 1;
-            double[] branchProbabilities = convertTypeToBranchProbabilities(typeProbabilities, notRecordedTypeProbability);
-            double nodeProbability = typeProbabilities[lastIndex];
-            IfNode nextNode = createTypeCheck(graph, objectClassNode, types[lastIndex], calleeEntryNodes[typesToConcretes[lastIndex]], unknownTypeSux, branchProbabilities[lastIndex], invoke.probability() * nodeProbability);
-            for (int i = lastIndex - 1; i >= 0; i--) {
-                nodeProbability += typeProbabilities[i];
-                nextNode = createTypeCheck(graph, objectClassNode, types[i], calleeEntryNodes[typesToConcretes[i]], nextNode, branchProbabilities[i], invoke.probability() * nodeProbability);
-            }
-
-            return nextNode;
-        }
+            assert ptypes.length > 1;
 
-        private static IfNode createTypeCheck(StructuredGraph graph, ReadHubNode objectClassNode, RiResolvedType type, BeginNode tsux, FixedNode nextNode, double tsuxProbability, double probability) {
-            IfNode result;
-            IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClassNode, type));
-            if (tsux instanceof MergeNode) {
-                EndNode endNode = graph.add(new EndNode());
-                result = graph.add(new IfNode(isTypeNode, endNode, nextNode, tsuxProbability));
-                ((MergeNode) tsux).addForwardEnd(endNode);
-            } else {
-                result = graph.add(new IfNode(isTypeNode, tsux, nextNode, tsuxProbability));
+            ResolvedJavaType[] types = new ResolvedJavaType[ptypes.length];
+            double[] probabilities = new double[ptypes.length + 1];
+            BeginNode[] successors = new BeginNode[ptypes.length + 1];
+            int[] keySuccessors = new int[ptypes.length + 1];
+            for (int i = 0; i < ptypes.length; i++) {
+                types[i] = ptypes[i].type;
+                probabilities[i] = ptypes[i].probability;
+                FixedNode entry = calleeEntryNodes[typesToConcretes[i]];
+                if (entry instanceof MergeNode) {
+                    EndNode endNode = graph.add(new EndNode());
+                    ((MergeNode) entry).addForwardEnd(endNode);
+                    entry = endNode;
+                }
+                successors[i] = BeginNode.begin(entry);
+                keySuccessors[i] = i;
             }
-            result.setProbability(probability);
-            return result;
-        }
+            assert !(unknownTypeSux instanceof MergeNode);
+            successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
+            probabilities[successors.length - 1] = notRecordedTypeProbability;
+            keySuccessors[successors.length - 1] = successors.length - 1;
 
-        private static double[] convertTypeToBranchProbabilities(double[] typeProbabilities, double notRecordedTypeProbability) {
-            double[] result = new double[typeProbabilities.length];
-            double total = notRecordedTypeProbability;
-            for (int i = typeProbabilities.length - 1; i >= 0; i--) {
-                total += typeProbabilities[i];
-                result[i] = typeProbabilities[i] / total;
-            }
-            assert total > 0.99 && total < 1.01;
-            return result;
+            TypeSwitchNode typeSwitch = graph.add(new TypeSwitchNode(objectClassNode, successors, probabilities, types, probabilities, keySuccessors));
+
+            return typeSwitch;
         }
 
         private static BeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, MergeNode returnMerge, PhiNode returnValuePhi,
@@ -448,7 +450,7 @@
             result.setUseForInlining(useForInlining);
             result.setProbability(probability);
 
-            CiKind kind = invoke.node().kind();
+            Kind kind = invoke.node().kind();
             if (!kind.isVoid()) {
                 FrameState stateAfter = invoke.stateAfter();
                 stateAfter = stateAfter.duplicate(stateAfter.bci);
@@ -467,7 +469,7 @@
                 BeginNode newExceptionEdge = (BeginNode) exceptionEdge.copyWithInputs();
                 ExceptionObjectNode newExceptionObject = (ExceptionObjectNode) exceptionObject.copyWithInputs();
                 // set new state (pop old exception object, push new one)
-                newExceptionObject.setStateAfter(stateAfterException.duplicateModified(stateAfterException.bci, stateAfterException.rethrowException(), CiKind.Object, newExceptionObject));
+                newExceptionObject.setStateAfter(stateAfterException.duplicateModified(stateAfterException.bci, stateAfterException.rethrowException(), Kind.Object, newExceptionObject));
                 newExceptionEdge.setNext(newExceptionObject);
 
                 EndNode endNode = graph.add(new EndNode());
@@ -483,9 +485,9 @@
         @Override
         public String toString() {
             StringBuilder builder = new StringBuilder(shouldFallbackToInvoke() ? "megamorphic" : "polymorphic");
-            builder.append(String.format(", %d methods with %d type checks:", concretes.size(), types.length));
+            builder.append(String.format(", %d methods with %d type checks:", concretes.size(), ptypes.length));
             for (int i = 0; i < concretes.size(); i++) {
-                builder.append(CiUtil.format("  %H.%n(%p):%r", concretes.get(i)));
+                builder.append(CodeUtil.format("  %H.%n(%p):%r", concretes.get(i)));
             }
             return builder.toString();
         }
@@ -502,18 +504,18 @@
      * but for which an assumption has to be registered because of non-final classes.
      */
     private static class AssumptionInlineInfo extends ExactInlineInfo {
-        public final RiResolvedType context;
+        public final ResolvedJavaType context;
 
-        public AssumptionInlineInfo(Invoke invoke, double weight, int level, RiResolvedType context, RiResolvedMethod concrete) {
+        public AssumptionInlineInfo(Invoke invoke, double weight, int level, ResolvedJavaType context, ResolvedJavaMethod concrete) {
             super(invoke, weight, level, concrete);
             this.context = context;
         }
 
         @Override
-        public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
+        public void inline(StructuredGraph graph, ExtendedRiRuntime runtime, InliningCallback callback) {
             if (Debug.isLogEnabled()) {
-                String targetName = CiUtil.format("%H.%n(%p):%r", invoke.callTarget().targetMethod());
-                String concreteName = CiUtil.format("%H.%n(%p):%r", concrete);
+                String targetName = CodeUtil.format("%H.%n(%p):%r", invoke.callTarget().targetMethod());
+                String concreteName = CodeUtil.format("%H.%n(%p):%r", concrete);
                 Debug.log("recording concrete method assumption: %s on receiver type %s -> %s", targetName, context, concreteName);
             }
             callback.recordConcreteMethodAssumption(invoke.callTarget().targetMethod(), context, concrete);
@@ -523,7 +525,7 @@
 
         @Override
         public String toString() {
-            return "assumption " + CiUtil.format("%H.%n(%p):%r", concrete);
+            return "assumption " + CodeUtil.format("%H.%n(%p):%r", concrete);
         }
 
         @Override
@@ -540,10 +542,10 @@
      * @param callback a callback that is used to determine the weight of a specific inlining
      * @return an instance of InlineInfo, or null if no inlining is possible at the given invoke
      */
-    public static InlineInfo getInlineInfo(Invoke invoke, int level, GraalRuntime runtime, CiAssumptions assumptions, InliningCallback callback, OptimisticOptimizations optimisticOpts) {
-        RiResolvedMethod parent = invoke.stateAfter().method();
+    public static InlineInfo getInlineInfo(Invoke invoke, int level, ExtendedRiRuntime runtime, Assumptions assumptions, InliningCallback callback, OptimisticOptimizations optimisticOpts) {
+        ResolvedJavaMethod parent = invoke.stateAfter().method();
         MethodCallTargetNode callTarget = invoke.callTarget();
-        RiResolvedMethod targetMethod = callTarget.targetMethod();
+        ResolvedJavaMethod targetMethod = callTarget.targetMethod();
         if (targetMethod == null) {
             return null;
         }
@@ -558,29 +560,29 @@
             }
             return null;
         }
-        if (callTarget.receiver().exactType() != null) {
-            RiResolvedType exact = callTarget.receiver().exactType();
-            assert exact.isSubtypeOf(targetMethod.holder()) : exact + " subtype of " + targetMethod.holder() + " for " + targetMethod;
-            RiResolvedMethod resolved = exact.resolveMethodImpl(targetMethod);
+        ObjectStamp receiverStamp = callTarget.receiver().objectStamp();
+        ResolvedJavaType receiverType = receiverStamp.type();
+        if (receiverStamp.isExactType()) {
+            assert receiverType.isSubtypeOf(targetMethod.holder()) : receiverType + " subtype of " + targetMethod.holder() + " for " + targetMethod;
+            ResolvedJavaMethod resolved = receiverType.resolveMethodImpl(targetMethod);
             if (checkTargetConditions(invoke, resolved, optimisticOpts)) {
                 double weight = callback == null ? 0 : callback.inliningWeight(parent, resolved, invoke);
                 return new ExactInlineInfo(invoke, weight, level, resolved);
             }
             return null;
         }
-        RiResolvedType holder = targetMethod.holder();
+        ResolvedJavaType holder = targetMethod.holder();
 
-        if (callTarget.receiver().declaredType() != null) {
-            RiResolvedType declared = callTarget.receiver().declaredType();
+        if (receiverStamp.type() != null) {
             // the invoke target might be more specific than the holder (happens after inlining: locals lose their declared type...)
             // TODO (lstadler) fix this
-            if (declared != null && declared.isSubtypeOf(holder)) {
-                holder = declared;
+            if (receiverType != null && receiverType.isSubtypeOf(holder)) {
+                holder = receiverType;
             }
         }
         // TODO (thomaswue) fix this
         if (assumptions != null) {
-            RiResolvedMethod concrete = holder.uniqueConcreteMethod(targetMethod);
+            ResolvedJavaMethod concrete = holder.uniqueConcreteMethod(targetMethod);
             if (concrete != null) {
                 if (checkTargetConditions(invoke, concrete, optimisticOpts)) {
                     double weight = callback == null ? 0 : callback.inliningWeight(parent, concrete, invoke);
@@ -594,20 +596,18 @@
         return getTypeCheckedInlineInfo(invoke, level, callback, parent, targetMethod, optimisticOpts);
     }
 
-    private static InlineInfo getTypeCheckedInlineInfo(Invoke invoke, int level, InliningCallback callback, RiResolvedMethod parent, RiResolvedMethod targetMethod, OptimisticOptimizations optimisticOpts) {
-        RiProfilingInfo profilingInfo = parent.profilingInfo();
-        RiTypeProfile typeProfile = profilingInfo.getTypeProfile(invoke.bci());
+    private static InlineInfo getTypeCheckedInlineInfo(Invoke invoke, int level, InliningCallback callback, ResolvedJavaMethod parent, ResolvedJavaMethod targetMethod, OptimisticOptimizations optimisticOpts) {
+        ProfilingInfo profilingInfo = parent.profilingInfo();
+        JavaTypeProfile typeProfile = profilingInfo.getTypeProfile(invoke.bci());
         if (typeProfile != null) {
-            RiResolvedType[] types = typeProfile.getTypes();
-            double[] probabilities = typeProfile.getProbabilities();
+            ProfiledType[] ptypes = typeProfile.getTypes();
 
-            if (types != null && probabilities != null && types.length > 0) {
-                assert types.length == probabilities.length : "length must match";
+            if (ptypes != null && ptypes.length > 0) {
                 double notRecordedTypeProbability = typeProfile.getNotRecordedProbability();
-                if (types.length == 1 && notRecordedTypeProbability == 0) {
+                if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
                     if (optimisticOpts.inlineMonomorphicCalls()) {
-                        RiResolvedType type = types[0];
-                        RiResolvedMethod concrete = type.resolveMethodImpl(targetMethod);
+                        ResolvedJavaType type = ptypes[0].type;
+                        ResolvedJavaMethod concrete = type.resolveMethodImpl(targetMethod);
                         if (checkTargetConditions(invoke, concrete, optimisticOpts)) {
                             double weight = callback == null ? 0 : callback.inliningWeight(parent, concrete, invoke);
                             return new TypeGuardInlineInfo(invoke, weight, level, concrete, type);
@@ -620,7 +620,7 @@
                         return null;
                     }
                 } else {
-                    invoke.setMegamorph(true);
+                    invoke.setMegamorphic(true);
                     if (optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0 || optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) {
                         // TODO (chaeubl) inlining of multiple methods should work differently
                         // 1. check which methods can be inlined
@@ -631,10 +631,10 @@
                         // TODO (chaeubl) sort types by probability
 
                         // determine concrete methods and map type to specific method
-                        ArrayList<RiResolvedMethod> concreteMethods = new ArrayList<>();
-                        int[] typesToConcretes = new int[types.length];
-                        for (int i = 0; i < types.length; i++) {
-                            RiResolvedMethod concrete = types[i].resolveMethodImpl(targetMethod);
+                        ArrayList<ResolvedJavaMethod> concreteMethods = new ArrayList<>();
+                        int[] typesToConcretes = new int[ptypes.length];
+                        for (int i = 0; i < ptypes.length; i++) {
+                            ResolvedJavaMethod concrete = ptypes[i].type.resolveMethodImpl(targetMethod);
 
                             int index = concreteMethods.indexOf(concrete);
                             if (index < 0) {
@@ -646,7 +646,7 @@
 
                         double totalWeight = 0;
                         boolean canInline = true;
-                        for (RiResolvedMethod concrete: concreteMethods) {
+                        for (ResolvedJavaMethod concrete: concreteMethods) {
                             if (!checkTargetConditions(invoke, concrete, optimisticOpts)) {
                                 canInline = false;
                                 break;
@@ -655,7 +655,7 @@
                         }
 
                         if (canInline) {
-                            return new MultiTypeGuardInlineInfo(invoke, totalWeight, level, concreteMethods, types, typesToConcretes, probabilities, notRecordedTypeProbability);
+                            return new MultiTypeGuardInlineInfo(invoke, totalWeight, level, concreteMethods, ptypes, typesToConcretes, notRecordedTypeProbability);
                         } else {
                             Debug.log("not inlining %s because it is a polymorphic method call and at least one invoked method cannot be inlined", methodName(targetMethod, invoke));
                             return null;
@@ -679,11 +679,9 @@
         }
     }
 
-    private static CheckCastNode createAnchoredReceiver(StructuredGraph graph, GraalRuntime runtime, FixedNode anchor, RiResolvedType commonType, ValueNode receiver) {
+    private static ValueNode createAnchoredReceiver(StructuredGraph graph, FixedNode anchor, ResolvedJavaType commonType, ValueNode receiver) {
         // to avoid that floating reads on receiver fields float above the type check
-        ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(commonType.getEncoding(Representation.ObjectHub), runtime, graph));
-        CheckCastNode checkCast = graph.unique(new CheckCastNode(anchor, typeConst, commonType, receiver, false));
-        return checkCast;
+        return graph.unique(new PiNode(receiver, anchor, StampFactory.declaredNonNull(commonType)));
     }
 
     private static boolean checkInvokeConditions(Invoke invoke) {
@@ -702,16 +700,16 @@
         return true;
     }
 
-    private static boolean checkTargetConditions(Invoke invoke, RiMethod method, OptimisticOptimizations optimisticOpts) {
+    private static boolean checkTargetConditions(Invoke invoke, JavaMethod method, OptimisticOptimizations optimisticOpts) {
         if (method == null) {
             Debug.log("not inlining because method is not resolved");
             return false;
         }
-        if (!(method instanceof RiResolvedMethod)) {
+        if (!(method instanceof ResolvedJavaMethod)) {
             Debug.log("not inlining %s because it is unresolved", method.toString());
             return false;
         }
-        RiResolvedMethod resolvedMethod = (RiResolvedMethod) method;
+        ResolvedJavaMethod resolvedMethod = (ResolvedJavaMethod) method;
         if (Modifier.isNative(resolvedMethod.accessFlags())) {
             Debug.log("not inlining %s because it is a native method", methodName(resolvedMethod, invoke));
             return false;
@@ -728,7 +726,7 @@
             Debug.log("not inlining %s because it is marked non-inlinable", methodName(resolvedMethod, invoke));
             return false;
         }
-        if (computeRecursiveInliningLevel(invoke.stateAfter(), (RiResolvedMethod) method) > GraalOptions.MaximumRecursiveInlining) {
+        if (computeRecursiveInliningLevel(invoke.stateAfter(), (ResolvedJavaMethod) method) > GraalOptions.MaximumRecursiveInlining) {
             Debug.log("not inlining %s because it exceeds the maximum recursive inlining depth", methodName(resolvedMethod, invoke));
             return false;
         }
@@ -741,7 +739,7 @@
         return true;
     }
 
-    private static int computeRecursiveInliningLevel(FrameState state, RiResolvedMethod method) {
+    private static int computeRecursiveInliningLevel(FrameState state, ResolvedJavaMethod method) {
         assert state != null;
 
         int count = 0;
@@ -757,12 +755,13 @@
 
     /**
      * Performs an actual inlining, thereby replacing the given invoke with the given inlineGraph.
+     *
      * @param invoke the invoke that will be replaced
      * @param inlineGraph the graph that the invoke will be replaced with
      * @param receiverNullCheck true if a null check needs to be generated for non-static inlinings, false if no such check is required
-     * @return The node that represents the return value, or null for void methods and methods that have no non-exceptional exit.
      */
     public static void inline(Invoke invoke, StructuredGraph inlineGraph, boolean receiverNullCheck) {
+        InliningIdentifier identifier = new InliningIdentifier(inlineGraph.method(), invoke.toString());
         NodeInputList<ValueNode> parameters = invoke.callTarget().arguments();
         StructuredGraph graph = (StructuredGraph) invoke.node().graph();
 
@@ -773,7 +772,7 @@
         ArrayList<Node> nodes = new ArrayList<>();
         ReturnNode returnNode = null;
         UnwindNode unwindNode = null;
-        BeginNode entryPointNode = inlineGraph.start();
+        StartNode entryPointNode = inlineGraph.start();
         FixedNode firstCFGNode = entryPointNode.next();
         for (Node node : inlineGraph.getNodes()) {
             if (node == entryPointNode || node == entryPointNode.stateAfter()) {
@@ -783,12 +782,15 @@
             } else {
                 nodes.add(node);
                 if (node instanceof ReturnNode) {
+                    assert returnNode == null;
                     returnNode = (ReturnNode) node;
                 } else if (node instanceof UnwindNode) {
+                    assert unwindNode == null;
                     unwindNode = (UnwindNode) node;
                 }
             }
         }
+        replacements.put(entryPointNode, BeginNode.prevBegin(invoke.node())); // ensure proper anchoring of things that where anchored to the StartNode
 
         assert invoke.node().successors().first() != null : invoke;
         assert invoke.node().predecessor() != null;
@@ -798,7 +800,7 @@
         if (receiverNullCheck) {
             receiverNullCheck(invoke);
         }
-        invoke.node().replaceAtPredecessors(firstCFGNodeDuplicate);
+        invoke.node().replaceAtPredecessor(firstCFGNodeDuplicate);
 
         FrameState stateAtExceptionEdge = null;
         if (invoke instanceof InvokeWithExceptionNode) {
@@ -820,7 +822,7 @@
         } else {
             if (unwindNode != null) {
                 UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
-                DeoptimizeNode deoptimizeNode = new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.NotCompiledExceptionHandler, invoke.leafGraphId());
+                DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler, invoke.leafGraphId());
                 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!)
@@ -866,6 +868,7 @@
                         outerFrameState.setDuringCall(true);
                     }
                     frameState.setOuterFrameState(outerFrameState);
+                    frameState.setInliningIdentifier(identifier);
                 }
             }
         }
@@ -899,8 +902,8 @@
         StructuredGraph graph = (StructuredGraph) invoke.graph();
         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.ClassCastException, RiDeoptAction.InvalidateReprofile, invoke.leafGraphId())));
+        if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) {
+            graph.addBeforeFixed(invoke.node(), graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, true, invoke.leafGraphId())));
         }
     }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/Util.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/Util.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,15 +22,13 @@
  */
 package com.oracle.graal.compiler.util;
 
-import java.lang.reflect.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.max.criutils.*;
 
 /**
  * The {@code Util} class contains a motley collection of utility methods used throughout the compiler.
@@ -134,31 +132,31 @@
     }
 
     static {
-        assert CiUtil.log2(2) == 1;
-        assert CiUtil.log2(4) == 2;
-        assert CiUtil.log2(8) == 3;
-        assert CiUtil.log2(16) == 4;
-        assert CiUtil.log2(32) == 5;
-        assert CiUtil.log2(0x40000000) == 30;
+        assert CodeUtil.log2(2) == 1;
+        assert CodeUtil.log2(4) == 2;
+        assert CodeUtil.log2(8) == 3;
+        assert CodeUtil.log2(16) == 4;
+        assert CodeUtil.log2(32) == 5;
+        assert CodeUtil.log2(0x40000000) == 30;
 
-        assert CiUtil.log2(2L) == 1;
-        assert CiUtil.log2(4L) == 2;
-        assert CiUtil.log2(8L) == 3;
-        assert CiUtil.log2(16L) == 4;
-        assert CiUtil.log2(32L) == 5;
-        assert CiUtil.log2(0x4000000000000000L) == 62;
+        assert CodeUtil.log2(2L) == 1;
+        assert CodeUtil.log2(4L) == 2;
+        assert CodeUtil.log2(8L) == 3;
+        assert CodeUtil.log2(16L) == 4;
+        assert CodeUtil.log2(32L) == 5;
+        assert CodeUtil.log2(0x4000000000000000L) == 62;
 
-        assert !CiUtil.isPowerOf2(3);
-        assert !CiUtil.isPowerOf2(5);
-        assert !CiUtil.isPowerOf2(7);
-        assert !CiUtil.isPowerOf2(-1);
+        assert !CodeUtil.isPowerOf2(3);
+        assert !CodeUtil.isPowerOf2(5);
+        assert !CodeUtil.isPowerOf2(7);
+        assert !CodeUtil.isPowerOf2(-1);
 
-        assert CiUtil.isPowerOf2(2);
-        assert CiUtil.isPowerOf2(4);
-        assert CiUtil.isPowerOf2(8);
-        assert CiUtil.isPowerOf2(16);
-        assert CiUtil.isPowerOf2(32);
-        assert CiUtil.isPowerOf2(64);
+        assert CodeUtil.isPowerOf2(2);
+        assert CodeUtil.isPowerOf2(4);
+        assert CodeUtil.isPowerOf2(8);
+        assert CodeUtil.isPowerOf2(16);
+        assert CodeUtil.isPowerOf2(32);
+        assert CodeUtil.isPowerOf2(64);
     }
 
     /**
@@ -188,7 +186,7 @@
 
     public static void guarantee(boolean b, String string) {
         if (!b) {
-            throw new CiBailout(string);
+            throw new BailoutException(string);
         }
     }
 
@@ -331,25 +329,6 @@
         return (short) v;
     }
 
-    /**
-     * Checks that two instructions are equivalent, optionally comparing constants.
-     * @param x the first instruction
-     * @param y the second instruction
-     * @param compareConstants {@code true} if equivalent constants should be considered equivalent
-     * @return {@code true} if the instructions are equivalent; {@code false} otherwise
-     */
-    public static boolean equivalent(FixedWithNextNode x, FixedWithNextNode y, boolean compareConstants) {
-        if (x == y) {
-            return true;
-        }
-        if (compareConstants && x != null && y != null) {
-            if (x.isConstant() && x.asConstant().equivalent(y.asConstant())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     public static boolean isFixed(Node n) {
         return n instanceof FixedNode;
     }
@@ -357,8 +336,4 @@
     public static boolean isFloating(Node n) {
         return n instanceof FloatingNode;
     }
-
-    public static boolean isFinalClass(RiResolvedType type) {
-        return Modifier.isFinal(type.accessFlags()) || (type.isArrayClass() && Modifier.isFinal(type.componentType().accessFlags()));
-    }
 }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Wed Jun 27 17:35:32 2012 +0200
@@ -226,6 +226,14 @@
             public PrintStream output() {
                 return output;
             }
+
+            @Override
+            public void addToContext(Object o) {
+            }
+
+            @Override
+            public void removeFromContext(Object o) {
+            }
         };
     }
 
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java	Wed Jun 27 17:35:32 2012 +0200
@@ -28,21 +28,39 @@
 
 public interface DebugConfig {
     /**
+     * Determines if logging is enabled in the {@linkplain Debug#currentScope() current debug scope}.
+     *
      * @see Debug#log(String, Object...)
      */
     boolean isLogEnabled();
 
     /**
+     * Determines if metering is enabled in the {@linkplain Debug#currentScope() current debug scope}.
+     *
      * @see Debug#metric(String)
      */
     boolean isMeterEnabled();
 
     /**
+     * Determines if dumping is enabled in the {@linkplain Debug#currentScope() current debug scope}.
+     *
      * @see Debug#dump(Object, String, Object...)
      */
     boolean isDumpEnabled();
 
     /**
+     * Adds an object the context used by this configuration to do filtering.
+     */
+    void addToContext(Object o);
+
+    /**
+     * Removes an object the context used by this configuration to do filtering.
+     *
+     * This should only removes extra context added by {@link #addToContext(Object)}.
+     */
+    void removeFromContext(Object o);
+
+    /**
      * @see Debug#timer(String)
      */
     boolean isTimeEnabled();
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpScope.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpScope.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,16 +22,24 @@
  */
 package com.oracle.graal.debug;
 
-public final class DebugDumpScope {
+public class DebugDumpScope {
+
+    public final String name;
 
-    private final String name;
+    /**
+     * Specifies if this scope decorates an inner scope.
+     * A hierarchical or tree representation of nested scopes may choose to represent
+     * a decorator scope at the same level as the scope it decorates.
+     */
+    public final boolean decorator;
 
     public DebugDumpScope(String name) {
-        this.name = name;
+        this(name, false);
     }
 
-    public String getName() {
-        return name;
+    public DebugDumpScope(String name, boolean decorator) {
+        this.name = name;
+        this.decorator = decorator;
     }
 
     @Override
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValue.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValue.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,24 @@
  */
 package com.oracle.graal.debug.internal;
 
+import java.util.*;
+
 public abstract class DebugValue {
 
+    public static final Comparator<DebugValue> ORDER_BY_NAME = new Comparator<DebugValue>() {
+        @Override
+        public int compare(DebugValue o1, DebugValue o2) {
+            // this keeps the "Runs" metric at the top of the list
+            if (o1.getName().equals("Runs")) {
+                return o2.getName().equals("Runs") ? 0 : -1;
+            }
+            if (o2.getName().equals("Runs")) {
+                return o1.getName().equals("Runs") ? 0 : 1;
+            }
+            return o1.getName().compareTo(o2.getName());
+        }
+    };
+
     private String name;
     private int index;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/TestNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011, 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.graph;
+
+
+public class TestNode extends Node implements Node.IterableNodeType {
+    private String name;
+
+    public TestNode(String name) {
+        this.name = name;
+    }
+
+
+    public String getName() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/TypedNodeIteratorTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2011, 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.graph;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.junit.*;
+
+
+
+public class TypedNodeIteratorTest {
+
+    @Test
+    public void singleNodeTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        assertTrue(graph.hasNode(TestNode.class));
+        assertEquals("a", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void deletingNodeTest() {
+        TestNode testNode = new TestNode("a");
+        Graph graph = new Graph();
+        graph.add(testNode);
+        testNode.safeDelete();
+        assertEquals("", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void deleteAndAddTest() {
+        TestNode testNode = new TestNode("b");
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        graph.add(testNode);
+        testNode.safeDelete();
+        assertEquals("a", toString(graph.getNodes(TestNode.class)));
+        graph.add(new TestNode("c"));
+        assertEquals("ac", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void iteratorBehaviorTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        Iterator<TestNode> iterator = graph.getNodes(TestNode.class).iterator();
+        assertTrue(iterator.hasNext());
+        assertEquals("a", iterator.next().getName());
+        assertFalse(iterator.hasNext());
+        graph.add(new TestNode("b"));
+        assertTrue(iterator.hasNext());
+        assertEquals("b", iterator.next().getName());
+        assertFalse(iterator.hasNext());
+        TestNode c = new TestNode("c");
+        graph.add(c);
+        assertTrue(iterator.hasNext());
+        c.safeDelete();
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void complicatedIterationTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        for (TestNode tn : graph.getNodes(TestNode.class)) {
+            String name = tn.getName();
+            for (int i = 0; i < name.length(); ++i) {
+                char c = name.charAt(i);
+                if (c == 'a') {
+                    tn.safeDelete();
+                    graph.add(new TestNode("b"));
+                    graph.add(new TestNode("c"));
+                } else if (c == 'b') {
+                    tn.safeDelete();
+                } else if (c == 'c') {
+                    graph.add(new TestNode("d"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("d"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("d"));
+                    graph.add(new TestNode("e"));
+                    graph.add(new TestNode("d"));
+                } else if (c == 'd') {
+                    for (TestNode tn2 : graph.getNodes(TestNode.class)) {
+                        if (tn2.getName().equals("e")) {
+                            tn2.safeDelete();
+                        } else if (tn2.getName().equals("c")) {
+                            tn2.safeDelete();
+                        }
+                    }
+                } else if (c == 'e') {
+                    fail("All e nodes must have been deleted by visiting the d node");
+                }
+            }
+        }
+        assertEquals("dddd", toString(graph.getNodes(TestNode.class)));
+    }
+
+    @Test
+    public void addingNodeDuringIterationTest() {
+        Graph graph = new Graph();
+        graph.add(new TestNode("a"));
+        StringBuilder sb = new StringBuilder();
+        int z = 0;
+        for (TestNode tn : graph.getNodes(TestNode.class)) {
+            if (z == 0) {
+                graph.add(new TestNode("b"));
+            }
+            sb.append(tn.getName());
+            z++;
+        }
+        assertEquals(2, z);
+        assertEquals("ab", sb.toString());
+        z = 0;
+        for (TestNode tn : graph.getNodes(TestNode.class)) {
+            if (z == 0) {
+                graph.add(new TestNode("c"));
+            }
+            assertNotNull(tn);
+            z++;
+        }
+        assertEquals(3, z);
+    }
+
+    private static String toString(Iterable<TestNode> nodes) {
+        StringBuilder sb = new StringBuilder();
+        for (TestNode tn : nodes) {
+            sb.append(tn.getName());
+        }
+        return sb.toString();
+    }
+}
--- a/graal/com.oracle.graal.graph/.checkstyle_checks.xml	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/.checkstyle_checks.xml	Wed Jun 27 17:35:32 2012 +0200
@@ -132,6 +132,7 @@
   </module>
   <module name="RegexpHeader">
     <property name="header" value="/\*\n \* Copyright \(c\) (20[0-9][0-9], )?20[0-9][0-9], Oracle and/or its affiliates. All rights reserved.\n \* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n \*\n \* This code is free software; you can redistribute it and/or modify it\n \* under the terms of the GNU General Public License version 2 only, as\n \* published by the Free Software Foundation.\n \*\n \* This code is distributed in the hope that it will be useful, but WITHOUT\n \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n \* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n \* version 2 for more details \(a copy is included in the LICENSE file that\n \* accompanied this code\).\n \*\n \* You should have received a copy of the GNU General Public License version\n \* 2 along with this work; if not, write to the Free Software Foundation,\n \* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n \*\n \* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n \* or visit www.oracle.com if you need additional information or have any\n \* questions.\n \*/\n"/>
+    <property name="fileExtensions" value="java"/>
   </module>
   <module name="FileTabCharacter">
     <property name="severity" value="error"/>
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/BitMap.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,733 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.graph;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * Implements a bitmap that stores a single bit for a range of integers (0-n).
- */
-public final class BitMap implements Serializable {
-
-    public static final long serialVersionUID = 0L;
-
-    private static final int ADDRESS_BITS_PER_WORD = 6;
-    private static final int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
-    private static final int BIT_INDEX_MASK = BITS_PER_WORD - 1;
-
-    public static final int DEFAULT_LENGTH = BITS_PER_WORD;
-
-    public static int roundUpLength(int length) {
-        return ((length + (BITS_PER_WORD - 1)) >> ADDRESS_BITS_PER_WORD) << ADDRESS_BITS_PER_WORD;
-    }
-
-    private int size;
-    private long low;
-    private long[] extra;
-
-    /**
-     * Constructs a new bit map with the {@linkplain #DEFAULT_LENGTH default length}.
-     */
-    public BitMap() {
-        this(DEFAULT_LENGTH);
-    }
-
-    /**
-     * Constructs a new bit map from a byte array encoded bit map.
-     *
-     * @param bitmap the bit map to convert
-     */
-    public BitMap(byte[] bitmap) {
-        this(bitmap, 0, bitmap.length);
-    }
-
-    /**
-     * Constructs a new bit map from a byte array encoded bit map.
-     *
-     * @param arr the byte array containing the bit map to convert
-     * @param off the byte index in {@code arr} at which the bit map starts
-     * @param numberOfBytes the number of bytes worth of bits to copy from {@code arr}
-     */
-    public BitMap(byte[] arr, int off, int numberOfBytes) {
-        this(numberOfBytes * 8);
-        int byteIndex = off;
-        int end = off + numberOfBytes;
-        assert end <= arr.length;
-        while (byteIndex < end && (byteIndex - off) < 8) {
-            long bite = (long) arr[byteIndex] & 0xff;
-            low |= bite << ((byteIndex - off) * 8);
-            byteIndex++;
-        }
-        if (byteIndex < end) {
-            assert (byteIndex - off) == 8;
-            int remBytes = end - byteIndex;
-            int remWords = (remBytes + 7) / 8;
-            for (int word = 0; word < remWords; word++) {
-                long w = 0L;
-                for (int i = 0; i < 8 && byteIndex < end; i++) {
-                    long bite = (long) arr[byteIndex] & 0xff;
-                    w |= bite << (i * 8);
-                    byteIndex++;
-                }
-                extra[word] = w;
-            }
-        }
-    }
-
-    /**
-     * Converts a {@code long} to a {@link BitMap}.
-     */
-    public static BitMap fromLong(long bitmap) {
-        BitMap bm = new BitMap(64);
-        bm.low = bitmap;
-        return bm;
-    }
-
-    /**
-     * Constructs a new bit map with the specified length.
-     *
-     * @param length the length of the bitmap
-     */
-    public BitMap(int length) {
-        assert length >= 0;
-        this.size = length;
-        if (length > BITS_PER_WORD) {
-            int n = wordIndex(length - 1) + 1;
-            extra = new long[n];
-        }
-    }
-
-    /**
-     * Sets the bit at the specified index.
-     *
-     * @param i the index of the bit to set
-     */
-    public void set(int i) {
-        if (checkIndex(i) < BITS_PER_WORD) {
-            low |= 1L << i;
-        } else {
-            int pos = wordIndex(i);
-            int index = bitInWord(i);
-            extra[pos] |= 1L << index;
-        }
-    }
-
-    /**
-     * Grows this bitmap to a new size, appending necessary zero bits.
-     *
-     * @param newLength the new length of the bitmap
-     */
-    public void grow(int newLength) {
-        if (newLength > size) {
-            // grow this bitmap to the new length
-            int newSize = newLength >> ADDRESS_BITS_PER_WORD;
-            if (newLength > 0) {
-                if (extra == null) {
-                    // extra just needs to be allocated now
-                    extra = new long[newSize];
-                } else {
-                    if (extra.length < newSize) {
-                        // extra needs to be copied
-                        long[] newExtra = new long[newSize];
-                        for (int i = 0; i < extra.length; i++) {
-                            newExtra[i] = extra[i];
-                        }
-                        extra = newExtra;
-                    } else {
-                        // nothing to do, extra is already the right size
-                    }
-                }
-            }
-            size = newLength;
-        }
-    }
-
-    private static int bitInWord(int i) {
-        return i & BIT_INDEX_MASK;
-    }
-
-    private static int wordIndex(int i) {
-        return (i >> ADDRESS_BITS_PER_WORD) - 1;
-    }
-
-    /**
-     * Clears the bit at the specified index.
-     * @param i the index of the bit to clear
-     */
-    public void clear(int i) {
-        if (checkIndex(i) < BITS_PER_WORD) {
-            low &= ~(1L << i);
-        } else {
-            int pos = wordIndex(i);
-            int index = bitInWord(i);
-            extra[pos] &= ~(1L << index);
-        }
-    }
-
-    /**
-     * Sets all the bits in this bitmap.
-     */
-    public void setAll() {
-        low = -1;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] = -1;
-            }
-        }
-    }
-
-    /**
-     * Clears all the bits in this bitmap.
-     */
-    public void clearAll() {
-        low = 0;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] = 0;
-            }
-        }
-    }
-
-    /**
-     * Gets the value of the bit at the specified index.
-     *
-     * @param i the index of the bit to get
-     * @return {@code true} if the bit at the specified position is {@code 1}
-     */
-    public boolean get(int i) {
-        if (checkIndex(i) < BITS_PER_WORD) {
-            return ((low >> i) & 1) != 0;
-        }
-        int pos = wordIndex(i);
-        int index = bitInWord(i);
-        long bits = extra[pos];
-        return ((bits >> index) & 1) != 0;
-    }
-
-    /**
-     * Gets the value of the bit at the specified index, returning {@code false} if the
-     * bitmap does not cover the specified index.
-     *
-     * @param i the index of the bit to get
-     * @return {@code true} if the bit at the specified position is {@code 1}
-     */
-    public boolean getDefault(int i) {
-        if (i < 0 || i >= size) {
-            return false;
-        }
-        if (i < BITS_PER_WORD) {
-            return ((low >> i) & 1) != 0;
-        }
-        int pos = wordIndex(i);
-        int index = bitInWord(i);
-        long bits = extra[pos];
-        return ((bits >> index) & 1) != 0;
-    }
-
-    /**
-     * Performs the union operation on this bitmap with the specified bitmap. That is, all bits set in either of the two
-     * bitmaps will be set in this bitmap following this operation.
-     *
-     * @param other the other bitmap for the union operation
-     */
-    public void setUnion(BitMap other) {
-        low |= other.low;
-        if (extra != null && other.extra != null) {
-            for (int i = 0; i < extra.length && i < other.extra.length; i++) {
-                extra[i] |= other.extra[i];
-            }
-        }
-    }
-
-    /**
-     * Performs the union operation on this bitmap with the specified bitmap. That is, all bits set in either of the two
-     * bitmaps will be set in this bitmap following this operation. It returns whether this bitmap was changed by the operation.
-     *
-     * @param other the other bitmap for the union operation
-     */
-    public boolean setUnionWithResult(BitMap other) {
-        long temp = low | other.low;
-        boolean changed = temp != low;
-        low = temp;
-
-        if (extra != null && other.extra != null) {
-            for (int i = 0; i < extra.length && i < other.extra.length; i++) {
-                temp = extra[i] | other.extra[i];
-                changed = changed || temp != extra[i];
-                extra[i] |= temp;
-            }
-        }
-        return changed;
-    }
-
-    /**
-     * Performs the union operation on this bitmap with the specified bitmap. That is, a bit is set in this
-     * bitmap if and only if it is set in both this bitmap and the specified bitmap.
-     *
-     * @param other the other bitmap for this operation
-     * @return {@code true} if any bits were cleared as a result of this operation
-     */
-    public boolean setIntersect(BitMap other) {
-        boolean same = true;
-        long intx = low & other.low;
-        if (low != intx) {
-            same = false;
-            low = intx;
-        }
-        long[] oxtra = other.extra;
-        if (extra != null && oxtra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                long a = extra[i];
-                if (i < oxtra.length) {
-                    // zero bits out of this map
-                    long ax = a & oxtra[i];
-                    if (a != ax) {
-                        same = false;
-                        extra[i] = ax;
-                    }
-                } else {
-                    // this bitmap is larger than the specified bitmap; zero remaining bits
-                    if (a != 0) {
-                        same = false;
-                        extra[i] = 0;
-                    }
-                }
-            }
-        }
-        return !same;
-    }
-
-    /**
-     * Gets the number of addressable bits in this bitmap.
-     *
-     * @return the size of this bitmap
-     */
-    public int size() {
-        return size;
-    }
-
-    private int checkIndex(int i) {
-        if (i < 0 || i >= size) {
-            throw new IndexOutOfBoundsException("Index " + i + " is out of bounds (size=" + size + ")");
-        }
-        return i;
-    }
-
-    public void setFrom(BitMap other) {
-        assert this.size == other.size : "must have same size";
-
-        low = other.low;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] = other.extra[i];
-            }
-        }
-    }
-
-    public void setDifference(BitMap other) {
-        assert this.size == other.size : "must have same size";
-
-        low &= ~other.low;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] &= ~other.extra[i];
-            }
-        }
-    }
-
-    public void negate() {
-        if (size == 0) {
-            return;
-        }
-        if (size < BITS_PER_WORD) {
-            long mask = (1L << size) - 1;
-            low = ~low & mask;
-        } else if (size == BITS_PER_WORD) {
-            low = ~low;
-        } else {
-            low = ~low;
-            if (extra != null) {
-                for (int i = 0; i < extra.length; i++) {
-                    extra[i] = ~extra[i];
-                    if (i == extra.length - 1 && wordIndex(size) == i) {
-                        if (bitInWord(size) != 0) {
-                            long mask = (1L << bitInWord(size)) - 1;
-                            extra[i] &= mask;
-                        }
-                    }
-                }
-
-            }
-        }
-    }
-
-    public boolean isSame(BitMap other) {
-        if (this.size != other.size || this.low != other.low) {
-            return false;
-        }
-
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                if (extra[i] != other.extra[i]) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns the index of the first set bit that occurs on or after a specified start index.
-     * If no such bit exists then -1 is returned.
-     * <p>
-     * To iterate over the set bits in a {@code BitMap}, use the following loop:
-     *
-     * <pre>
-     * for (int i = bitMap.nextSetBit(0); i &gt;= 0; i = bitMap.nextSetBit(i + 1)) {
-     *     // operate on index i here
-     * }
-     * </pre>
-     *
-     * @param fromIndex the index to start checking from (inclusive)
-     * @return the index of the lowest set bit between {@code [fromIndex .. size())} or -1 if there is no set bit in this range
-     * @throws IndexOutOfBoundsException if the specified index is negative.
-     */
-    public int nextSetBit(int fromIndex) {
-        return nextSetBit(fromIndex, size());
-    }
-
-    /**
-     * Returns the index of the first set bit that occurs on or after a specified start index
-     * and before a specified end index. If no such bit exists then -1 is returned.
-     * <p>
-     * To iterate over the set bits in a {@code BitMap}, use the following loop:
-     *
-     * <pre>
-     * for (int i = bitMap.nextSetBit(0, bitMap.size()); i &gt;= 0; i = bitMap.nextSetBit(i + 1, bitMap.size())) {
-     *     // operate on index i here
-     * }
-     * </pre>
-     *
-     * @param fromIndex the index to start checking from (inclusive)
-     * @param toIndex the index at which to stop checking (exclusive)
-     * @return the index of the lowest set bit between {@code [fromIndex .. toIndex)} or -1 if there is no set bit in this range
-     * @throws IndexOutOfBoundsException if the specified index is negative.
-     */
-    public int nextSetBit(int fromIndex, int toIndex) {
-        assert fromIndex <= size() : "index out of bounds";
-        assert toIndex <= size() : "index out of bounds";
-        assert fromIndex <= toIndex : "fromIndex > toIndex";
-
-        if (fromIndex == toIndex) {
-            return -1;
-        }
-        int fromWordIndex = wordIndex(fromIndex);
-        int toWordIndex = wordIndex(toIndex - 1) + 1;
-        int resultIndex = fromIndex;
-
-        // check bits including and to the left_ of offset's position
-        int pos = bitInWord(resultIndex);
-        long res = map(fromWordIndex) >> pos;
-        if (res != 0) {
-            resultIndex += Long.numberOfTrailingZeros(res);
-            assert resultIndex >= fromIndex && resultIndex < toIndex : "just checking";
-            if (resultIndex < toIndex) {
-                return resultIndex;
-            }
-            return -1;
-        }
-        // skip over all word length 0-bit runs
-        for (fromWordIndex++; fromWordIndex < toWordIndex; fromWordIndex++) {
-            res = map(fromWordIndex);
-            if (res != 0) {
-                // found a 1, return the offset
-                resultIndex = bitIndex(fromWordIndex) + Long.numberOfTrailingZeros(res);
-                assert resultIndex >= fromIndex : "just checking";
-                if (resultIndex < toIndex) {
-                    return resultIndex;
-                }
-                return -1;
-            }
-        }
-        return -1;
-    }
-
-    private static int bitIndex(int index) {
-        return (index + 1) << ADDRESS_BITS_PER_WORD;
-    }
-
-    private long map(int index) {
-        if (index == -1) {
-            return low;
-        }
-        return extra[index];
-    }
-
-    private static boolean allZeros(int start, long[] arr) {
-        for (int i = start; i < arr.length; i++) {
-            if (arr[i] != 0) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Compares this object against the specified object.
-     * The result is {@code true} if and only if {@code obj} is
-     * not {@code null} and is a {@code CiBitMap} object that has
-     * exactly the same set of bits set to {@code true} as this bit
-     * set.
-     *
-     * @param   obj   the object to compare with.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof BitMap) {
-            BitMap bm = (BitMap) obj;
-            if (bm.low == low) {
-                if (bm.extra == null) {
-                    if (extra == null) {
-                        // Common case
-                        return true;
-                    }
-                    return allZeros(0, extra);
-                }
-                if (extra == null) {
-                    return allZeros(0, bm.extra);
-                }
-                // both 'extra' array non null:
-                int i = 0;
-                int length = Math.min(extra.length, bm.extra.length);
-                while (i < length) {
-                    if (extra[i] != bm.extra[i]) {
-                        return false;
-                    }
-                    i++;
-                }
-                if (extra.length > bm.extra.length) {
-                    return allZeros(length, extra);
-                }
-                if (extra.length < bm.extra.length) {
-                    return allZeros(length, bm.extra);
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns a string representation of this bit map
-     * that is the same as the string returned by {@link BitSet#toString()}
-     * for a bit set with the same bits set as this bit map.
-     */
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(size * 2);
-        sb.append('{');
-
-        int bit = nextSetBit(0);
-        if (bit != -1) {
-            sb.append(bit);
-            for (bit = nextSetBit(bit + 1); bit >= 0; bit = nextSetBit(bit + 1)) {
-                sb.append(", ").append(bit);
-            }
-        }
-
-        sb.append('}');
-        return sb.toString();
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + Arrays.hashCode(extra);
-        result = prime * result + (int) (low ^ (low >>> 32));
-        result = prime * result + size;
-        return result;
-    }
-
-    public static int highestOneBitIndex(long value) {
-        int bit = Long.numberOfTrailingZeros(Long.highestOneBit(value));
-        if (bit == 64) {
-            return -1;
-        }
-        return bit;
-    }
-
-    /**
-     * Returns the number of bits set to {@code true} in this bit map.
-     */
-    public int cardinality() {
-        int sum = Long.bitCount(low);
-        if (extra != null) {
-            for (long word : extra) {
-                sum += Long.bitCount(word);
-            }
-        }
-        return sum;
-    }
-
-    /**
-     * Returns the "logical size" of this bit map: the index of
-     * the highest set bit in the bit map plus one. Returns zero
-     * if the bit map contains no set bits.
-     *
-     * @return  the logical size of this bit map
-     */
-    public int length() {
-        if (extra != null) {
-            for (int i = extra.length - 1; i >= 0; i--) {
-                if (extra[i] != 0) {
-                    return (highestOneBitIndex(extra[i]) + ((i + 1) * 64)) + 1;
-                }
-            }
-        }
-        return highestOneBitIndex(low) + 1;
-    }
-
-    /**
-     * Returns a string representation of this bit map with every set bit represented as {@code '1'}
-     * and every unset bit represented as {@code '0'}. The first character in the returned string represents
-     * bit 0 in this bit map.
-     */
-    public String toBinaryString() {
-        StringBuilder sb = new StringBuilder(size);
-        for (int i = 0; i < size; ++i) {
-            sb.append(get(i) ? '1' : '0');
-        }
-        return sb.toString();
-    }
-
-    static final char[] hexDigits = {
-        '0', '1', '2', '3', '4', '5', '6', '7',
-        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-    };
-
-    /**
-     * Returns a string representation of this bit map in hex.
-     */
-    public String toHexString() {
-        if (size == 0) {
-            return "";
-        }
-        int hexSize = align(this.size, 4);
-        StringBuilder sb = new StringBuilder(hexSize / 4);
-        for (int i = 0; i < hexSize; i += 4) {
-            int nibble = get(i) ? 1 : 0;
-            if (get(i + 1)) {
-                nibble |= 2;
-            }
-            if (get(i + 2)) {
-                nibble |= 4;
-            }
-            if (get(i + 3)) {
-                nibble |= 8;
-            }
-
-            sb.append(hexDigits[nibble]);
-        }
-        return sb.toString();
-    }
-
-    private static int align(int size, int align) {
-        return (size + align - 1) & ~(align - 1);
-    }
-
-    public BitMap copy() {
-        BitMap n = new BitMap(BITS_PER_WORD);
-        n.low = low;
-        if (extra != null) {
-            n.extra = Arrays.copyOf(extra, extra.length);
-        }
-        n.size = size;
-        return n;
-    }
-
-    /**
-     * Copies this bit map into a given byte array.
-     *
-     * @param arr the destination
-     * @param off the byte index in {@code arr} at which to start writing
-     * @param numberOfBytes the number of bytes worth of bits to copy from this bit map.
-     * @return the number of bytes written to {@code arr}
-     */
-    public int copyTo(byte[] arr, int off, int numberOfBytes) {
-        for (int i = 0; i < numberOfBytes; ++i) {
-            long word = low;
-            int byteInWord;
-            if (i >= 8) {
-                int wordIndex = (i - 8) / 8;
-                word = extra[wordIndex];
-                byteInWord = i & 0x7;
-            } else {
-                byteInWord = i;
-            }
-            assert byteInWord < 8;
-            byte b = (byte) (word >> (byteInWord * 8));
-            arr[off + i] = b;
-        }
-        return numberOfBytes;
-    }
-
-    /**
-     * Converts this bit map to a byte array. The length of the returned
-     * byte array is {@code ((size() + 7) / 8)}.
-     */
-    public byte[] toByteArray() {
-        byte[] arr = new byte[(size + 7) / 8];
-        copyTo(arr, 0, arr.length);
-        return arr;
-    }
-
-    /**
-     * Converts this bit map to a long.
-     *
-     * @throws IllegalArgumentException if {@code (size() > 64)}
-     */
-    public long toLong() {
-        if (size > 64) {
-            throw new IllegalArgumentException("bit map of size " + size + " cannot be converted to long");
-        }
-        return low;
-    }
-
-    public boolean containsAll(BitMap other) {
-        assert this.size == other.size : "must have same size";
-        if ((low & other.low) != other.low) {
-            return false;
-        }
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                if ((extra[i] & other.extra[i]) != other.extra[i]) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalInternalError.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalInternalError.java	Wed Jun 27 17:35:32 2012 +0200
@@ -29,9 +29,6 @@
  */
 public class GraalInternalError extends Error {
 
-    /**
-     *
-     */
     private static final long serialVersionUID = 8776065085829593278L;
     private Node node;
     private Graph graph;
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Wed Jun 27 17:35:32 2012 +0200
@@ -34,7 +34,7 @@
  */
 public class Graph {
 
-    protected final String name;
+    public final String name;
 
     private static final boolean TIME_TRAVEL = false;
 
@@ -45,11 +45,10 @@
     private final ArrayList<Node> nodeCacheFirst;
     private final ArrayList<Node> nodeCacheLast;
     private int deletedNodeCount;
-    private int mark;
     private GraphEventLog eventLog;
 
     ArrayList<Node> usagesDropped = new ArrayList<>();
-    NodeWorkList inputChanged;
+    InputChangedListener inputChanged;
     private final HashMap<CacheEntry, Node> cachedNodes = new HashMap<>();
 
     private static final class CacheEntry {
@@ -160,8 +159,12 @@
         return result;
     }
 
-    public void trackInputChange(NodeWorkList worklist) {
-        this.inputChanged = worklist;
+    public interface InputChangedListener {
+        void inputChanged(Node node);
+    }
+
+    public void trackInputChange(InputChangedListener inputChangedListener) {
+        this.inputChanged = inputChangedListener;
     }
 
     public void stopTrackingInputChange() {
@@ -206,11 +209,22 @@
                             return usage;
                         }
                     }
-                    break;
+                    return null;
                 }
             }
         }
-        return null;
+        CacheEntry key = new CacheEntry(node);
+        Node cachedNode = cachedNodes.get(key);
+        if (cachedNode != null) {
+            if (!cachedNode.isAlive()) {
+                cachedNodes.remove(key);
+                return null;
+            }
+            return cachedNode != node ? cachedNode : null;
+        } else {
+            cachedNodes.put(key, node);
+            return null;
+        }
     }
 
     private static boolean checkValueNumberable(Node node) {
@@ -220,8 +234,11 @@
         return true;
     }
 
-    public void mark() {
-        this.mark = nodeIdCount();
+    /**
+     * Gets a mark that can be used with {@link #getNewNodes()}.
+     */
+    public int getMark() {
+        return nodeIdCount();
     }
 
     private class NodeIterator implements Iterator<Node> {
@@ -274,12 +291,11 @@
     }
 
     /**
-     * Returns an {@link Iterable} providing all nodes added since the last {@link Graph#mark() mark}.
-     * @return an {@link Iterable} providing the new nodes
+     * Returns an {@link Iterable} providing all nodes added since the last {@link Graph#getMark() mark}.
      */
-    public NodeIterable<Node> getNewNodes() {
-        final int index = this.mark;
-        return new NodeIterable<Node>() {
+    public NodeIterable<Node> getNewNodes(int mark) {
+        final int index = mark;
+        return new AbstractNodeIterable<Node>() {
             @Override
             public Iterator<Node> iterator() {
                 return new NodeIterator(index);
@@ -292,11 +308,20 @@
      * @return an {@link Iterable} providing all the live nodes.
      */
     public NodeIterable<Node> getNodes() {
-        return new NodeIterable<Node>() {
+        return new AbstractNodeIterable<Node>() {
             @Override
             public Iterator<Node> iterator() {
                 return new NodeIterator();
             }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public <F extends Node> NodeIterable<F> filter(Class<F> clazz) {
+                if (IterableNodeType.class.isAssignableFrom(clazz)) {
+                    return getNodes((Class) clazz);
+                }
+                return super.filter(clazz);
+            }
         };
     }
 
@@ -360,7 +385,7 @@
      */
     public <T extends Node & IterableNodeType> NodeIterable<T> getNodes(final Class<T> type) {
         final Node start = getStartNode(type);
-        return new NodeIterable<T>() {
+        return new AbstractNodeIterable<T>() {
             @Override
             public Iterator<T> iterator() {
                 return new TypedNodeIterator<>(start);
@@ -385,7 +410,11 @@
     }
 
     public NodeBitMap createNodeBitMap() {
-        return new NodeBitMap(this);
+        return createNodeBitMap(false);
+    }
+
+    public NodeBitMap createNodeBitMap(boolean autoGrow) {
+        return new NodeBitMap(this, autoGrow);
     }
 
     public <T> NodeMap<T> createNodeMap() {
@@ -500,7 +529,45 @@
      * @param replacements the replacement map (can be null if no replacement is to be performed)
      * @return a map which associates the original nodes from {@code nodes} to their duplicates
      */
-    public Map<Node, Node> addDuplicates(Iterable<Node> newNodes, Map<Node, Node> replacements) {
+    public Map<Node, Node> addDuplicates(Iterable<Node> newNodes, Map<Node, Node> replacementsMap) {
+        DuplicationReplacement replacements;
+        if (replacementsMap == null) {
+            replacements = null;
+        } else {
+            replacements = new MapReplacement(replacementsMap);
+        }
+        return addDuplicates(newNodes, replacements);
+    }
+
+    public interface DuplicationReplacement {
+        Node replacement(Node original);
+    }
+
+    private static final class MapReplacement implements DuplicationReplacement {
+        private final Map<Node, Node> map;
+        public MapReplacement(Map<Node, Node> map) {
+            this.map = map;
+        }
+        @Override
+        public Node replacement(Node original) {
+            Node replacement = map.get(original);
+            return replacement != null ? replacement : original;
+        }
+
+    }
+
+    private static final DuplicationReplacement NO_REPLACEMENT = new DuplicationReplacement() {
+        @Override
+        public Node replacement(Node original) {
+            return original;
+        }
+    };
+
+    @SuppressWarnings("all")
+    public Map<Node, Node> addDuplicates(Iterable<Node> newNodes, DuplicationReplacement replacements) {
+        if (replacements == null) {
+            replacements = NO_REPLACEMENT;
+        }
         return NodeClass.addGraphDuplicate(this, newNodes, replacements);
     }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,6 +25,7 @@
 import java.lang.annotation.*;
 import java.util.*;
 
+import com.oracle.graal.graph.Graph.InputChangedListener;
 import com.oracle.graal.graph.NodeClass.*;
 
 
@@ -89,27 +90,6 @@
         Class value() default NodeIntrinsic.class;
     }
 
-
-    /**
-     * Annotates a method replaced by a compile-time constant.
-     * A (resolved) call to the annotated method is replaced
-     * with a constant obtained by calling the annotated method via reflection.
-     *
-     * All arguments to such a method (including the receiver if applicable)
-     * must be compile-time constants.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    public static @interface Fold {
-    }
-
-
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    public static @interface NodePhase {
-        Class value() default NodePhase.class;
-    }
-
     public interface ValueNumberable {}
 
     public interface IterableNodeType {}
@@ -123,7 +103,7 @@
     private NodeUsagesList usages;
     private Node predecessor;
     private int modCount;
-    private NodeClass nodeClass;
+    private final NodeClass nodeClass;
 
     public Node() {
         this.graph = null;
@@ -191,9 +171,9 @@
                 assert assertTrue(result, "not found in usages, old input: %s", oldInput);
             }
             if (newInput != null) {
-                NodeWorkList inputChanged = graph.inputChanged;
+                InputChangedListener inputChanged = graph.inputChanged;
                 if (inputChanged != null) {
-                    inputChanged.addAgain(this);
+                    inputChanged.inputChanged(this);
                 }
                 newInput.usages.add(this);
             }
@@ -201,10 +181,10 @@
     }
 
     /**
-     * Updates the predecessor sets of the given nodes after a successor slot is changed from oldSuccessor to newSuccessor:
+     * Updates the predecessor of the given nodes after a successor slot is changed from oldSuccessor to newSuccessor:
      * removes this node from oldSuccessor's predecessors and adds this node to newSuccessor's predecessors.
      */
-    protected void updatePredecessors(Node oldSuccessor, Node newSuccessor) {
+    protected void updatePredecessor(Node oldSuccessor, Node newSuccessor) {
         assert assertTrue(usages != null, "usages == null while adding %s to %s", newSuccessor, this);
         if (oldSuccessor != newSuccessor) {
             if (oldSuccessor != null) {
@@ -227,7 +207,7 @@
             updateUsages(null, input);
         }
         for (Node successor : successors()) {
-            updatePredecessors(null, successor);
+            updatePredecessor(null, successor);
         }
     }
 
@@ -251,9 +231,9 @@
             boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other);
             assert assertTrue(result, "not found in inputs, usage: %s", usage);
             if (other != null) {
-                NodeWorkList inputChanged = graph.inputChanged;
+                InputChangedListener inputChanged = graph.inputChanged;
                 if (inputChanged != null) {
-                    inputChanged.addAgain(usage);
+                    inputChanged.inputChanged(usage);
                 }
                 other.usages.add(usage);
             }
@@ -261,12 +241,12 @@
         usages.clear();
     }
 
-    public void replaceAtPredecessors(Node other) {
+    public void replaceAtPredecessor(Node other) {
         assert checkReplaceWith(other);
         if (predecessor != null) {
             boolean result = predecessor.getNodeClass().replaceFirstSuccessor(predecessor, this, other);
             assert assertTrue(result, "not found in successors, predecessor: %s", predecessor);
-            predecessor.updatePredecessors(this, other);
+            predecessor.updatePredecessor(this, other);
         }
     }
 
@@ -275,14 +255,14 @@
         if (other != null) {
             clearSuccessors();
             replaceAtUsages(other);
-            replaceAtPredecessors(other);
+            replaceAtPredecessor(other);
         }
         safeDelete();
     }
 
     public void replaceFirstSuccessor(Node oldSuccessor, Node newSuccessor) {
         if (getNodeClass().replaceFirstSuccessor(this, oldSuccessor, newSuccessor)) {
-            updatePredecessors(oldSuccessor, newSuccessor);
+            updatePredecessor(oldSuccessor, newSuccessor);
         }
     }
 
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,36 +22,44 @@
  */
 package com.oracle.graal.graph;
 
-import java.util.Collection;
-import java.util.Iterator;
+import java.util.*;
+
+import com.oracle.graal.graph.iterators.*;
 
 
 
-public final class NodeBitMap implements Iterable<Node>{
-
-    private final BitMap bitMap;
+public final class NodeBitMap extends AbstractNodeIterable<Node>{
+    private final boolean autoGrow;
+    private final BitSet bitMap;
     private final Graph graph;
+    private int nodeCount;
 
     public NodeBitMap(Graph graph) {
+        this(graph, false);
+    }
+
+    public NodeBitMap(Graph graph, boolean autoGrow) {
+        this(graph, autoGrow, graph.nodeIdCount(), new BitSet(graph.nodeIdCount()));
+    }
+
+    private NodeBitMap(Graph graph, boolean autoGrow, int nodeCount, BitSet bits) {
         this.graph = graph;
-        bitMap = new BitMap(graph.nodeIdCount());
+        this.autoGrow = autoGrow;
+        this.nodeCount = nodeCount;
+        bitMap = bits;
     }
 
     public Graph graph() {
         return graph;
     }
 
-    public boolean setIntersect(NodeBitMap other) {
-        return bitMap.setIntersect(other.bitMap);
-    }
-
     public void setUnion(NodeBitMap other) {
-        bitMap.setUnion(other.bitMap);
+        bitMap.or(other.bitMap);
     }
 
     public void negate() {
         grow();
-        bitMap.negate();
+        bitMap.flip(0, nodeCount);
     }
 
     public boolean isNotNewMarked(Node node) {
@@ -63,48 +71,49 @@
     }
 
     public boolean isMarked(Node node) {
-        check(node);
         return bitMap.get(node.id());
     }
 
     public boolean isNew(Node node) {
-        return node.id() >= bitMap.size();
+        return node.id() >= nodeCount;
     }
 
     public void mark(Node node) {
-        check(node);
+        if (autoGrow && isNew(node)) {
+            grow();
+        }
+        assert check(node);
         bitMap.set(node.id());
     }
 
     public void clear(Node node) {
-        check(node);
+        if (autoGrow && isNew(node)) {
+            return;
+        }
+        assert check(node);
         bitMap.clear(node.id());
     }
 
     public void clearAll() {
-        bitMap.clearAll();
+        bitMap.clear();
     }
 
     public void grow(Node node) {
-        bitMap.grow(node.id() + 1);
+        nodeCount = Math.max(nodeCount, node.id() + 1);
     }
 
     public void grow() {
-        bitMap.grow(graph.nodeIdCount());
+        nodeCount = Math.max(nodeCount, graph.nodeIdCount());
     }
 
-    private void check(Node node) {
+    private boolean check(Node node) {
         assert node.graph() == graph : "this node is not part of the graph";
-        assert !isNew(node) : "this node (" + node.id() + ") was added to the graph after creating the node bitmap (" + bitMap.length() + ")";
-        assert node.isAlive() : "node " + node + " is deleted!";
+        assert !isNew(node) : "node was added to the graph after creating the node bitmap";
+        assert node.isAlive() : "node is deleted!";
+        return true;
     }
 
-    @Override
-    public String toString() {
-        return bitMap.toBinaryString();
-    }
-
-    public <T extends Node> void markAll(Collection<T> nodes) {
+    public <T extends Node> void markAll(Iterable<T> nodes) {
         for (Node node : nodes) {
             mark(node);
         }
@@ -164,4 +173,23 @@
     public int cardinality() {
         return bitMap.cardinality();
     }
+
+    public NodeBitMap copy() {
+        return new NodeBitMap(graph, autoGrow, nodeCount, (BitSet) bitMap.clone());
+    }
+
+    @Override
+    public NodeIterable<Node> distinct() {
+        return this;
+    }
+
+    @Override
+    public int count() {
+        return bitMap.cardinality();
+    }
+
+    @Override
+    public boolean contains(Node node) {
+        return isMarked(node);
+    }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Wed Jun 27 17:35:32 2012 +0200
@@ -27,6 +27,8 @@
 import java.util.Map.*;
 import java.util.concurrent.ConcurrentHashMap;
 
+import com.oracle.graal.graph.Graph.DuplicationReplacement;
+
 import sun.misc.Unsafe;
 
 public class NodeClass {
@@ -555,12 +557,16 @@
             if (type.isPrimitive()) {
                 if (type == Integer.TYPE) {
                     value = unsafe.getInt(node, dataOffsets[i]);
+                } else if (type == Long.TYPE) {
+                    value = unsafe.getLong(node, dataOffsets[i]);
                 } else if (type == Boolean.TYPE) {
                     value = unsafe.getBoolean(node, dataOffsets[i]);
+                } else if (type == Long.TYPE) {
+                    value = unsafe.getLong(node, dataOffsets[i]);
                 } else if (type == Double.TYPE) {
-                    value = String.format(Locale.ENGLISH, "%7.5f", unsafe.getDouble(node, dataOffsets[i]));
+                    value = unsafe.getDouble(node, dataOffsets[i]);
                 } else {
-                    assert false;
+                    assert false : "unhandled property type: " + type;
                 }
             } else {
                 value = unsafe.getObject(node, dataOffsets[i]);
@@ -624,6 +630,9 @@
     }
 
     public boolean isValid(Position pos, NodeClass from) {
+        if (this == from) {
+            return true;
+        }
         long[] offsets = pos.input ? inputOffsets : successorOffsets;
         if (pos.index >= offsets.length) {
             return false;
@@ -657,7 +666,7 @@
             if (pos.input) {
                 node.updateUsages(old, x);
             } else {
-                node.updatePredecessors(old, x);
+                node.updatePredecessor(old, x);
             }
         } else {
             NodeList<Node> list = getNodeList(node, offset);
@@ -906,15 +915,22 @@
         return directSuccessorCount;
     }
 
-    static Map<Node, Node> addGraphDuplicate(Graph graph, Iterable<Node> nodes, Map<Node, Node> replacements) {
+    static Map<Node, Node> addGraphDuplicate(Graph graph, Iterable<Node> nodes, DuplicationReplacement replacements) {
         Map<Node, Node> newNodes = new IdentityHashMap<>();
+        Map<Node, Node> replacementsMap = new IdentityHashMap<>();
         // create node duplicates
         for (Node node : nodes) {
-            if (node != null && !replacements.containsKey(node)) {
+            if (node != null) {
                 assert !node.isDeleted() : "trying to duplicate deleted node";
-                Node newNode = node.clone(graph);
-                assert newNode.getClass() == node.getClass();
-                newNodes.put(node, newNode);
+                Node replacement = replacements.replacement(node);
+                if (replacement != node) {
+                    assert replacement != null;
+                    newNodes.put(node, replacement);
+                } else {
+                    Node newNode = node.clone(graph);
+                    assert newNode.getClass() == node.getClass();
+                    newNodes.put(node, newNode);
+                }
             }
         }
         // re-wire inputs
@@ -923,28 +939,27 @@
             Node node = entry.getValue();
             for (NodeClassIterator iter = oldNode.inputs().iterator(); iter.hasNext();) {
                 Position pos = iter.nextPosition();
+                if (!pos.isValidFor(node, oldNode)) {
+                    continue;
+                }
                 Node input = oldNode.getNodeClass().get(oldNode, pos);
-                Node target = replacements.get(input);
+                Node target = newNodes.get(input);
                 if (target == null) {
-                    target = newNodes.get(input);
+                    target = replacementsMap.get(input);
+                    if (target == null) {
+                        Node replacement = replacements.replacement(input);
+                        if (replacement != input) {
+                            replacementsMap.put(input, replacement);
+                            assert replacement == null || node.getNodeClass().inputTypes[pos.index] == null || node.getNodeClass().inputTypes[pos.index].isAssignableFrom(replacement.getClass());
+                            target = replacement;
+                        } else if (input.graph() == graph) { // patch to the outer world
+                            target = input;
+                        }
+                    }
                 }
                 node.getNodeClass().set(node, pos, target);
             }
         }
-        for (Entry<Node, Node> entry : replacements.entrySet()) {
-            Node oldNode = entry.getKey();
-            Node node = entry.getValue();
-            if (oldNode == node) {
-                continue;
-            }
-            for (NodeClassIterator iter = oldNode.inputs().iterator(); iter.hasNext();) {
-                Position pos = iter.nextPosition();
-                Node input = oldNode.getNodeClass().get(oldNode, pos);
-                if (newNodes.containsKey(input)) {
-                    node.getNodeClass().set(node, pos, newNodes.get(input));
-                }
-            }
-        }
 
         // re-wire successors
         for (Entry<Node, Node> entry : newNodes.entrySet()) {
@@ -952,28 +967,25 @@
             Node node = entry.getValue();
             for (NodeClassIterator iter = oldNode.successors().iterator(); iter.hasNext();) {
                 Position pos = iter.nextPosition();
+                if (!pos.isValidFor(node, oldNode)) {
+                    continue;
+                }
                 Node succ = oldNode.getNodeClass().get(oldNode, pos);
-                Node target = replacements.get(succ);
+                Node target = newNodes.get(succ);
                 if (target == null) {
-                    target = newNodes.get(succ);
+                    target = replacementsMap.get(succ);
+                    if (target == null) {
+                        Node replacement = replacements.replacement(succ);
+                        if (replacement != succ) {
+                            replacementsMap.put(succ, replacement);
+                            assert replacement == null || node.getNodeClass().successorTypes[pos.index] == null || node.getNodeClass().successorTypes[pos.index].isAssignableFrom(replacement.getClass());
+                            target = replacement;
+                        }
+                    }
                 }
                 node.getNodeClass().set(node, pos, target);
             }
         }
-        for (Entry<Node, Node> entry : replacements.entrySet()) {
-            Node oldNode = entry.getKey();
-            Node node = entry.getValue();
-            if (oldNode == node) {
-                continue;
-            }
-            for (NodeClassIterator iter = oldNode.successors().iterator(); iter.hasNext();) {
-                Position pos = iter.nextPosition();
-                Node succ = oldNode.getNodeClass().get(oldNode, pos);
-                if (newNodes.containsKey(succ)) {
-                    node.getNodeClass().set(node, pos, newNodes.get(succ));
-                }
-            }
-        }
         return newNodes;
     }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputsIterable.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputsIterable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,7 +25,7 @@
 import com.oracle.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.graal.graph.iterators.*;
 
-public abstract class NodeInputsIterable extends NodeIterable<Node> {
+public abstract class NodeInputsIterable extends AbstractNodeIterable<Node> {
     @Override
     public abstract NodeClassIterator iterator();
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java	Wed Jun 27 17:35:32 2012 +0200
@@ -21,21 +21,16 @@
  * questions.
  */
 package com.oracle.graal.graph;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
+import java.util.*;
 
 import com.oracle.graal.graph.iterators.*;
 
-public abstract class NodeList<T extends Node> extends NodeIterable<T> implements List<T> {
+public abstract class NodeList<T extends Node> extends AbstractList<T> implements NodeIterable<T> {
 
     protected static final Node[] EMPTY_NODE_ARRAY = new Node[0];
 
     protected Node[] nodes;
     private int size;
-    private int modCount;
     protected final int initialSize;
 
     protected NodeList() {
@@ -60,6 +55,7 @@
             this.nodes = new Node[elements.length];
             for (int i = 0; i < elements.length; i++) {
                 this.nodes[i] = elements[i];
+                assert this.nodes[i] == null || !this.nodes[i].isDeleted();
             }
         }
     }
@@ -75,6 +71,7 @@
             this.nodes = new Node[elements.size()];
             for (int i = 0; i < elements.size(); i++) {
                 this.nodes[i] = elements.get(i);
+                assert this.nodes[i] == null || !this.nodes[i].isDeleted();
             }
         }
     }
@@ -329,46 +326,6 @@
     }
 
     @Override
-    public boolean addAll(int index, Collection< ? extends T> c) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public boolean removeAll(Collection< ? > c) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public boolean retainAll(Collection< ? > c) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public void add(int index, T element) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public int lastIndexOf(Object o) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public ListIterator<T> listIterator() {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public ListIterator<T> listIterator(int index) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public List<T> subList(int fromIndex, int toIndex) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append('[');
@@ -381,4 +338,41 @@
         sb.append(']');
         return sb.toString();
     }
+
+    @Override
+    public NodeIterable<T> until(final T u) {
+        return new FilteredNodeIterable<>(this).until(u);
+    }
+    @Override
+    public NodeIterable<T> until(final Class<? extends T> clazz) {
+        return new FilteredNodeIterable<>(this).until(clazz);
+    }
+    @Override
+    @SuppressWarnings("unchecked")
+    public <F extends T> NodeIterable<F> filter(Class<F> clazz) {
+        return (NodeIterable<F>) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz));
+    }
+    @Override
+    public NodeIterable<T> filterInterface(Class<?> iface) {
+        return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface));
+    }
+    @Override
+    public FilteredNodeIterable<T> filter(NodePredicate predicate) {
+        return new FilteredNodeIterable<>(this).and(predicate);
+    }
+    @Override
+    public FilteredNodeIterable<T> nonNull() {
+        return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull());
+    }
+    @Override
+    public NodeIterable<T> distinct() {
+        return new FilteredNodeIterable<>(this).distinct();
+    }
+    @Override
+    public T first() {
+        if (size() > 0) {
+            return get(0);
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java	Wed Jun 27 17:35:32 2012 +0200
@@ -43,7 +43,7 @@
 
     @Override
     protected void update(T oldNode, T newNode) {
-        self.updatePredecessors(oldNode, newNode);
+        self.updatePredecessor(oldNode, newNode);
     }
 
     @Override
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorsIterable.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorsIterable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,7 +25,7 @@
 import com.oracle.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.graal.graph.iterators.*;
 
-public abstract class NodeSuccessorsIterable extends NodeIterable<Node> {
+public abstract class NodeSuccessorsIterable extends AbstractNodeIterable<Node> {
     @Override
     public abstract NodeClassIterator iterator();
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeUsagesList.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeUsagesList.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.graph.iterators.*;
 
-public final class NodeUsagesList extends NodeIterable<Node> {
+public final class NodeUsagesList extends AbstractNodeIterable<Node> {
 
     protected static final Node[] EMPTY_NODE_ARRAY = new Node[0];
 
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/VerificationError.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/VerificationError.java	Wed Jun 27 17:35:32 2012 +0200
@@ -28,9 +28,6 @@
  */
 public class VerificationError extends GraalInternalError {
 
-    /**
-     * 
-     */
     private static final long serialVersionUID = 8459607567446819822L;
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph.iterators;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+
+public abstract class AbstractNodeIterable<T extends Node> implements NodeIterable<T> {
+    @Override
+    public NodeIterable<T> until(final T u) {
+        return new FilteredNodeIterable<>(this).until(u);
+    }
+    @Override
+    public NodeIterable<T> until(final Class<? extends T> clazz) {
+        return new FilteredNodeIterable<>(this).until(clazz);
+    }
+    @Override
+    @SuppressWarnings("unchecked")
+    public <F extends T> NodeIterable<F> filter(Class<F> clazz) {
+        return (NodeIterable<F>) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz));
+    }
+    @Override
+    public NodeIterable<T> filterInterface(Class<?> iface) {
+        return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface));
+    }
+    @Override
+    public FilteredNodeIterable<T> filter(NodePredicate predicate) {
+        return new FilteredNodeIterable<>(this).and(predicate);
+    }
+    @Override
+    public FilteredNodeIterable<T> nonNull() {
+        return new FilteredNodeIterable<>(this).and(NodePredicates.isNotNull());
+    }
+    @Override
+    public NodeIterable<T> distinct() {
+        return new FilteredNodeIterable<>(this).distinct();
+    }
+    @Override
+    public List<T> snapshot() {
+        ArrayList<T> list = new ArrayList<>();
+        for (T n : this) {
+            list.add(n);
+        }
+        return list;
+    }
+    @Override
+    public T first() {
+        Iterator<T> iterator = iterator();
+        if (iterator.hasNext()) {
+            return iterator.next();
+        }
+        return null;
+    }
+    @Override
+    public int count() {
+        int count = 0;
+        Iterator<T> iterator = iterator();
+        while (iterator.hasNext()) {
+            iterator.next();
+            count++;
+        }
+        return count;
+    }
+    @Override
+    public boolean isEmpty() {
+        return !iterator().hasNext();
+    }
+    @Override
+    public boolean isNotEmpty() {
+        return iterator().hasNext();
+    }
+    @Override
+    public boolean contains(T node) {
+        return this.filter(NodePredicates.equals(node)).isNotEmpty();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctFilteredNodeIterable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * 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.graph.iterators;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+
+
+public class DistinctFilteredNodeIterable<T extends Node> extends FilteredNodeIterable<T> {
+
+    public DistinctFilteredNodeIterable(NodeIterable<T> nodeIterable) {
+        super(nodeIterable);
+    }
+
+    @Override
+    public DistinctFilteredNodeIterable<T> distinct() {
+        return this;
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+        return new DistinctPredicatedProxyNodeIterator<>(until, nodeIterable.iterator(), predicate);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctPredicatedProxyNodeIterator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,59 @@
+/*
+ * 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.graph.iterators;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+
+
+public class DistinctPredicatedProxyNodeIterator<T extends Node> extends PredicatedProxyNodeIterator<T> {
+    private NodeBitMap visited;
+
+    public DistinctPredicatedProxyNodeIterator(NodePredicate until, Iterator<T> iterator, NodePredicate predicate) {
+        super(until, iterator, predicate);
+    }
+
+    @Override
+    protected void forward() {
+        if (current == null) {
+            super.forward();
+            while (!accept(current)) {
+                current = null;
+                super.forward();
+            }
+        }
+    }
+
+    private boolean accept(T n) {
+        if (n == null) {
+            return true;
+        }
+        if (visited == null) {
+            visited = n.graph().createNodeBitMap(true);
+        }
+        boolean accept = !visited.isMarked(n);
+        visited.mark(n);
+        return accept;
+    }
+}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/FilteredNodeIterable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,10 +26,10 @@
 
 import com.oracle.graal.graph.*;
 
-public class FilteredNodeIterable<T extends Node> extends NodeIterable<T> {
-    private final NodeIterable<T> nodeIterable;
-    private NodePredicate predicate = NodePredicates.alwaysTrue();
-    private NodePredicate until = NodePredicates.isNull();
+public class FilteredNodeIterable<T extends Node> extends AbstractNodeIterable<T> {
+    protected final NodeIterable<T> nodeIterable;
+    protected NodePredicate predicate = NodePredicates.alwaysTrue();
+    protected NodePredicate until = NodePredicates.isNull();
     public FilteredNodeIterable(NodeIterable<T> nodeIterable) {
         this.nodeIterable = nodeIterable;
     }
@@ -52,9 +52,20 @@
         return this;
     }
     @Override
+    public FilteredNodeIterable<T> nonNull() {
+        this.predicate = this.predicate.or(NodePredicates.isNotNull());
+        return this;
+    }
+    @Override
+    public DistinctFilteredNodeIterable<T> distinct() {
+        DistinctFilteredNodeIterable<T> distinct = new DistinctFilteredNodeIterable<>(nodeIterable);
+        distinct.predicate = predicate;
+        distinct.until = until;
+        return distinct;
+    }
+    @Override
     public Iterator<T> iterator() {
-        final Iterator<T> iterator = nodeIterable.iterator();
-        return new PredicatedProxyNodeIterator<>(until, iterator, predicate);
+        return new PredicatedProxyNodeIterator<>(until, nodeIterable.iterator(), predicate);
     }
 
     @SuppressWarnings("unchecked")
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,53 +26,32 @@
 
 import com.oracle.graal.graph.*;
 
-public abstract class NodeIterable<T extends Node> implements Iterable<T> {
-    public NodeIterable<T> until(final T u) {
-        return new FilteredNodeIterable<>(this).until(u);
-    }
-    public NodeIterable<T> until(final Class<? extends T> clazz) {
-        return new FilteredNodeIterable<>(this).until(clazz);
-    }
-    @SuppressWarnings("unchecked")
-    public <F extends T> FilteredNodeIterable<F> filter(Class<F> clazz) {
-        return (FilteredNodeIterable<F>) new FilteredNodeIterable<>(this).and(NodePredicates.isA(clazz));
-    }
-    public FilteredNodeIterable<T> filterInterface(Class<?> iface) {
-        return new FilteredNodeIterable<>(this).and(NodePredicates.isAInterface(iface));
-    }
-    public FilteredNodeIterable<T> filter(NodePredicate predicate) {
-        return new FilteredNodeIterable<>(this).and(predicate);
-    }
-    public List<T> snapshot() {
-        ArrayList<T> list = new ArrayList<>();
-        for (T n : this) {
-            list.add(n);
-        }
-        return list;
-    }
-    public T first() {
-        Iterator<T> iterator = iterator();
-        if (iterator.hasNext()) {
-            return iterator.next();
-        }
-        return null;
-    }
-    public int count() {
-        int count = 0;
-        Iterator<T> iterator = iterator();
-        while (iterator.hasNext()) {
-            iterator.next();
-            count++;
-        }
-        return count;
-    }
-    public boolean isEmpty() {
-        return count() == 0;
-    }
-    public boolean isNotEmpty() {
-        return iterator().hasNext();
-    }
-    public boolean contains(T node) {
-        return this.filter(NodePredicates.equals(node)).isNotEmpty();
-    }
+public interface NodeIterable<T extends Node> extends Iterable<T> {
+
+    NodeIterable<T> until(T u);
+
+    NodeIterable<T> until(Class< ? extends T> clazz);
+
+    <F extends T> NodeIterable<F> filter(Class<F> clazz);
+
+    NodeIterable<T> filterInterface(Class< ? > iface);
+
+    FilteredNodeIterable<T> filter(NodePredicate predicate);
+
+    FilteredNodeIterable<T> nonNull();
+
+    NodeIterable<T> distinct();
+
+    List<T> snapshot();
+
+    T first();
+
+    int count();
+
+    boolean isEmpty();
+
+    boolean isNotEmpty();
+
+    boolean contains(T node);
+
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/PredicatedProxyNodeIterator.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/PredicatedProxyNodeIterator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 
 import com.oracle.graal.graph.*;
 
-public final class PredicatedProxyNodeIterator<T extends Node> extends NodeIterator<T> {
+public class PredicatedProxyNodeIterator<T extends Node> extends NodeIterator<T> {
     private final Iterator<T> iterator;
     private final NodePredicate predicate;
     private final NodePredicate until;
--- a/graal/com.oracle.graal.graph/test/com/oracle/graal/graph/test/TestNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2011, 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.graph.test;
-
-import com.oracle.graal.graph.*;
-
-
-public class TestNode extends Node implements Node.IterableNodeType {
-    private String name;
-
-    public TestNode(String name) {
-        this.name = name;
-    }
-
-
-    public String getName() {
-        return name;
-    }
-}
--- a/graal/com.oracle.graal.graph/test/com/oracle/graal/graph/test/TypedNodeIteratorTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2011, 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.graph.test;
-import static org.junit.Assert.*;
-
-import java.util.*;
-
-import org.junit.*;
-
-import com.oracle.graal.graph.*;
-
-
-
-public class TypedNodeIteratorTest {
-
-    @Test
-    public void singleNodeTest() {
-        Graph graph = new Graph();
-        graph.add(new TestNode("a"));
-        assertTrue(graph.hasNode(TestNode.class));
-        assertEquals("a", toString(graph.getNodes(TestNode.class)));
-    }
-
-    @Test
-    public void deletingNodeTest() {
-        TestNode testNode = new TestNode("a");
-        Graph graph = new Graph();
-        graph.add(testNode);
-        testNode.safeDelete();
-        assertEquals("", toString(graph.getNodes(TestNode.class)));
-    }
-
-    @Test
-    public void deleteAndAddTest() {
-        TestNode testNode = new TestNode("b");
-        Graph graph = new Graph();
-        graph.add(new TestNode("a"));
-        graph.add(testNode);
-        testNode.safeDelete();
-        assertEquals("a", toString(graph.getNodes(TestNode.class)));
-        graph.add(new TestNode("c"));
-        assertEquals("ac", toString(graph.getNodes(TestNode.class)));
-    }
-
-    @Test
-    public void iteratorBehaviorTest() {
-        Graph graph = new Graph();
-        graph.add(new TestNode("a"));
-        Iterator<TestNode> iterator = graph.getNodes(TestNode.class).iterator();
-        assertTrue(iterator.hasNext());
-        assertEquals("a", iterator.next().getName());
-        assertFalse(iterator.hasNext());
-        graph.add(new TestNode("b"));
-        assertTrue(iterator.hasNext());
-        assertEquals("b", iterator.next().getName());
-        assertFalse(iterator.hasNext());
-        TestNode c = new TestNode("c");
-        graph.add(c);
-        assertTrue(iterator.hasNext());
-        c.safeDelete();
-        assertFalse(iterator.hasNext());
-    }
-
-    @Test
-    public void complicatedIterationTest() {
-        Graph graph = new Graph();
-        graph.add(new TestNode("a"));
-        for (TestNode tn : graph.getNodes(TestNode.class)) {
-            String name = tn.getName();
-            for (int i = 0; i < name.length(); ++i) {
-                char c = name.charAt(i);
-                if (c == 'a') {
-                    tn.safeDelete();
-                    graph.add(new TestNode("b"));
-                    graph.add(new TestNode("c"));
-                } else if (c == 'b') {
-                    tn.safeDelete();
-                } else if (c == 'c') {
-                    graph.add(new TestNode("d"));
-                    graph.add(new TestNode("e"));
-                    graph.add(new TestNode("d"));
-                    graph.add(new TestNode("e"));
-                    graph.add(new TestNode("e"));
-                    graph.add(new TestNode("d"));
-                    graph.add(new TestNode("e"));
-                    graph.add(new TestNode("d"));
-                } else if (c == 'd') {
-                    for (TestNode tn2 : graph.getNodes(TestNode.class)) {
-                        if (tn2.getName().equals("e")) {
-                            tn2.safeDelete();
-                        } else if (tn2.getName().equals("c")) {
-                            tn2.safeDelete();
-                        }
-                    }
-                } else if (c == 'e') {
-                    fail("All e nodes must have been deleted by visiting the d node");
-                }
-            }
-        }
-        assertEquals("dddd", toString(graph.getNodes(TestNode.class)));
-    }
-
-    @Test
-    public void addingNodeDuringIterationTest() {
-        Graph graph = new Graph();
-        graph.add(new TestNode("a"));
-        StringBuilder sb = new StringBuilder();
-        int z = 0;
-        for (TestNode tn : graph.getNodes(TestNode.class)) {
-            if (z == 0) {
-                graph.add(new TestNode("b"));
-            }
-            sb.append(tn.getName());
-            z++;
-        }
-        assertEquals(2, z);
-        assertEquals("ab", sb.toString());
-        z = 0;
-        for (TestNode tn : graph.getNodes(TestNode.class)) {
-            if (z == 0) {
-                graph.add(new TestNode("c"));
-            }
-            assertNotNull(tn);
-            z++;
-        }
-        assertEquals(3, z);
-    }
-
-    private static String toString(Iterable<TestNode> nodes) {
-        StringBuilder sb = new StringBuilder();
-        for (TestNode tn : nodes) {
-            sb.append(tn.getName());
-        }
-        return sb.toString();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/CompilationServer.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.server;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.net.*;
+
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.logging.*;
+
+/**
+ * Server side of the client/server compilation model. The server listens for connections on the hardcoded port 1199.
+ */
+public class CompilationServer implements Runnable {
+
+    public static void main(String[] args) throws Exception {
+        new CompilationServer(false).run();
+    }
+
+    public interface ConnectionObserver {
+
+        void connectionStarted(HotSpotGraalRuntime compiler);
+
+        void connectionFinished(HotSpotGraalRuntime compiler);
+    }
+
+    private final boolean multiple;
+    private final ArrayList<ConnectionObserver> observers = new ArrayList<>();
+
+    /**
+     * Creates a new Compilation server. The server is activated by calling {@link #run()} directly or via a new
+     * {@link Thread}.
+     *
+     * @param multiple true if the server should server should serve an infinite amount of consecutive connections,
+     *            false if it should terminate after the first connection ends.
+     */
+    public CompilationServer(boolean multiple) {
+        this.multiple = multiple;
+        HotSpotOptions.setDefaultOptions();
+    }
+
+    public void addConnectionObserver(ConnectionObserver observer) {
+        observers.add(observer);
+    }
+
+    public void removeConnectionObserver(ConnectionObserver observer) {
+        observers.remove(observer);
+    }
+
+    public void run() {
+        final ServerSocket serverSocket;
+        try {
+            serverSocket = ServerSocketFactory.getDefault().createServerSocket(1199);
+        } catch (IOException e) {
+            throw new RuntimeException("Couldn't create compilation server", e);
+        }
+        do {
+            Socket socket = null;
+            try {
+                Logger.log("Compilation server ready, waiting for client to connect...");
+                socket = serverSocket.accept();
+                Logger.log("Connected to " + socket.getRemoteSocketAddress());
+
+                ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream());
+
+                // get the CompilerToVM proxy from the client
+                CompilerToVM toVM = (CompilerToVM) streams.getInvocation().waitForResult(false);
+
+                // return the initialized compiler to the client
+                HotSpotGraalRuntime compiler = initializeServer(toVM);
+                compiler.getCompiler();
+                streams.getInvocation().sendResult(compiler);
+
+                for (ConnectionObserver observer : observers) {
+                    observer.connectionStarted(compiler);
+                }
+
+                streams.getInvocation().waitForResult(true);
+
+                for (ConnectionObserver observer : observers) {
+                    observer.connectionFinished(compiler);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException(e);
+            } finally {
+                if (socket != null) {
+                    try {
+                        socket.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        } while (multiple);
+    }
+
+    @SuppressWarnings("unused")
+    private static HotSpotGraalRuntime initializeServer(CompilerToVM toVM) {
+        // TODO(thomaswue): Fix creation of compiler instances on server side.
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/InvocationSocket.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.server;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.hotspot.logging.*;
+
+/**
+ * A collection of java.lang.reflect proxies that communicate over a socket connection.
+ *
+ * Calling a method sends the method name and the parameters through the socket. Afterwards this class waits for a
+ * result. While waiting for a result three types of objects can arrive through the socket: a method invocation, a
+ * method result or an exception. Method invocation can thus be recursive.
+ */
+public class InvocationSocket {
+
+    private static final boolean DEBUG = false;
+    private static final boolean COUNT_CALLS = false;
+
+    private static final HashSet<String> cachedMethodNames = new HashSet<>();
+    private static final HashSet<String> forbiddenMethodNames = new HashSet<>();
+
+    static {
+        cachedMethodNames.add("name");
+        cachedMethodNames.add("kind");
+        cachedMethodNames.add("isResolved");
+        cachedMethodNames.add("getCompilerToVM");
+        cachedMethodNames.add("exactType");
+        cachedMethodNames.add("isInitialized");
+        forbiddenMethodNames.add("javaClass");
+    }
+
+    private final ObjectOutputStream output;
+    private final ObjectInputStream input;
+
+    private final Map<String, Integer> counts = new HashMap<>();
+
+    public InvocationSocket(ObjectOutputStream output, ObjectInputStream input) {
+        this.output = output;
+        this.input = input;
+
+        if (COUNT_CALLS) {
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                @Override
+                public void run() {
+                    SortedMap<Integer, String> sorted = new TreeMap<>();
+                    for (Map.Entry<String, Integer> entry : counts.entrySet()) {
+                        sorted.put(entry.getValue(), entry.getKey());
+                    }
+                    for (Map.Entry<Integer, String> entry : sorted.entrySet()) {
+                        System.out.println(entry.getKey() + ": " + entry.getValue());
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Represents one invocation of a method that is transferred via the socket connection.
+     *
+     */
+    private static class Invocation implements Serializable {
+
+        private static final long serialVersionUID = -799162779226626066L;
+
+        public Object receiver;
+        public String methodName;
+        public Object[] args;
+
+        public Invocation(Object receiver, String methodName, Object[] args) {
+            this.receiver = receiver;
+            this.methodName = methodName;
+            this.args = args;
+        }
+    }
+
+    /**
+     * Represents the result of an invocation that is transferred via the socket connection.
+     *
+     */
+    private static class Result implements Serializable {
+
+        private static final long serialVersionUID = -7496058356272415814L;
+
+        public Object result;
+
+        public Result(Object result) {
+            this.result = result;
+        }
+    }
+
+    private void incCount(String name, Object[] args) {
+        if (COUNT_CALLS) {
+            String nameAndArgCount = name + (args == null ? 0 : args.length);
+            if (counts.get(nameAndArgCount) != null) {
+                counts.put(nameAndArgCount, counts.get(nameAndArgCount) + 1);
+            } else {
+                counts.put(nameAndArgCount, 1);
+            }
+        }
+    }
+
+    /**
+     * Each instance of this class handles remote invocations for one instance of a Remote class. It will forward all
+     * interface methods to the other end of the socket and cache the results of calls to certain methods.
+     *
+     */
+    public class Handler implements InvocationHandler {
+
+        private final Object receiver;
+        private final HashMap<String, Object> cache = new HashMap<>();
+
+        public Handler(Object receiver) {
+            this.receiver = receiver;
+        }
+
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            // only interface methods can be transferred, java.lang.Object methods
+            if (method.getDeclaringClass() == Object.class) {
+                return method.invoke(receiver, args);
+            }
+            String methodName = method.getName();
+            // check if the result of this zero-arg method was cached
+            if (args == null || args.length == 0) {
+                if (cache.containsKey(methodName)) {
+                    return cache.get(methodName);
+                }
+            }
+            if (forbiddenMethodNames.contains(methodName)) {
+                throw new IllegalAccessException(methodName + " not allowed");
+            }
+            Object result = null;
+            try {
+                if (DEBUG) {
+                    Logger.startScope("invoking remote " + methodName);
+                }
+                incCount(methodName, args);
+
+                output.writeObject(new Invocation(receiver, methodName, args));
+                output.flush();
+                result = waitForResult(false);
+
+                // result caching for selected methods
+                if ((args == null || args.length == 0) && cachedMethodNames.contains(methodName)) {
+                    cache.put(methodName, result);
+                }
+                return result;
+            } catch (Throwable t) {
+                t.printStackTrace();
+                throw t;
+            } finally {
+                if (DEBUG) {
+                    Logger.endScope(" = " + result);
+                }
+            }
+        }
+    }
+
+    /**
+     * Waits for the result of a remote method invocation. Invocations that should be executed in this VM might arrive
+     * while waiting for the result, and these invocations will be executed before again waiting fort he result.
+     */
+    @SuppressWarnings("unused")
+    public Object waitForResult(boolean eofExpected) throws IOException, ClassNotFoundException {
+        while (true) {
+            Object in;
+            try {
+                in = input.readObject();
+            } catch (EOFException e) {
+                if (eofExpected) {
+                    return null;
+                }
+                throw e;
+            }
+            if (in instanceof Result) {
+                return ((Result) in).result;
+            } else if (in instanceof RuntimeException) {
+                throw (RuntimeException) in;
+            } else if (in instanceof Throwable) {
+                throw new RuntimeException((Throwable) in);
+            }
+
+            Invocation invoke = (Invocation) in;
+            Method method = null;
+            for (Class<?> clazz = invoke.receiver.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+                for (Method m : clazz.getDeclaredMethods()) {
+                    if (invoke.methodName.equals(m.getName())) {
+                        method = m;
+                        break;
+                    }
+                }
+            }
+            if (method == null) {
+                Exception e = new UnsupportedOperationException("unknown method " + invoke.methodName);
+                e.printStackTrace();
+                output.writeObject(e);
+                output.flush();
+            } else {
+                Object result = null;
+                try {
+                    if (invoke.args == null) {
+                        if (DEBUG) {
+                            Logger.startScope("invoking local " + invoke.methodName);
+                        }
+                        result = method.invoke(invoke.receiver);
+                    } else {
+                        if (Logger.ENABLED && DEBUG) {
+                            StringBuilder str = new StringBuilder();
+                            str.append("invoking local " + invoke.methodName + "(");
+                            for (int i = 0; i < invoke.args.length; i++) {
+                                str.append(i == 0 ? "" : ", ");
+                                str.append(Logger.pretty(invoke.args[i]));
+                            }
+                            str.append(")");
+                            Logger.startScope(str.toString());
+                        }
+                        result = method.invoke(invoke.receiver, invoke.args);
+                    }
+                    result = new Result(result);
+                } catch (IllegalArgumentException e) {
+                    System.out.println("error while invoking " + invoke.methodName);
+                    e.getCause().printStackTrace();
+                    result = e.getCause();
+                } catch (InvocationTargetException e) {
+                    System.out.println("error while invoking " + invoke.methodName);
+                    e.getCause().printStackTrace();
+                    result = e.getCause();
+                } catch (IllegalAccessException e) {
+                    System.out.println("error while invoking " + invoke.methodName);
+                    e.getCause().printStackTrace();
+                    result = e.getCause();
+                } finally {
+                    if (DEBUG) {
+                        if (result instanceof Result) {
+                            Logger.endScope(" = " + ((Result) result).result);
+                        } else {
+                            Logger.endScope(" = " + result);
+                        }
+                    }
+                }
+                output.writeObject(result);
+                output.flush();
+            }
+        }
+    }
+
+    /**
+     * Sends a result without invoking a method, used by CompilationServer startup code.
+     */
+    public void sendResult(Object obj) throws IOException {
+        output.writeObject(new Result(obj));
+        output.flush();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/Remote.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.server;
+
+
+public interface Remote {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.server;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.logging.*;
+
+public class ReplacingStreams {
+
+    private IdentityHashMap<Object, Placeholder> objectMap = new IdentityHashMap<>();
+    private ArrayList<Object> objectList = new ArrayList<>();
+
+    private ReplacingOutputStream output;
+    private ReplacingInputStream input;
+
+    private InvocationSocket invocation;
+
+    public ReplacingStreams(OutputStream outputStream, InputStream inputStream) throws IOException {
+        output = new ReplacingOutputStream(new BufferedOutputStream(outputStream));
+        // required, because creating an ObjectOutputStream writes a header, but doesn't flush the stream
+        output.flush();
+        input = new ReplacingInputStream(new BufferedInputStream(inputStream));
+        invocation = new InvocationSocket(output, input);
+
+        addStaticObject(Value.IllegalValue);
+        addStaticObject(HotSpotProxy.DUMMY_CONSTANT_OBJ);
+    }
+
+    public void setInvocationSocket(InvocationSocket invocation) {
+        this.invocation = invocation;
+    }
+
+    public ReplacingOutputStream getOutput() {
+        return output;
+    }
+
+    public ReplacingInputStream getInput() {
+        return input;
+    }
+
+    public InvocationSocket getInvocation() {
+        return invocation;
+    }
+
+    private void addStaticObject(Object obj) {
+        int id = objectList.size();
+        objectList.add(obj);
+        objectMap.put(obj, new Placeholder(id));
+    }
+
+    public static class Placeholder implements Serializable {
+
+        private static final long serialVersionUID = 6071894297788156945L;
+        public final int id;
+
+        public Placeholder(int id) {
+            this.id = id;
+        }
+
+        @Override
+        public String toString() {
+            return "#<" + id + ">";
+        }
+    }
+
+    public static class NewRemoteCallPlaceholder implements Serializable {
+
+        private static final long serialVersionUID = 3084101671389500206L;
+        public final Class<?>[] interfaces;
+
+        public NewRemoteCallPlaceholder(Class<?>[] interfaces) {
+            this.interfaces = interfaces;
+        }
+    }
+
+    public static class NewDummyPlaceholder implements Serializable {
+        private static final long serialVersionUID = 2692666726573532288L;
+    }
+
+    /**
+     * Replaces certain cir objects that cannot easily be made Serializable.
+     */
+    public class ReplacingInputStream extends ObjectInputStream {
+
+        public ReplacingInputStream(InputStream in) throws IOException {
+            super(in);
+            enableResolveObject(true);
+        }
+
+        @Override
+        protected Object resolveObject(Object obj) throws IOException {
+            // see ReplacingInputStream.replaceObject for details on when these types of objects are created
+
+            if (obj instanceof Placeholder) {
+                Placeholder placeholder = (Placeholder) obj;
+                Object resolvedObj = objectList.get(placeholder.id);
+                return resolvedObj;
+            }
+
+            if (obj instanceof NewRemoteCallPlaceholder) {
+                NewRemoteCallPlaceholder newPlaceholder = (NewRemoteCallPlaceholder) obj;
+                Placeholder placeholder = new Placeholder(objectList.size());
+                Object resolvedObj = Proxy.newProxyInstance(getClass().getClassLoader(), newPlaceholder.interfaces, invocation.new Handler(placeholder));
+                objectMap.put(resolvedObj, placeholder);
+                objectList.add(resolvedObj);
+                return resolvedObj;
+            }
+
+            if (obj instanceof NewDummyPlaceholder) {
+                Object resolvedObj = new Placeholder(objectList.size());
+                objectMap.put(resolvedObj, (Placeholder) resolvedObj);
+                objectList.add(resolvedObj);
+                return resolvedObj;
+            }
+
+            return obj;
+        }
+    }
+
+    /**
+     * Replaces certain cir objects that cannot easily be made Serializable.
+     */
+    public class ReplacingOutputStream extends ObjectOutputStream {
+
+        public ReplacingOutputStream(OutputStream out) throws IOException {
+            super(out);
+            enableReplaceObject(true);
+        }
+
+        @Override
+        protected Object replaceObject(Object obj) throws IOException {
+            // is the object a known instance?
+            Placeholder placeholder = objectMap.get(obj);
+            if (placeholder != null) {
+                return placeholder;
+            }
+
+            // is the object an instance of a class that will always be executed remotely?
+            if (obj instanceof Remote) {
+                return createRemoteCallPlaceholder(obj);
+            }
+
+            // is the object a constant of object type?
+            if (obj.getClass() == Constant.class) {
+                Constant constant = (Constant) obj;
+                if (constant.kind != Kind.Object) {
+                    return obj;
+                }
+                Object contents = constant.asObject();
+                if (contents == null) {
+                    return obj;
+                }
+                // don't replace if the object already is a placeholder
+                if (contents instanceof Placeholder || contents instanceof Long) {
+                    return obj;
+                }
+                placeholder = objectMap.get(contents);
+                if (placeholder != null) {
+                    return Constant.forObject(placeholder);
+                }
+                if (contents instanceof Remote) {
+                    return Constant.forObject(createRemoteCallPlaceholder(contents));
+                }
+                return Constant.forObject(createDummyPlaceholder(contents));
+            }
+            return obj;
+        }
+    }
+
+    private Object createRemoteCallPlaceholder(Object obj) {
+        // collect all interfaces that this object's class implements (proxies only support interfaces)
+        objectMap.put(obj, new Placeholder(objectList.size()));
+        objectList.add(obj);
+        return new NewRemoteCallPlaceholder(ProxyUtil.getAllInterfaces(obj.getClass()));
+    }
+
+    public Object createDummyPlaceholder(Object obj) {
+        objectMap.put(obj, new Placeholder(objectList.size()));
+        objectList.add(obj);
+        return new NewDummyPlaceholder();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.server/src/com/oracle/graal/hotspot/server/package-info.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+/**
+ * Implementation of a compilation server socket that delegates incoming requests to Graal.
+ */
+package com.oracle.graal.hotspot.server;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,212 @@
+/*
+ * 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.hotspot;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+@SuppressWarnings("unused")
+public final class CompilationStatistics {
+
+    private static final long RESOLUTION = 100000000;
+    private static final boolean TIMELINE_ENABLED = System.getProperty("stats.timeline.file") != null;
+    private static final boolean COMPILATIONSTATS_ENABLED = System.getProperty("stats.compilations.file") != null;
+    private static final boolean ENABLED = TIMELINE_ENABLED || COMPILATIONSTATS_ENABLED;
+
+    private static final CompilationStatistics DUMMY = new CompilationStatistics(null);
+
+    private static ConcurrentLinkedDeque<CompilationStatistics> list = new ConcurrentLinkedDeque<>();
+
+    private static final ThreadLocal<Deque<CompilationStatistics>> current = new ThreadLocal<Deque<CompilationStatistics>>() {
+
+        @Override
+        protected Deque<CompilationStatistics> initialValue() {
+            return new ArrayDeque<>();
+        }
+    };
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    private static @interface AbsoluteTimeValue {
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    private static @interface TimeValue {
+    }
+
+    private static long zeroTime = System.nanoTime();
+
+    private final String holder;
+    private final String name;
+    private final String signature;
+    @AbsoluteTimeValue
+    private final long startTime;
+    @TimeValue
+    private long duration;
+    private int startInvCount;
+    private int endInvCount;
+    private int bytecodeCount;
+    private int codeSize;
+    private int deoptCount;
+
+    private CompilationStatistics(ResolvedJavaMethod method) {
+        if (method != null) {
+            holder = CodeUtil.format("%H", method);
+            name = method.name();
+            signature = CodeUtil.format("%p", method);
+            startTime = System.nanoTime();
+            startInvCount = method.invocationCount();
+            bytecodeCount = method.codeSize();
+        } else {
+            holder = "";
+            name = "";
+            signature = "";
+            startTime = 0;
+        }
+    }
+
+    public void finish(ResolvedJavaMethod method) {
+        if (ENABLED) {
+            duration = System.nanoTime() - startTime;
+            endInvCount = method.invocationCount();
+            codeSize = method.compiledCodeSize();
+            if (current.get().getLast() != this) {
+                throw new RuntimeException("mismatch in finish()");
+            }
+            current.get().removeLast();
+        }
+    }
+
+    public static CompilationStatistics current() {
+        return current.get().isEmpty() ? null : current.get().getLast();
+    }
+
+    public static CompilationStatistics create(ResolvedJavaMethod method) {
+        if (ENABLED) {
+            CompilationStatistics stats = new CompilationStatistics(method);
+            list.add(stats);
+            current.get().addLast(stats);
+            return stats;
+        } else {
+            return DUMMY;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public static void clear(String dumpName) {
+        if (!ENABLED) {
+            return;
+        }
+        try {
+            ConcurrentLinkedDeque<CompilationStatistics> snapshot = list;
+            long snapshotZeroTime = zeroTime;
+
+            list = new ConcurrentLinkedDeque<>();
+            zeroTime = System.nanoTime();
+
+            Date now = new Date();
+            String dateString = (now.getYear() + 1900) + "_" + (now.getMonth() + 1) + "_" + now.getDate() + " " + now.getHours() + "_" + now.getMinutes() + "_" + now.getSeconds();
+            try (PrintStream out = new PrintStream("compilations " + dateString + " " + dumpName + ".csv")) {
+                // output the list of all compilations
+
+                Field[] declaredFields = CompilationStatistics.class.getDeclaredFields();
+                ArrayList<Field> fields = new ArrayList<>();
+                for (Field field : declaredFields) {
+                    if (!Modifier.isStatic(field.getModifiers())) {
+                        fields.add(field);
+                    }
+                }
+                for (Field field : fields) {
+                    out.print(field.getName() + ";");
+                }
+                out.println();
+                for (CompilationStatistics stats : snapshot) {
+                    for (Field field : fields) {
+                        if (field.isAnnotationPresent(AbsoluteTimeValue.class)) {
+                            double value = (field.getLong(stats) - snapshotZeroTime) / 1000000d;
+                            out.print(String.format(Locale.ENGLISH, "%.3f", value) + ";");
+                        } else if (field.isAnnotationPresent(TimeValue.class)) {
+                            double value = field.getLong(stats) / 1000000d;
+                            out.print(String.format(Locale.ENGLISH, "%.3f", value) + ";");
+                        } else {
+                            out.print(field.get(stats) + ";");
+                        }
+                    }
+                    out.println();
+                }
+            }
+
+            String timelineFile = System.getProperty("stats.timeline.file");
+            if (timelineFile == null || timelineFile.isEmpty()) {
+                timelineFile = "timeline " + dateString;
+            }
+            try (FileOutputStream fos = new FileOutputStream(timelineFile + " " + dumpName + ".csv", true); PrintStream out = new PrintStream(fos)) {
+
+                long[] timeSpent = new long[10000];
+                int maxTick = 0;
+                for (CompilationStatistics stats : snapshot) {
+                    long start = stats.startTime - snapshotZeroTime;
+                    long duration = stats.duration;
+                    if (start < 0) {
+                        duration -= -start;
+                        start = 0;
+                    }
+
+                    int tick = (int) (start / RESOLUTION);
+                    long timeLeft = RESOLUTION - (start % RESOLUTION);
+
+                    while (tick < timeSpent.length && duration > 0) {
+                        if (tick > maxTick) {
+                            maxTick = tick;
+                        }
+                        timeSpent[tick] += Math.min(timeLeft, duration);
+                        duration -= timeLeft;
+                        tick++;
+                        timeLeft = RESOLUTION;
+                    }
+                }
+                String timelineName = System.getProperty("stats.timeline.name");
+                if (timelineName != null && !timelineName.isEmpty()) {
+                    out.print(timelineName + ";");
+                }
+                for (int i = 0; i <= maxTick; i++) {
+                    out.print((timeSpent[i] * 100 / RESOLUTION) + ";");
+                }
+                out.println();
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void setDeoptCount(int count) {
+        this.deoptCount = count;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,14 +24,13 @@
 
 import java.util.concurrent.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
-import com.oracle.graal.cri.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.hotspot.ri.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 
 
@@ -48,18 +47,18 @@
 
     private volatile boolean cancelled;
 
-    private final Compiler compiler;
+    private final HotSpotGraalRuntime compiler;
     private final PhasePlan plan;
-    private final HotSpotMethodResolved method;
+    private final HotSpotResolvedJavaMethod method;
     private final OptimisticOptimizations optimisticOpts;
     private final int id;
     private final int priority;
 
-    public static CompilationTask create(Compiler compiler, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotMethodResolved method, int id, int priority) {
+    public static CompilationTask create(HotSpotGraalRuntime compiler, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int id, int priority) {
         return new CompilationTask(compiler, plan, optimisticOpts, method, id, priority);
     }
 
-    private CompilationTask(Compiler compiler, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotMethodResolved method, int id, int priority) {
+    private CompilationTask(HotSpotGraalRuntime compiler, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int id, int priority) {
         this.compiler = compiler;
         this.plan = plan;
         this.method = method;
@@ -68,7 +67,7 @@
         this.priority = priority;
     }
 
-    public RiResolvedMethod method() {
+    public ResolvedJavaMethod method() {
         return method;
     }
 
@@ -80,8 +79,6 @@
         cancelled = true;
     }
 
-//    private static PrintStream out = System.out;
-
     public void run() {
         withinEnqueue.set(Boolean.FALSE);
         try {
@@ -104,20 +101,20 @@
     }
 
     public void runCompilation() {
-        CiCompilationStatistics stats = CiCompilationStatistics.create(method);
+        CompilationStatistics stats = CompilationStatistics.create(method);
         try {
             final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed();
             if (printCompilation) {
                 TTY.println(String.format("%-6d Graal %-70s %-45s %-50s ...", id, method.holder().name(), method.name(), method.signature().asString()));
             }
 
-            CiTargetMethod result = null;
+            CompilationResult result = null;
             TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
             try {
-                result = Debug.scope("Compiling", new Callable<CiTargetMethod>() {
+                result = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true), new Callable<CompilationResult>() {
 
                     @Override
-                    public CiTargetMethod call() throws Exception {
+                    public CompilationResult call() throws Exception {
                         compiler.evictDeoptedGraphs();
                         StructuredGraph graph = new StructuredGraph(method);
                         return compiler.getCompiler().compileMethod(method, graph, -1, compiler.getCache(), plan, optimisticOpts);
@@ -131,14 +128,14 @@
             }
 
             installMethod(result);
-        } catch (CiBailout bailout) {
+        } catch (BailoutException bailout) {
             Debug.metric("Bailouts").increment();
             if (GraalOptions.ExitVMOnBailout) {
-                TTY.cachedOut.println(CiUtil.format("Bailout in %H.%n(%p)", method));
+                TTY.cachedOut.println(CodeUtil.format("Bailout in %H.%n(%p)", method));
                 bailout.printStackTrace(TTY.cachedOut);
                 System.exit(-1);
             } else if (GraalOptions.PrintBailout) {
-                TTY.cachedOut.println(CiUtil.format("Bailout in %H.%n(%p)", method));
+                TTY.cachedOut.println(CodeUtil.format("Bailout in %H.%n(%p)", method));
                 bailout.printStackTrace(TTY.cachedOut);
             }
         } catch (Throwable t) {
@@ -150,14 +147,14 @@
         stats.finish(method);
     }
 
-    private void installMethod(final CiTargetMethod tm) {
-        Debug.scope("CodeInstall", new Object[] {compiler.getCompiler(), method}, new Runnable() {
+    private void installMethod(final CompilationResult tm) {
+        Debug.scope("CodeInstall", new Object[] {new DebugDumpScope(String.valueOf(id), true), compiler.getCompiler(), method}, new Runnable() {
             @Override
             public void run() {
-                final HotSpotCodeInfo info = Debug.isDumpEnabled() ? new HotSpotCodeInfo(compiler, tm, method) : null;
+                final CodeInfo[] info = Debug.isDumpEnabled() ? new CodeInfo[1] : null;
                 compiler.getRuntime().installMethod(method, tm, info);
                 if (info != null) {
-                    Debug.dump(info, "After code installation");
+                    Debug.dump(new Object[] {tm, info[0]}, "After code installation");
                 }
             }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/Compiler.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.graph.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.ri.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-
-public interface Compiler {
-
-    CompilerToVM getCompilerToVM();
-    VMToCompiler getVMToCompiler();
-    GraalCompiler getCompiler();
-    RiType lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve);
-    HotSpotVMConfig getConfig();
-    HotSpotRuntime getRuntime();
-    CiTarget getTarget();
-    GraphCache getCache();
-    void evictDeoptedGraphs();
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerImpl.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.*;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.graph.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.cri.*;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.logging.*;
-import com.oracle.graal.hotspot.ri.*;
-import com.oracle.graal.hotspot.server.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.*;
-
-/**
- * Singleton class holding the instance of the GraalCompiler.
- */
-public final class CompilerImpl implements Compiler, Remote {
-
-    private static Compiler theInstance;
-
-    public static Compiler getInstance() {
-        if (theInstance == null) {
-            initialize();
-        }
-        return theInstance;
-    }
-
-    public static synchronized void initialize() {
-        if (theInstance != null) {
-            return;
-        }
-
-        String remote = System.getProperty("graal.remote");
-        if (remote != null) {
-            // remote compilation (will not create a local Compiler)
-            try {
-                System.out.println("Graal compiler started in client/server mode, server: " + remote);
-                Socket socket = new Socket(remote, 1199);
-                ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream());
-                streams.getInvocation().sendResult(new CompilerToVMImpl());
-
-                theInstance = (Compiler) streams.getInvocation().waitForResult(false);
-            } catch (IOException e1) {
-                System.out.println("Connection to compilation server FAILED.");
-                throw new RuntimeException(e1);
-            } catch (ClassNotFoundException e2) {
-                System.out.println("Connection to compilation server FAILED.");
-                throw new RuntimeException(e2);
-            }
-        } else {
-            // ordinary local compilation
-            theInstance = new CompilerImpl(null);
-        }
-    }
-
-    public static Compiler initializeServer(CompilerToVM entries) {
-        assert theInstance == null;
-        theInstance = new CompilerImpl(entries);
-        return theInstance;
-    }
-
-    private final CompilerToVM compilerToVm;
-    private final VMToCompiler vmToCompiler;
-
-    private HotSpotRuntime runtime;
-    private GraalCompiler compiler;
-    private CiTarget target;
-    private volatile GraphCache cache;
-
-    private final HotSpotVMConfig config;
-
-    public HotSpotVMConfig getConfig() {
-        return config;
-    }
-
-    private CompilerImpl(CompilerToVM initialEntries) {
-
-        CompilerToVM toVM = initialEntries;
-        // initialize CompilerToVM
-        if (toVM == null) {
-            toVM = new CompilerToVMImpl();
-        }
-
-        // initialize VmToCompiler
-        VMToCompiler toCompiler = new VMToCompilerImpl(this);
-
-        // logging, etc.
-        if (CountingProxy.ENABLED) {
-            toCompiler = CountingProxy.getProxy(VMToCompiler.class, toCompiler);
-            toVM = CountingProxy.getProxy(CompilerToVM.class, toVM);
-        }
-        if (Logger.ENABLED) {
-            toCompiler = LoggingProxy.getProxy(VMToCompiler.class, toCompiler);
-            toVM = LoggingProxy.getProxy(CompilerToVM.class, toVM);
-        }
-
-        // set the final fields
-        compilerToVm = toVM;
-        vmToCompiler = toCompiler;
-
-        // initialize compiler
-        config = compilerToVm.getConfiguration();
-        config.check();
-
-        if (Boolean.valueOf(System.getProperty("graal.printconfig"))) {
-            printConfig(config);
-        }
-    }
-
-    private static void printConfig(HotSpotVMConfig config) {
-        Field[] fields = config.getClass().getDeclaredFields();
-        for (Field f : fields) {
-            f.setAccessible(true);
-            try {
-                Logger.info(String.format("%9s %-40s = %s", f.getType().getSimpleName(), f.getName(), Logger.pretty(f.get(config))));
-            } catch (Exception e) {
-            }
-        }
-    }
-
-    @Override
-    public CiTarget getTarget() {
-        if (target == null) {
-            final int wordSize = 8;
-            final int stackFrameAlignment = 16;
-            target = new CiTarget(new AMD64(), true, stackFrameAlignment, config.vmPageSize, wordSize, true, true, true);
-        }
-
-        return target;
-    }
-
-    /**
-     * Factory method for getting a Graal compiler instance. This method is called via reflection.
-     */
-    public static GraalRuntime getGraalRuntime() {
-        return getInstance().getRuntime();
-    }
-
-    @Override
-    public GraalCompiler getCompiler() {
-        if (compiler == null) {
-            // these options are important - graal will not generate correct code without them
-            GraalOptions.StackShadowPages = config.stackShadowPages;
-
-            RiXirGenerator generator = new HotSpotXirGenerator(config, getTarget(), getRuntime().getGlobalStubRegisterConfig(), this);
-            if (Logger.ENABLED) {
-                generator = LoggingProxy.getProxy(RiXirGenerator.class, generator);
-            }
-
-            Backend backend = Backend.create(runtime, target);
-            generator.initialize(backend.newXirAssembler());
-
-            compiler = new GraalCompiler(getRuntime(), getTarget(), backend, generator);
-            if (GraalOptions.CacheGraphs) {
-                cache = new GraphCache(GraalOptions.PrintGraphCache);
-            }
-        }
-        return compiler;
-    }
-
-    @Override
-    public GraphCache getCache() {
-        return cache;
-    }
-
-    @Override
-    public CompilerToVM getCompilerToVM() {
-        return compilerToVm;
-    }
-
-    @Override
-    public VMToCompiler getVMToCompiler() {
-        return vmToCompiler;
-    }
-
-    @Override
-    public RiType lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve) {
-        if (returnType.length() == 1 && vmToCompiler instanceof VMToCompilerImpl) {
-            VMToCompilerImpl exitsNative = (VMToCompilerImpl) vmToCompiler;
-            CiKind kind = CiKind.fromPrimitiveOrVoidTypeChar(returnType.charAt(0));
-            switch(kind) {
-                case Boolean:
-                    return exitsNative.typeBoolean;
-                case Byte:
-                    return exitsNative.typeByte;
-                case Char:
-                    return exitsNative.typeChar;
-                case Double:
-                    return exitsNative.typeDouble;
-                case Float:
-                    return exitsNative.typeFloat;
-                case Illegal:
-                    break;
-                case Int:
-                    return exitsNative.typeInt;
-                case Jsr:
-                    break;
-                case Long:
-                    return exitsNative.typeLong;
-                case Object:
-                    break;
-                case Short:
-                    return exitsNative.typeShort;
-                case Void:
-                    return exitsNative.typeVoid;
-            }
-        }
-        return compilerToVm.RiSignature_lookupType(returnType, accessingClass, eagerResolve);
-    }
-
-    @Override
-    public HotSpotRuntime getRuntime() {
-        if (runtime == null) {
-            if (GraalOptions.PrintCFGToFile) {
-//                context.addCompilationObserver(new CFGPrinterObserver());
-            }
-           // if (GraalOptions.PrintIdealGraphLevel != 0 || GraalOptions.Plot || GraalOptions.PlotOnError) {
-             //   CompilationObserver observer;
-               // if (GraalOptions.PrintIdealGraphFile) {
-              //      observer = new IdealGraphPrinterObserver();
-              //  } else {
-              //      observer = new IdealGraphPrinterObserver(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort);
-              //  }
-//                context.addCompilationObserver(observer);
-                // TODO (thomaswue): Install observer.
-           // }
-            runtime = new HotSpotRuntime(config, this);
-        }
-        return runtime;
-    }
-
-    public void evictDeoptedGraphs() {
-        if (cache != null) {
-            long[] deoptedGraphs = getCompilerToVM().getDeoptedLeafGraphIds();
-            if (deoptedGraphs != null) {
-                if (deoptedGraphs.length == 0) {
-                    cache.clear();
-                } else {
-                    cache.removeGraphs(deoptedGraphs);
-                }
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerObject.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerObject.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,19 +24,12 @@
 
 import java.io.*;
 
+import com.oracle.graal.api.meta.Kind.*;
+
 
 /**
  * Parent class for all HotSpot Ri... types.
  */
-public abstract class CompilerObject implements Serializable {
-    /**
-     * 
-     */
+public abstract class CompilerObject implements Serializable, FormatWithToString {
     private static final long serialVersionUID = -4551670987101214877L;
-    protected final Compiler compiler;
-
-    protected CompilerObject(Compiler compiler) {
-        this.compiler = compiler;
-    }
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot;
 
+import java.io.*;
 import java.util.concurrent.*;
 
 import com.oracle.graal.compiler.*;
@@ -57,7 +58,8 @@
     public void run() {
         if (GraalOptions.Debug) {
             Debug.enable();
-            HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, GraalOptions.LogFile);
+            PrintStream log = HotSpotGraalRuntime.getInstance().getVMToCompiler().log();
+            HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log);
             Debug.setConfig(hotspotDebugConfig);
         }
         super.run();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,12 +25,13 @@
 import java.io.*;
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.printer.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 
 public class HotSpotDebugConfig implements DebugConfig {
@@ -42,11 +43,9 @@
     private final MethodFilter[] methodFilter;
     private final List<DebugDumpHandler> dumpHandlers = new ArrayList<>();
     private final PrintStream output;
-
-    private static final PrintStream cachedOut = System.out;
+    private final Set<Object> extraFilters = new HashSet<>();
 
-
-    public HotSpotDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter, String logFile) {
+    public HotSpotDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter, PrintStream output) {
         this.logFilter = DebugFilter.parse(logFilter);
         this.meterFilter = DebugFilter.parse(meterFilter);
         this.timerFilter = DebugFilter.parse(timerFilter);
@@ -63,7 +62,7 @@
 
         // Report the filters that have been configured so the user can verify it's what they expect
         if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) {
-            TTY.println(this.toString());
+            TTY.println(Thread.currentThread().getName() + ": " + toString());
         }
 
         if (GraalOptions.PrintIdealGraphFile) {
@@ -72,15 +71,7 @@
             dumpHandlers.add(new IdealGraphPrinterDumpHandler(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort));
         }
         dumpHandlers.add(new CFGPrinterObserver());
-        if (logFile == null || logFile.isEmpty()) {
-            output = cachedOut;
-        } else {
-            try {
-                output = new PrintStream(logFile);
-            } catch (FileNotFoundException e) {
-                throw new RuntimeException("couldn't create log file: " + logFile, e);
-            }
-        }
+        this.output = output;
     }
 
     public boolean isLogEnabled() {
@@ -112,14 +103,18 @@
     }
 
     private boolean checkMethodFilter() {
-        if (methodFilter == null) {
+        if (methodFilter == null && extraFilters.isEmpty()) {
             return true;
         } else {
             for (Object o : Debug.context()) {
-                if (o instanceof RiMethod) {
-                    for (MethodFilter filter : methodFilter) {
-                        if (filter.matches((RiMethod) o)) {
-                            return true;
+                if (extraFilters.contains(o)) {
+                    return true;
+                } else if (methodFilter != null) {
+                    if (o instanceof JavaMethod) {
+                        for (MethodFilter filter : methodFilter) {
+                            if (filter.matches((JavaMethod) o)) {
+                                return true;
+                            }
                         }
                     }
                 }
@@ -155,18 +150,28 @@
 
     @Override
     public RuntimeException interceptException(Throwable e) {
-        if (e instanceof CiBailout) {
+        if (e instanceof BailoutException) {
             return null;
         }
         Debug.setConfig(Debug.fixedConfig(true, true, false, false, dumpHandlers, output));
-        // sync "Exception occured in scope: " with mx/sanitycheck.py::Test.__init__
-        Debug.log(String.format("Exception occured in scope: %s", Debug.currentScope()));
+        Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope()));
         for (Object o : Debug.context()) {
-            Debug.log("Context obj %s", o);
-            if (o instanceof Graph && GraalOptions.DumpOnError) {
-                Graph graph = (Graph) o;
-                Debug.log("Found graph in context: ", graph);
-                Debug.dump(o, "Exception graph");
+            if (o instanceof Graph) {
+                Debug.log("Context obj %s", o);
+                if (GraalOptions.DumpOnError) {
+                    Debug.dump(o, "Exception graph");
+                } else {
+                    Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error");
+                }
+            } else if (o instanceof Node) {
+                String location = GraphUtil.approxSourceLocation((Node) o);
+                if (location != null) {
+                    Debug.log("Context obj %s (approx. location: %s)", o, location);
+                } else {
+                    Debug.log("Context obj %s", o);
+                }
+            } else {
+                Debug.log("Context obj %s", o);
             }
         }
         return null;
@@ -176,4 +181,14 @@
     public Collection<? extends DebugDumpHandler> dumpHandlers() {
         return dumpHandlers;
     }
+
+    @Override
+    public void addToContext(Object o) {
+        extraFilters.add(o);
+    }
+
+    @Override
+    public void removeFromContext(Object o) {
+        extraFilters.remove(o);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot;
+
+import java.lang.reflect.*;
+import com.oracle.graal.api.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.logging.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.xir.*;
+
+/**
+ * Singleton class holding the instance of the GraalCompiler.
+ */
+public final class HotSpotGraalRuntime implements GraalRuntime {
+
+    private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime();
+
+    public static HotSpotGraalRuntime getInstance() {
+        return instance;
+    }
+
+    private final CompilerToVM compilerToVm;
+    private final VMToCompiler vmToCompiler;
+
+    private HotSpotRuntime runtime;
+    private GraalCompiler compiler;
+    private TargetDescription target;
+    private volatile HotSpotGraphCache cache;
+
+    private final HotSpotVMConfig config;
+
+    public HotSpotVMConfig getConfig() {
+        return config;
+    }
+
+    private HotSpotGraalRuntime() {
+
+        CompilerToVM toVM = new CompilerToVMImpl();
+
+        // initialize VmToCompiler
+        VMToCompiler toCompiler = new VMToCompilerImpl(this);
+
+        // logging, etc.
+        if (CountingProxy.ENABLED) {
+            toCompiler = CountingProxy.getProxy(VMToCompiler.class, toCompiler);
+            toVM = CountingProxy.getProxy(CompilerToVM.class, toVM);
+        }
+        if (Logger.ENABLED) {
+            toCompiler = LoggingProxy.getProxy(VMToCompiler.class, toCompiler);
+            toVM = LoggingProxy.getProxy(CompilerToVM.class, toVM);
+        }
+
+        // set the final fields
+        compilerToVm = toVM;
+        vmToCompiler = toCompiler;
+        config = compilerToVm.getConfiguration();
+        config.check();
+
+        if (Boolean.valueOf(System.getProperty("graal.printconfig"))) {
+            printConfig(config);
+        }
+    }
+
+    private static void printConfig(HotSpotVMConfig config) {
+        Field[] fields = config.getClass().getDeclaredFields();
+        for (Field f : fields) {
+            f.setAccessible(true);
+            try {
+                Logger.info(String.format("%9s %-40s = %s", f.getType().getSimpleName(), f.getName(), Logger.pretty(f.get(config))));
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    public TargetDescription getTarget() {
+        if (target == null) {
+            final int wordSize = 8;
+            final int stackFrameAlignment = 16;
+            target = new TargetDescription(new AMD64(), true, stackFrameAlignment, config.vmPageSize, wordSize, true, true, true);
+        }
+
+        return target;
+    }
+
+    public GraalCompiler getCompiler() {
+        if (compiler == null) {
+            // these options are important - graal will not generate correct code without them
+            GraalOptions.StackShadowPages = config.stackShadowPages;
+
+            RiXirGenerator generator = new HotSpotXirGenerator(config, getTarget(), getRuntime().getGlobalStubRegisterConfig(), this);
+            if (Logger.ENABLED) {
+                generator = LoggingProxy.getProxy(RiXirGenerator.class, generator);
+            }
+
+            Backend backend = Backend.create(runtime, target);
+            generator.initialize(backend.newXirAssembler());
+
+            compiler = new GraalCompiler(getRuntime(), getTarget(), backend, generator);
+            if (GraalOptions.CacheGraphs) {
+                cache = new HotSpotGraphCache();
+            }
+        }
+        return compiler;
+    }
+
+    public HotSpotGraphCache getCache() {
+        return cache;
+    }
+
+    public CompilerToVM getCompilerToVM() {
+        return compilerToVm;
+    }
+
+    public VMToCompiler getVMToCompiler() {
+        return vmToCompiler;
+    }
+
+    public JavaType lookupType(String returnType, HotSpotResolvedJavaType accessingClass, boolean eagerResolve) {
+        if (returnType.length() == 1 && vmToCompiler instanceof VMToCompilerImpl) {
+            VMToCompilerImpl exitsNative = (VMToCompilerImpl) vmToCompiler;
+            Kind kind = Kind.fromPrimitiveOrVoidTypeChar(returnType.charAt(0));
+            switch(kind) {
+                case Boolean:
+                    return exitsNative.typeBoolean;
+                case Byte:
+                    return exitsNative.typeByte;
+                case Char:
+                    return exitsNative.typeChar;
+                case Double:
+                    return exitsNative.typeDouble;
+                case Float:
+                    return exitsNative.typeFloat;
+                case Illegal:
+                    break;
+                case Int:
+                    return exitsNative.typeInt;
+                case Jsr:
+                    break;
+                case Long:
+                    return exitsNative.typeLong;
+                case Object:
+                    break;
+                case Short:
+                    return exitsNative.typeShort;
+                case Void:
+                    return exitsNative.typeVoid;
+            }
+        }
+        return compilerToVm.Signature_lookupType(returnType, accessingClass, eagerResolve);
+    }
+
+    public HotSpotRuntime getRuntime() {
+        if (runtime == null) {
+            runtime = new HotSpotRuntime(config, this);
+        }
+        return runtime;
+    }
+
+    public void evictDeoptedGraphs() {
+        if (cache != null) {
+            long[] deoptedGraphs = getCompilerToVM().getDeoptedLeafGraphIds();
+            if (deoptedGraphs != null) {
+                if (deoptedGraphs.length == 0) {
+                    cache.clear();
+                } else {
+                    cache.removeGraphs(deoptedGraphs);
+                }
+            }
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "HotSpotGraalRuntime";
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T getCapability(Class<T> clazz) {
+        if (clazz == ExtendedRiRuntime.class || clazz == MetaAccessProvider.class) {
+            return (T) getRuntime();
+        }
+        if (clazz == GraalCompiler.class) {
+            return (T) getCompiler();
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotKlassOop.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,47 @@
+/*
+ * 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.hotspot;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * A mechanism for safely conveying a HotSpot klassOop value from the compiler to the C++ code.
+ * Such values should not be directly exposed to Java code as they are not real Java
+ * objects. For instance, invoking a method on them or using them in an <code>instanceof</code>
+ * expression will most likely crash the VM.
+ */
+public class HotSpotKlassOop extends CompilerObject {
+
+    private static final long serialVersionUID = -5445542223575839143L;
+
+    public final ResolvedJavaType type;
+
+    public HotSpotKlassOop(ResolvedJavaType type) {
+        this.type = type;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotKlassOop<" + type.toJava().getName() + ">";
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetMethod.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,54 +24,39 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
 import com.oracle.graal.hotspot.logging.*;
-import com.oracle.graal.hotspot.ri.*;
+import com.oracle.graal.hotspot.meta.*;
 
 /**
  * CiTargetMethod augmented with HotSpot-specific information.
  */
 public final class HotSpotTargetMethod extends CompilerObject {
 
-    /**
-     *
-     */
     private static final long serialVersionUID = 7807321392203253218L;
-    public final CiTargetMethod targetMethod;
-    public final HotSpotMethodResolved method; // used only for methods
+    public final CompilationResult targetMethod;
+    public final HotSpotResolvedJavaMethod method; // used only for methods
     public final String name; // used only for stubs
 
     public final Site[] sites;
     public final ExceptionHandler[] exceptionHandlers;
 
-    public HotSpotTargetMethod(Compiler compiler, HotSpotMethodResolved method, CiTargetMethod targetMethod) {
-        super(compiler);
+    public HotSpotTargetMethod(HotSpotResolvedJavaMethod method, CompilationResult targetMethod) {
         this.method = method;
         this.targetMethod = targetMethod;
         this.name = null;
 
         sites = getSortedSites(targetMethod);
-        if (targetMethod.exceptionHandlers == null) {
+        if (targetMethod.getExceptionHandlers() == null) {
             exceptionHandlers = null;
         } else {
-            exceptionHandlers = targetMethod.exceptionHandlers.toArray(new ExceptionHandler[targetMethod.exceptionHandlers.size()]);
+            exceptionHandlers = targetMethod.getExceptionHandlers().toArray(new ExceptionHandler[targetMethod.getExceptionHandlers().size()]);
         }
     }
 
-    private HotSpotTargetMethod(Compiler compiler, CiTargetMethod targetMethod, String name) {
-        super(compiler);
-        this.method = null;
-        this.targetMethod = targetMethod;
-        this.name = name;
-
-        sites = getSortedSites(targetMethod);
-        assert targetMethod.exceptionHandlers == null || targetMethod.exceptionHandlers.size() == 0;
-        exceptionHandlers = null;
-    }
-
-    private static Site[] getSortedSites(CiTargetMethod target) {
-        List<?>[] lists = new List<?>[] {target.safepoints, target.dataReferences, target.marks};
+    private static Site[] getSortedSites(CompilationResult target) {
+        List<?>[] lists = new List<?>[] {target.getSafepoints(), target.getDataReferences(), target.getMarks()};
         int count = 0;
         for (List<?> list : lists) {
             count += list.size();
@@ -99,9 +84,4 @@
         }
         return result;
     }
-
-    public static Object installStub(Compiler compiler, CiTargetMethod targetMethod, String name, HotSpotCodeInfo info) {
-        return compiler.getCompilerToVM().installStub(new HotSpotTargetMethod(compiler, targetMethod, name), info);
-    }
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,34 +22,34 @@
  */
 package com.oracle.graal.hotspot;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 
 /**
  * Used to communicate configuration details, runtime offsets, etc. to graal upon compileMethod.
  */
 public final class HotSpotVMConfig extends CompilerObject {
 
-    /**
-     *
-     */
     private static final long serialVersionUID = -4744897993263044184L;
 
     private HotSpotVMConfig() {
-        super(null);
     }
 
     // os information, register layout, code generation, ...
     public boolean windowsOs;
     public int codeEntryAlignment;
-    public boolean verifyPointers;
+    public boolean verifyOops;
     public boolean useFastLocking;
     public boolean useFastNewObjectArray;
     public boolean useFastNewTypeArray;
+    public boolean useTLAB;
 
     // offsets, ...
     public int vmPageSize;
     public int stackShadowPages;
     public int hubOffset;
+    public int superCheckOffsetOffset;
+    public int secondarySuperCacheOffset;
+    public int secondarySupersOffset;
     public int arrayLengthOffset;
     public int klassStateOffset;
     public int klassStateFullyInitialized;
@@ -90,7 +90,6 @@
     public long debugStub;
     public long instanceofStub;
     public long newInstanceStub;
-    public long unresolvedNewInstanceStub;
     public long newTypeArrayStub;
     public long newObjectArrayStub;
     public long newMultiArrayStub;
@@ -104,7 +103,7 @@
     public long monitorExitStub;
     public long fastMonitorEnterStub;
     public long fastMonitorExitStub;
-    public long verifyPointerStub;
+    public long verifyOopStub;
 
     public void check() {
         assert vmPageSize >= 16;
@@ -112,7 +111,7 @@
         assert stackShadowPages > 0;
     }
 
-    public int getArrayOffset(CiKind kind) {
+    public int getArrayOffset(Kind kind) {
         return arrayOffsets[kind.ordinal()];
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/MethodFilter.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/MethodFilter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,8 +25,7 @@
 import java.util.*;
 import java.util.regex.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 
 /**
  * This class implements a method filter that can filter based on class name, method name and parameters.
@@ -107,22 +106,22 @@
         }
     }
 
-    public boolean matches(RiMethod o) {
+    public boolean matches(JavaMethod o) {
         // check method name first, since CiUtil.toJavaName is expensive
         if (methodName != null && !methodName.matcher(o.name()).matches()) {
             return false;
         }
-        if (clazz != null && !clazz.matcher(CiUtil.toJavaName(o.holder())).matches()) {
+        if (clazz != null && !clazz.matcher(MetaUtil.toJavaName(o.holder())).matches()) {
             return false;
         }
         if (signature != null) {
-            RiSignature sig = o.signature();
+            Signature sig = o.signature();
             if (sig.argumentCount(false) != signature.length) {
                 return false;
             }
             for (int i = 0; i < signature.length; i++) {
-                RiType type = sig.argumentTypeAt(i, null);
-                String javaName = CiUtil.toJavaName(type);
+                JavaType type = sig.argumentTypeAt(i, null);
+                String javaName = MetaUtil.toJavaName(type);
                 if (signature[i] != null && !signature[i].matcher(javaName).matches()) {
                     return false;
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,10 +25,10 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.ri.*;
+import com.oracle.graal.hotspot.meta.*;
 
 /**
  * Calls from Java into HotSpot.
@@ -37,87 +37,87 @@
 
     // Checkstyle: stop
 
-    byte[] RiMethod_code(HotSpotMethodResolved method);
+    byte[] JavaMethod_code(HotSpotResolvedJavaMethod method);
 
-    String RiMethod_signature(HotSpotMethodResolved method);
+    String JavaMethod_signature(HotSpotResolvedJavaMethod method);
 
-    RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method);
+    ExceptionHandler[] JavaMethod_exceptionHandlers(HotSpotResolvedJavaMethod method);
 
-    boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method);
+    boolean JavaMethod_hasBalancedMonitors(HotSpotResolvedJavaMethod method);
 
-    RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method);
+    JavaMethod JavaMethod_uniqueConcreteMethod(HotSpotResolvedJavaMethod method);
 
-    int RiMethod_invocationCount(HotSpotMethodResolved method);
+    int JavaMethod_invocationCount(HotSpotResolvedJavaMethod method);
 
-    HotSpotMethodData RiMethod_methodData(HotSpotMethodResolved method);
+    HotSpotMethodData JavaMethod_methodData(HotSpotResolvedJavaMethod method);
 
-    RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve);
-
-    Object RiConstantPool_lookupConstant(HotSpotTypeResolved pool, int cpi);
+    JavaType Signature_lookupType(String returnType, HotSpotResolvedJavaType accessingClass, boolean eagerResolve);
 
-    RiMethod RiConstantPool_lookupMethod(HotSpotTypeResolved pool, int cpi, byte byteCode);
+    Object ConstantPool_lookupConstant(HotSpotResolvedJavaType pool, int cpi);
 
-    RiType RiConstantPool_lookupType(HotSpotTypeResolved pool, int cpi);
+    JavaMethod ConstantPool_lookupMethod(HotSpotResolvedJavaType pool, int cpi, byte byteCode);
 
-    RiField RiConstantPool_lookupField(HotSpotTypeResolved pool, int cpi, byte byteCode);
+    JavaType ConstantPool_lookupType(HotSpotResolvedJavaType pool, int cpi);
 
-    void RiConstantPool_loadReferencedType(HotSpotTypeResolved pool, int cpi, byte byteCode);
+    JavaField ConstantPool_lookupField(HotSpotResolvedJavaType pool, int cpi, byte byteCode);
 
-    HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode, HotSpotCodeInfo info);
+    void ConstantPool_loadReferencedType(HotSpotResolvedJavaType pool, int cpi, byte byteCode);
 
-    long installStub(HotSpotTargetMethod targetMethod, HotSpotCodeInfo info);
+    HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean makeDefault, HotSpotCodeInfo info);
 
     HotSpotVMConfig getConfiguration();
 
-    RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
+    JavaMethod JavaType_resolveMethodImpl(HotSpotResolvedJavaType klass, String name, String signature);
 
-    boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
+    boolean JavaType_isSubtypeOf(HotSpotResolvedJavaType klass, JavaType other);
 
-    RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+    JavaType JavaType_leastCommonAncestor(HotSpotResolvedJavaType thisType, HotSpotResolvedJavaType otherType);
 
-    RiType getPrimitiveArrayType(CiKind kind);
+    JavaType getPrimitiveArrayType(Kind kind);
 
-    RiType RiType_arrayOf(HotSpotTypeResolved klass);
+    JavaType JavaType_arrayOf(HotSpotResolvedJavaType klass);
 
-    RiType RiType_componentType(HotSpotTypeResolved klass);
+    JavaType JavaType_componentType(HotSpotResolvedJavaType klass);
 
-    boolean RiType_isInitialized(HotSpotTypeResolved klass);
+    boolean JavaType_isInitialized(HotSpotResolvedJavaType klass);
 
-    RiType getType(Class<?> javaClass);
+    JavaType getType(Class<?> javaClass);
 
-    RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved klass);
+    JavaType JavaType_uniqueConcreteSubtype(HotSpotResolvedJavaType klass);
 
-    RiType RiType_superType(HotSpotTypeResolved klass);
+    JavaType JavaType_superType(HotSpotResolvedJavaType klass);
 
-    int getArrayLength(CiConstant array);
+    int getArrayLength(Constant array);
 
-    boolean compareConstantObjects(CiConstant x, CiConstant y);
+    boolean compareConstantObjects(Constant x, Constant y);
 
-    RiType getRiType(CiConstant constant);
+    JavaType getJavaType(Constant constant);
 
-    RiResolvedField[] RiType_fields(HotSpotTypeResolved klass);
+    ResolvedJavaField[] JavaType_fields(HotSpotResolvedJavaType klass);
 
-    boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method);
+    boolean JavaMethod_hasCompiledCode(HotSpotResolvedJavaMethod method);
 
-    int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method);
+    int JavaMethod_getCompiledCodeSize(HotSpotResolvedJavaMethod method);
 
-    RiMethod getRiMethod(Method reflectionMethod);
+    JavaMethod getJavaMethod(Method reflectionMethod);
 
-    long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+    long getMaxCallTargetOffset(RuntimeCall rtcall);
 
     String disassembleNative(byte[] code, long address);
 
-    String disassembleJava(HotSpotMethodResolved method);
+    String disassembleJava(HotSpotResolvedJavaMethod method);
 
-    StackTraceElement RiMethod_toStackTraceElement(HotSpotMethodResolved method, int bci);
+    StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
 
     Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3);
 
     Object executeCompiledMethodVarargs(HotSpotCompiledMethod method, Object... args);
 
-    int RiMethod_vtableEntryOffset(HotSpotMethodResolved method);
+    int JavaMethod_vtableEntryOffset(HotSpotResolvedJavaMethod method);
 
     long[] getDeoptedLeafGraphIds();
 
+    String decodePC(long pc);
+
     // Checkstyle: resume
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,112 +25,108 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.ri.*;
-import com.oracle.graal.hotspot.server.*;
+import com.oracle.graal.hotspot.meta.*;
 
 /**
  * Entries into the HotSpot VM from Java code.
  */
-public class CompilerToVMImpl implements CompilerToVM, Remote {
+public class CompilerToVMImpl implements CompilerToVM {
 
     // Checkstyle: stop
 
     @Override
-    public native RiMethod getRiMethod(Method reflectionMethod);
+    public native JavaMethod getJavaMethod(Method reflectionMethod);
 
     @Override
-    public native byte[] RiMethod_code(HotSpotMethodResolved method);
-
-    @Override
-    public native String RiMethod_signature(HotSpotMethodResolved method);
+    public native byte[] JavaMethod_code(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native RiExceptionHandler[] RiMethod_exceptionHandlers(HotSpotMethodResolved method);
+    public native String JavaMethod_signature(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native boolean RiMethod_hasBalancedMonitors(HotSpotMethodResolved method);
+    public native ExceptionHandler[] JavaMethod_exceptionHandlers(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native RiMethod RiMethod_uniqueConcreteMethod(HotSpotMethodResolved method);
+    public native boolean JavaMethod_hasBalancedMonitors(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native int RiMethod_invocationCount(HotSpotMethodResolved method);
+    public native JavaMethod JavaMethod_uniqueConcreteMethod(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass, boolean eagerResolve);
+    public native int JavaMethod_invocationCount(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native Object RiConstantPool_lookupConstant(HotSpotTypeResolved pool, int cpi);
+    public native JavaType Signature_lookupType(String returnType, HotSpotResolvedJavaType accessingClass, boolean eagerResolve);
 
     @Override
-    public native RiMethod RiConstantPool_lookupMethod(HotSpotTypeResolved pool, int cpi, byte byteCode);
+    public native Object ConstantPool_lookupConstant(HotSpotResolvedJavaType pool, int cpi);
 
     @Override
-    public native RiType RiConstantPool_lookupType(HotSpotTypeResolved pool, int cpi);
+    public native JavaMethod ConstantPool_lookupMethod(HotSpotResolvedJavaType pool, int cpi, byte byteCode);
 
     @Override
-    public native void RiConstantPool_loadReferencedType(HotSpotTypeResolved pool, int cpi, byte byteCode);
+    public native JavaType ConstantPool_lookupType(HotSpotResolvedJavaType pool, int cpi);
 
     @Override
-    public native RiField RiConstantPool_lookupField(HotSpotTypeResolved pool, int cpi, byte byteCode);
+    public native void ConstantPool_loadReferencedType(HotSpotResolvedJavaType pool, int cpi, byte byteCode);
 
     @Override
-    public native HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean installCode, HotSpotCodeInfo info);
+    public native JavaField ConstantPool_lookupField(HotSpotResolvedJavaType pool, int cpi, byte byteCode);
 
     @Override
-    public native long installStub(HotSpotTargetMethod targetMethod, HotSpotCodeInfo info);
+    public native HotSpotCompiledMethod installMethod(HotSpotTargetMethod targetMethod, boolean makeDefault, HotSpotCodeInfo info);
 
     @Override
     public native HotSpotVMConfig getConfiguration();
 
     @Override
-    public native RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
+    public native JavaMethod JavaType_resolveMethodImpl(HotSpotResolvedJavaType klass, String name, String signature);
 
     @Override
-    public native boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
+    public native boolean JavaType_isSubtypeOf(HotSpotResolvedJavaType klass, JavaType other);
 
     @Override
-    public native RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+    public native JavaType JavaType_leastCommonAncestor(HotSpotResolvedJavaType thisType, HotSpotResolvedJavaType otherType);
 
     @Override
-    public native RiType getPrimitiveArrayType(CiKind kind);
+    public native JavaType getPrimitiveArrayType(Kind kind);
 
     @Override
-    public native RiType RiType_arrayOf(HotSpotTypeResolved klass);
+    public native JavaType JavaType_arrayOf(HotSpotResolvedJavaType klass);
 
     @Override
-    public native RiType RiType_componentType(HotSpotTypeResolved klass);
+    public native JavaType JavaType_componentType(HotSpotResolvedJavaType klass);
 
     @Override
-    public native RiType RiType_uniqueConcreteSubtype(HotSpotTypeResolved klass);
+    public native JavaType JavaType_uniqueConcreteSubtype(HotSpotResolvedJavaType klass);
 
     @Override
-    public native RiType RiType_superType(HotSpotTypeResolved klass);
+    public native JavaType JavaType_superType(HotSpotResolvedJavaType klass);
 
     @Override
-    public native boolean RiType_isInitialized(HotSpotTypeResolved klass);
+    public native boolean JavaType_isInitialized(HotSpotResolvedJavaType klass);
 
     @Override
-    public native HotSpotMethodData RiMethod_methodData(HotSpotMethodResolved method);
+    public native HotSpotMethodData JavaMethod_methodData(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native RiType getType(Class<?> javaClass);
+    public native JavaType getType(Class<?> javaClass);
 
     @Override
-    public int getArrayLength(CiConstant array) {
+    public int getArrayLength(Constant array) {
         return Array.getLength(array.asObject());
     }
 
     @Override
-    public boolean compareConstantObjects(CiConstant x, CiConstant y) {
+    public boolean compareConstantObjects(Constant x, Constant y) {
         return x.asObject() == y.asObject();
     }
 
     @Override
-    public RiType getRiType(CiConstant constant) {
+    public JavaType getJavaType(Constant constant) {
         Object o = constant.asObject();
         if (o == null) {
             return null;
@@ -139,25 +135,25 @@
     }
 
     @Override
-    public native RiResolvedField[] RiType_fields(HotSpotTypeResolved klass);
+    public native ResolvedJavaField[] JavaType_fields(HotSpotResolvedJavaType klass);
 
     @Override
-    public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method);
+    public native boolean JavaMethod_hasCompiledCode(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method);
+    public native int JavaMethod_getCompiledCodeSize(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+    public native long getMaxCallTargetOffset(RuntimeCall rtcall);
 
     @Override
     public native String disassembleNative(byte[] code, long address);
 
     @Override
-    public native String disassembleJava(HotSpotMethodResolved method);
+    public native String disassembleJava(HotSpotResolvedJavaMethod method);
 
     @Override
-    public native StackTraceElement RiMethod_toStackTraceElement(HotSpotMethodResolved method, int bci);
+    public native StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
 
     @Override
     public native Object executeCompiledMethod(HotSpotCompiledMethod method, Object arg1, Object arg2, Object arg3);
@@ -166,10 +162,13 @@
     public native Object executeCompiledMethodVarargs(HotSpotCompiledMethod method, Object... args);
 
     @Override
-    public native int RiMethod_vtableEntryOffset(HotSpotMethodResolved method);
+    public native int JavaMethod_vtableEntryOffset(HotSpotResolvedJavaMethod method);
 
     @Override
     public native long[] getDeoptedLeafGraphIds();
 
+    @Override
+    public native String decodePC(long pc);
+
     // Checkstyle: resume
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,16 +23,19 @@
 
 package com.oracle.graal.hotspot.bridge;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.ri.*;
+import java.io.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.hotspot.meta.*;
 
 /**
  * Calls from HotSpot into Java.
  */
 public interface VMToCompiler {
 
-    boolean compileMethod(HotSpotMethodResolved method, int entryBCI, boolean blocking, int priority) throws Throwable;
+    boolean compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, boolean blocking, int priority) throws Throwable;
 
     void shutdownCompiler() throws Throwable;
 
@@ -40,23 +43,25 @@
 
     void bootstrap() throws Throwable;
 
-    RiMethod createRiMethodUnresolved(String name, String signature, RiType holder);
+    PrintStream log();
 
-    RiSignature createRiSignature(String signature);
+    JavaMethod createJavaMethod(String name, String signature, JavaType holder);
 
-    RiField createRiField(RiType holder, String name, RiType type, int offset, int flags);
+    Signature createSignature(String signature);
 
-    RiType createRiType(HotSpotConstantPool pool, String name);
+    JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags);
 
-    RiType createRiTypePrimitive(int basicType);
+    JavaType createPrimitiveJavaType(int basicType);
 
-    RiType createRiTypeUnresolved(String name);
+    JavaType createJavaType(String name);
 
-    CiConstant createCiConstant(CiKind kind, long value);
+    Constant createConstant(Kind kind, long value);
+
+    Constant createConstantFloat(float value);
 
-    CiConstant createCiConstantFloat(float value);
+    Constant createConstantDouble(double value);
 
-    CiConstant createCiConstantDouble(double value);
+    Constant createConstantObject(Object object);
 
-    CiConstant createCiConstantObject(Object object);
+    PhasePlan createPhasePlan(OptimisticOptimizations optimisticOpts);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,33 +23,32 @@
 
 package com.oracle.graal.hotspot.bridge;
 
+import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-import com.oracle.graal.hotspot.ri.*;
-import com.oracle.graal.hotspot.server.*;
+import com.oracle.graal.hotspot.counters.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.snippets.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.snippets.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 
 /**
  * Exits from the HotSpot VM into Java code.
  */
-public class VMToCompilerImpl implements VMToCompiler, Remote {
+public class VMToCompilerImpl implements VMToCompiler {
 
-    private final Compiler compiler;
+    private final HotSpotGraalRuntime compiler;
     private IntrinsifyArrayCopyPhase intrinsifyArrayCopy;
 
     public final HotSpotTypePrimitive typeBoolean;
@@ -66,23 +65,33 @@
     private ThreadPoolExecutor slowCompileQueue;
     private AtomicInteger compileTaskIds = new AtomicInteger();
 
-    public VMToCompilerImpl(Compiler compiler) {
+    private PrintStream log = System.out;
+
+    public VMToCompilerImpl(HotSpotGraalRuntime compiler) {
         this.compiler = compiler;
 
-        typeBoolean = new HotSpotTypePrimitive(compiler, CiKind.Boolean);
-        typeChar = new HotSpotTypePrimitive(compiler, CiKind.Char);
-        typeFloat = new HotSpotTypePrimitive(compiler, CiKind.Float);
-        typeDouble = new HotSpotTypePrimitive(compiler, CiKind.Double);
-        typeByte = new HotSpotTypePrimitive(compiler, CiKind.Byte);
-        typeShort = new HotSpotTypePrimitive(compiler, CiKind.Short);
-        typeInt = new HotSpotTypePrimitive(compiler, CiKind.Int);
-        typeLong = new HotSpotTypePrimitive(compiler, CiKind.Long);
-        typeVoid = new HotSpotTypePrimitive(compiler, CiKind.Void);
+        typeBoolean = new HotSpotTypePrimitive(Kind.Boolean);
+        typeChar = new HotSpotTypePrimitive(Kind.Char);
+        typeFloat = new HotSpotTypePrimitive(Kind.Float);
+        typeDouble = new HotSpotTypePrimitive(Kind.Double);
+        typeByte = new HotSpotTypePrimitive(Kind.Byte);
+        typeShort = new HotSpotTypePrimitive(Kind.Short);
+        typeInt = new HotSpotTypePrimitive(Kind.Int);
+        typeLong = new HotSpotTypePrimitive(Kind.Long);
+        typeVoid = new HotSpotTypePrimitive(Kind.Void);
     }
 
     public void startCompiler() throws Throwable {
-        // Make sure TTY is initialized here such that the correct System.out is used for TTY.
-        TTY.initialize();
+        if (GraalOptions.LogFile != null) {
+            try {
+                final boolean enableAutoflush = true;
+                log = new PrintStream(new FileOutputStream(GraalOptions.LogFile), enableAutoflush);
+            } catch (FileNotFoundException e) {
+                throw new RuntimeException("couldn't open log file: " + GraalOptions.LogFile, e);
+            }
+        }
+
+        TTY.initialize(log);
 
         if (GraalOptions.Log == null && GraalOptions.Meter == null && GraalOptions.Time == null && GraalOptions.Dump == null) {
             if (GraalOptions.MethodFilter != null) {
@@ -92,7 +101,7 @@
 
         if (GraalOptions.Debug) {
             Debug.enable();
-            HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, GraalOptions.LogFile);
+            HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log);
             Debug.setConfig(hotspotDebugConfig);
         }
         // Install intrinsics.
@@ -103,10 +112,9 @@
                 @Override
                 public void run() {
                     VMToCompilerImpl.this.intrinsifyArrayCopy = new IntrinsifyArrayCopyPhase(runtime);
-                    GraalIntrinsics.installIntrinsics(runtime, runtime.getCompiler().getTarget());
-                    Snippets.install(runtime, runtime.getCompiler().getTarget(), new SystemSnippets());
-                    Snippets.install(runtime, runtime.getCompiler().getTarget(), new UnsafeSnippets());
-                    Snippets.install(runtime, runtime.getCompiler().getTarget(), new ArrayCopySnippets());
+                    SnippetInstaller installer = new SnippetInstaller(runtime, runtime.getCompiler().getTarget());
+                    GraalIntrinsics.installIntrinsics(installer);
+                    runtime.installSnippets(installer);
                 }
             });
 
@@ -203,47 +211,59 @@
                 }
             }
         } while ((System.currentTimeMillis() - startTime) <= GraalOptions.TimedBootstrap);
-        CiCompilationStatistics.clear("bootstrap");
+        CompilationStatistics.clear("bootstrap");
 
         TTY.println(" in %d ms", System.currentTimeMillis() - startTime);
         if (compiler.getCache() != null) {
             compiler.getCache().clear();
-            compiler.getCache().enable();
         }
         System.gc();
-        CiCompilationStatistics.clear("bootstrap2");
+        CompilationStatistics.clear("bootstrap2");
+        MethodEntryCounters.printCounters(compiler);
     }
 
     private void enqueue(Method m) throws Throwable {
-        RiMethod riMethod = compiler.getRuntime().getRiMethod(m);
-        assert !Modifier.isAbstract(((HotSpotMethodResolved) riMethod).accessFlags()) && !Modifier.isNative(((HotSpotMethodResolved) riMethod).accessFlags()) : riMethod;
-        compileMethod((HotSpotMethodResolved) riMethod, 0, false, 10);
+        JavaMethod riMethod = compiler.getRuntime().getResolvedJavaMethod(m);
+        assert !Modifier.isAbstract(((HotSpotResolvedJavaMethod) riMethod).accessFlags()) && !Modifier.isNative(((HotSpotResolvedJavaMethod) riMethod).accessFlags()) : riMethod;
+        compileMethod((HotSpotResolvedJavaMethod) riMethod, 0, false, 10);
+    }
+
+    private static void shutdownCompileQueue(ThreadPoolExecutor queue) throws InterruptedException {
+        if (queue != null) {
+            queue.shutdown();
+            if (Debug.isEnabled() && GraalOptions.Dump != null) {
+                // Wait 2 seconds to flush out all graph dumps that may be of interest
+                queue.awaitTermination(2, TimeUnit.SECONDS);
+            }
+        }
     }
 
     public void shutdownCompiler() throws Throwable {
         try {
             assert !CompilationTask.withinEnqueue.get();
             CompilationTask.withinEnqueue.set(Boolean.TRUE);
-            compileQueue.shutdown();
-            if (slowCompileQueue != null) {
-                slowCompileQueue.shutdown();
-            }
+            shutdownCompileQueue(compileQueue);
+            shutdownCompileQueue(slowCompileQueue);
         } finally {
             CompilationTask.withinEnqueue.set(Boolean.FALSE);
         }
 
+
         if (Debug.isEnabled()) {
             List<DebugValueMap> topLevelMaps = DebugValueMap.getTopLevelMaps();
             List<DebugValue> debugValues = KeyRegistry.getDebugValues();
             if (debugValues.size() > 0) {
+                ArrayList<DebugValue> sortedValues = new ArrayList<>(debugValues);
+                Collections.sort(sortedValues, DebugValue.ORDER_BY_NAME);
+
                 if (GraalOptions.SummarizeDebugValues) {
-                    printSummary(topLevelMaps, debugValues);
+                    printSummary(topLevelMaps, sortedValues);
                 } else if (GraalOptions.PerThreadDebugValues) {
                     for (DebugValueMap map : topLevelMaps) {
                         TTY.println("Showing the results for thread: " + map.getName());
                         map.group();
                         map.normalize();
-                        printMap(map, debugValues, 0);
+                        printMap(map, sortedValues, 0);
                     }
                 } else {
                     DebugValueMap globalMap = new DebugValueMap("Global");
@@ -260,11 +280,14 @@
                         globalMap.group();
                     }
                     globalMap.normalize();
-                    printMap(globalMap, debugValues, 0);
+                    printMap(globalMap, sortedValues, 0);
                 }
             }
         }
-        CiCompilationStatistics.clear("final");
+        CompilationStatistics.clear("final");
+        MethodEntryCounters.printCounters(compiler);
+        HotSpotXirGenerator.printCounters(TTY.out().out());
+        CheckCastSnippets.printCounters(TTY.out().out());
     }
 
     private void flattenChildren(DebugValueMap map, DebugValueMap globalMap) {
@@ -305,6 +328,7 @@
 
         printIndent(level);
         TTY.println("%s", map.getName());
+
         for (DebugValue value : debugValues) {
             long l = map.getCurrentValue(value.getIndex());
             if (l != 0) {
@@ -326,7 +350,7 @@
     }
 
     @Override
-    public boolean compileMethod(final HotSpotMethodResolved method, final int entryBCI, boolean blocking, int priority) throws Throwable {
+    public boolean compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, boolean blocking, int priority) throws Throwable {
         if (CompilationTask.withinEnqueue.get()) {
             // This is required to avoid deadlocking a compiler thread. The issue is that a
             // java.util.concurrent.BlockingQueue is used to implement the compilation worker
@@ -350,7 +374,7 @@
 
             final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method);
             int id = compileTaskIds.incrementAndGet();
-            CompilationTask task = CompilationTask.create(compiler, createHotSpotSpecificPhasePlan(optimisticOpts), optimisticOpts, method, id, priority);
+            CompilationTask task = CompilationTask.create(compiler, createPhasePlan(optimisticOpts), optimisticOpts, method, id, priority);
             if (blocking) {
                 task.runCompilation();
             } else {
@@ -373,31 +397,26 @@
     }
 
     @Override
-    public RiMethod createRiMethodUnresolved(String name, String signature, RiType holder) {
-        return new HotSpotMethodUnresolved(compiler, name, signature, holder);
+    public JavaMethod createJavaMethod(String name, String signature, JavaType holder) {
+        return new HotSpotMethodUnresolved(name, signature, holder);
     }
 
     @Override
-    public RiSignature createRiSignature(String signature) {
-        return new HotSpotSignature(compiler, signature);
+    public Signature createSignature(String signature) {
+        return new HotSpotSignature(signature);
     }
 
     @Override
-    public RiField createRiField(RiType holder, String name, RiType type, int offset, int flags) {
+    public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags) {
         if (offset != -1) {
-            HotSpotTypeResolved resolved = (HotSpotTypeResolved) holder;
+            HotSpotResolvedJavaType resolved = (HotSpotResolvedJavaType) holder;
             return resolved.createRiField(name, type, offset, flags);
         }
         return new BaseUnresolvedField(holder, name, type);
     }
 
     @Override
-    public RiType createRiType(HotSpotConstantPool pool, String name) {
-        throw new RuntimeException("not implemented");
-    }
-
-    @Override
-    public RiType createRiTypePrimitive(int basicType) {
+    public ResolvedJavaType createPrimitiveJavaType(int basicType) {
         switch (basicType) {
             case 4:
                 return typeBoolean;
@@ -423,46 +442,46 @@
     }
 
     @Override
-    public RiType createRiTypeUnresolved(String name) {
-        return new HotSpotTypeUnresolved(compiler, name);
+    public JavaType createJavaType(String name) {
+        return new HotSpotTypeUnresolved(name);
     }
 
     @Override
-    public CiConstant createCiConstant(CiKind kind, long value) {
-        if (kind == CiKind.Long) {
-            return CiConstant.forLong(value);
-        } else if (kind == CiKind.Int) {
-            return CiConstant.forInt((int) value);
-        } else if (kind == CiKind.Short) {
-            return CiConstant.forShort((short) value);
-        } else if (kind == CiKind.Char) {
-            return CiConstant.forChar((char) value);
-        } else if (kind == CiKind.Byte) {
-            return CiConstant.forByte((byte) value);
-        } else if (kind == CiKind.Boolean) {
-            return (value == 0) ? CiConstant.FALSE : CiConstant.TRUE;
+    public Constant createConstant(Kind kind, long value) {
+        if (kind == Kind.Long) {
+            return Constant.forLong(value);
+        } else if (kind == Kind.Int) {
+            return Constant.forInt((int) value);
+        } else if (kind == Kind.Short) {
+            return Constant.forShort((short) value);
+        } else if (kind == Kind.Char) {
+            return Constant.forChar((char) value);
+        } else if (kind == Kind.Byte) {
+            return Constant.forByte((byte) value);
+        } else if (kind == Kind.Boolean) {
+            return (value == 0) ? Constant.FALSE : Constant.TRUE;
         } else {
             throw new IllegalArgumentException();
         }
     }
 
     @Override
-    public CiConstant createCiConstantFloat(float value) {
-        return CiConstant.forFloat(value);
+    public Constant createConstantFloat(float value) {
+        return Constant.forFloat(value);
     }
 
     @Override
-    public CiConstant createCiConstantDouble(double value) {
-        return CiConstant.forDouble(value);
+    public Constant createConstantDouble(double value) {
+        return Constant.forDouble(value);
     }
 
     @Override
-    public CiConstant createCiConstantObject(Object object) {
-        return CiConstant.forObject(object);
+    public Constant createConstantObject(Object object) {
+        return Constant.forObject(object);
     }
 
 
-    private PhasePlan createHotSpotSpecificPhasePlan(OptimisticOptimizations optimisticOpts) {
+    public PhasePlan createPhasePlan(OptimisticOptimizations optimisticOpts) {
         PhasePlan phasePlan = new PhasePlan();
         GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
@@ -471,4 +490,9 @@
         }
         return phasePlan;
     }
+
+    @Override
+    public PrintStream log() {
+        return log;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/counters/MethodEntryCounters.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2012, 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.hotspot.counters;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.util.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
+import com.oracle.max.criutils.*;
+
+
+public class MethodEntryCounters {
+    protected static final class Counter implements Comparable<Counter> {
+        protected static ArrayList<Counter> counters = new ArrayList<>();
+
+        protected final String method;
+        protected final long[] counts = new long[GraalOptions.MethodEntryCountersCallers * 2 + 2];
+
+        protected long sortCount;
+
+        protected Counter(ResolvedJavaMethod method) {
+            this.method = CodeUtil.format("%H.%n", method);
+            counters.add(this);
+        }
+
+        @Override
+        public int compareTo(Counter o) {
+            return (int) (o.sortCount - sortCount);
+        }
+    }
+
+
+    protected static class AMD64MethodEntryOp extends AMD64LIRInstruction {
+        protected static int codeSize;
+
+        protected final Counter counter;
+
+        protected AMD64MethodEntryOp(Counter counter, Value counterArr, Value callerPc) {
+            super("ENTRY_COUNTER", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, new Value[] {counterArr, callerPc});
+            this.counter = counter;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            int start = masm.codeBuffer.position();
+
+            Value counterArr = temp(0);
+            Value callerPc = temp(1);
+
+            int off = Unsafe.getUnsafe().arrayBaseOffset(long[].class);
+            int scale = Unsafe.getUnsafe().arrayIndexScale(long[].class);
+
+            AMD64Move.move(tasm, masm, counterArr, Constant.forObject(counter.counts));
+            AMD64Move.load(tasm, masm, callerPc, new Address(Kind.Long, AMD64.rbp.asValue(Kind.Long), 8), null);
+
+            Label done = new Label();
+            for (int i = 0; i < counter.counts.length - 2; i += 2) {
+                Address counterPcAddr = new Address(Kind.Long, counterArr, i * scale + off);
+                Address counterValueAddr = new Address(Kind.Long, counterArr, (i + 1) * scale + off);
+
+                Label skipClaim = new Label();
+                masm.cmpq(counterPcAddr, 0);
+                masm.jccb(ConditionFlag.notEqual, skipClaim);
+                AMD64Move.store(tasm, masm, counterPcAddr, callerPc, null);
+                masm.bind(skipClaim);
+
+                Label skipInc = new Label();
+                masm.cmpq(counterPcAddr, asRegister(callerPc));
+                masm.jccb(ConditionFlag.notEqual, skipInc);
+                masm.addq(counterValueAddr, 1);
+                masm.jmp(done);
+                masm.bind(skipInc);
+            }
+
+            Address counterValueAddr = new Address(Kind.Long, counterArr, (counter.counts.length - 1) * scale + off);
+            masm.addq(counterValueAddr, 1);
+            masm.bind(done);
+
+            int size = masm.codeBuffer.position() - start;
+            assert codeSize == 0 || codeSize == size;
+            codeSize = size;
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Temp && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Temp && index == 1) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+
+    public static void emitCounter(LIRGenerator gen, ResolvedJavaMethod method) {
+        if (!GraalOptions.MethodEntryCounters) {
+            return;
+        }
+        gen.append(new AMD64MethodEntryOp(new Counter(method), gen.newVariable(Kind.Long), gen.newVariable(Kind.Long)));
+    }
+
+    public static int getCodeSize() {
+        if (!GraalOptions.MethodEntryCounters) {
+            return 0;
+        }
+        return AMD64MethodEntryOp.codeSize;
+    }
+
+
+    public static void printCounters(HotSpotGraalRuntime compiler) {
+        if (!GraalOptions.MethodEntryCounters) {
+            return;
+        }
+        ArrayList<Counter> copy = new ArrayList<>(Counter.counters);
+        long total = 0;
+        for (Counter counter : copy) {
+            long sum = 0;
+            for (int i = 0; i < counter.counts.length; i += 2) {
+                sum += counter.counts[i + 1];
+            }
+            counter.sortCount = sum;
+            total += sum;
+        }
+        Collections.sort(copy);
+
+        TTY.println();
+        TTY.println("** Compiled method invocation counters **");
+        for (Counter counter : copy) {
+            TTY.println("%16d %5.2f%%  %s", counter.sortCount, (double) counter.sortCount / total * 100d, counter.method);
+
+            if (counter.counts.length > 2) {
+                for (int i = 0; i < counter.counts.length; i += 2) {
+                    if (counter.counts[i] != 0 || counter.counts[i + 1] != 0) {
+                        TTY.print("              %16d  %5.2f%%", counter.counts[i + 1], (double) counter.counts[i + 1] / counter.sortCount * 100d);
+                        if (counter.counts[i] == 0) {
+                            TTY.println("  [other callers]");
+                        } else {
+                            TTY.println("  %x  %s", counter.counts[i], compiler.getCompilerToVM().decodePC(counter.counts[i]));
+                        }
+                        counter.counts[i] = 0;
+                        counter.counts[i + 1] = 0;
+                    }
+                }
+            }
+        }
+        TTY.println("** Compiled method invocation counters **");
+        TTY.println();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/CountingProxy.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/CountingProxy.java	Wed Jun 27 17:35:32 2012 +0200
@@ -27,8 +27,6 @@
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
-import com.oracle.graal.hotspot.server.*;
-
 /**
  * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return
  * values.
@@ -73,7 +71,7 @@
     }
 
     public static <T> T getProxy(Class<T> interf, T delegate) {
-        Class<?>[] interfaces = ReplacingStreams.getAllInterfaces(delegate.getClass());
+        Class<?>[] interfaces = ProxyUtil.getAllInterfaces(delegate.getClass());
         Object obj = Proxy.newProxyInstance(interf.getClassLoader(), interfaces, new CountingProxy<>(delegate));
         return interf.cast(obj);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/LoggingProxy.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/LoggingProxy.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,6 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.graal.hotspot.server.*;
-
 /**
  * A java.lang.reflect proxy that hierarchically logs all method invocations along with their parameters and return values.
  */
@@ -70,7 +68,7 @@
      * The object returned by this method will implement all interfaces that are implemented by delegate.
      */
     public static <T> T getProxy(Class<T> interf, T delegate) {
-        Class<?>[] interfaces = ReplacingStreams.getAllInterfaces(delegate.getClass());
+        Class<?>[] interfaces = ProxyUtil.getAllInterfaces(delegate.getClass());
         Object obj = Proxy.newProxyInstance(interf.getClassLoader(), interfaces, new LoggingProxy<>(delegate));
         return interf.cast(obj);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/logging/ProxyUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.logging;
+
+import java.util.*;
+
+
+public final class ProxyUtil {
+    public static Class<?>[] getAllInterfaces(Class<?> clazz) {
+        HashSet<Class< ? >> interfaces = new HashSet<>();
+        getAllInterfaces(clazz, interfaces);
+        return interfaces.toArray(new Class<?>[interfaces.size()]);
+    }
+
+    private static void getAllInterfaces(Class<?> clazz, HashSet<Class<?>> interfaces) {
+        for (Class< ? > iface : clazz.getInterfaces()) {
+            if (!interfaces.contains(iface)) {
+                interfaces.add(iface);
+                getAllInterfaces(iface, interfaces);
+            }
+        }
+        if (clazz.getSuperclass() != null) {
+            getAllInterfaces(clazz.getSuperclass(), interfaces);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of {@link CodeInfo} for HotSpot.
+ */
+public class HotSpotCodeInfo extends CompilerObject implements CodeInfo {
+
+    private static final long serialVersionUID = -6766490427732498354L;
+
+    private long start;
+    private byte[] code;
+    public final CompilationResult targetMethod;
+    private HotSpotResolvedJavaMethod method;
+
+    public HotSpotCodeInfo(CompilationResult targetMethod, HotSpotResolvedJavaMethod method) {
+        assert targetMethod != null;
+        this.method = method;
+        this.targetMethod = targetMethod;
+    }
+
+    @Override
+    public long start() {
+        return start;
+    }
+
+    @Override
+    public byte[] code() {
+        return code;
+    }
+
+    @Override
+    public String toString() {
+        int size = code == null ? 0 : code.length;
+        return "installed code @[" + Long.toHexString(start) + "-" + Long.toHexString(start + size) + "]";
+
+    }
+
+    @Override
+    public ResolvedJavaMethod method() {
+        return method;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCompiledMethod.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of RiCompiledMethod for HotSpot.
+ * Stores a reference to the nmethod which contains the compiled code.
+ * The nmethod also stores a weak reference to the HotSpotCompiledMethod
+ * instance which is necessary to keep the nmethod from being unloaded.
+ */
+public class HotSpotCompiledMethod extends CompilerObject implements InstalledCode {
+
+    private static final long serialVersionUID = 156632908220561612L;
+
+    private final ResolvedJavaMethod method;
+    private long nmethod;
+
+    public HotSpotCompiledMethod(ResolvedJavaMethod method) {
+        this.method = method;
+    }
+
+    @Override
+    public ResolvedJavaMethod method() {
+        return method;
+    }
+
+    @Override
+    public boolean isValid() {
+        return nmethod != 0;
+    }
+
+    @Override
+    public String toString() {
+        return "compiled method " + method + " @" + nmethod;
+    }
+
+    @Override
+    public Object execute(Object arg1, Object arg2, Object arg3) {
+        assert method.signature().argumentCount(!Modifier.isStatic(method.accessFlags())) == 3;
+        assert method.signature().argumentKindAt(0) == Kind.Object;
+        assert method.signature().argumentKindAt(1) == Kind.Object;
+        assert !Modifier.isStatic(method.accessFlags()) || method.signature().argumentKindAt(2) == Kind.Object;
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(this, arg1, arg2, arg3);
+    }
+
+    private boolean checkArgs(Object... args) {
+        Kind[] sig = CodeUtil.signatureToKinds(method);
+        assert args.length == sig.length : CodeUtil.format("%H.%n(%p): expected ", method) + sig.length + " args, got " + args.length;
+        for (int i = 0; i < sig.length; i++) {
+            Object arg = args[i];
+            if (arg == null) {
+                assert sig[i].isObject() : CodeUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i];
+            } else if (!sig[i].isObject()) {
+                assert sig[i].toBoxedJavaClass() == arg.getClass() : CodeUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Object executeVarargs(Object... args) {
+        assert checkArgs(args);
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethodVarargs(this, args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of RiConstantPool for HotSpot.
+ */
+public class HotSpotConstantPool extends CompilerObject implements ConstantPool {
+
+    private static final long serialVersionUID = -5443206401485234850L;
+
+    private final HotSpotResolvedJavaType type;
+
+    public HotSpotConstantPool(HotSpotResolvedJavaType type) {
+        this.type = type;
+    }
+
+    @Override
+    public Object lookupConstant(int cpi) {
+        Object constant = HotSpotGraalRuntime.getInstance().getCompilerToVM().ConstantPool_lookupConstant(type, cpi);
+        return constant;
+    }
+
+    @Override
+    public Signature lookupSignature(int cpi) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public JavaMethod lookupMethod(int cpi, int byteCode) {
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().ConstantPool_lookupMethod(type, cpi, (byte) byteCode);
+    }
+
+    @Override
+    public JavaType lookupType(int cpi, int opcode) {
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().ConstantPool_lookupType(type, cpi);
+    }
+
+    @Override
+    public JavaField lookupField(int cpi, int opcode) {
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().ConstantPool_lookupField(type, cpi, (byte) opcode);
+    }
+
+    @Override
+    public void loadReferencedType(int cpi, int bytecode) {
+        HotSpotGraalRuntime.getInstance().getCompilerToVM().ConstantPool_loadReferencedType(type, cpi, (byte) bytecode);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,171 @@
+/*
+ * 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.hotspot.meta;
+
+import java.io.*;
+import java.lang.ref.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * This class implements the graph caching system for the HotSpot platform.
+ *
+ * This implementation does not use a map to store the actual cached graphs. The problem is that such maps keep the
+ * graph, and therefore the RiResolvedMethod referenced from the graph, alive. For some applications and benchmarks this
+ * is a problem, e.g., the DaCapoScala "scalatest" benchmark will quickly run out of perm gen because of this.
+ *
+ * This cannot be solved with a WeakHashMap<RiResolvedMethod, Graph>, since the values within the map will keep the keys
+ * alive. In order for this to work we would require a weak map in which the "strongness" of the value references
+ * depends upon the reachability of the keys.
+ *
+ * Therefore the graph cache is implemented in such a way that it stores its cache entries within the RiResolvedMethod.
+ * It uses the {@link ResolvedJavaMethod#compilerStorage()} map with the HotSpotGraphCache instance as key.
+ * The cached graph will be kept alive as long as the RiResolvedMethod is alive, but does not prevent the method, and
+ * therefore the class, from being unloaded.
+ *
+ * The {@link #cachedGraphIds} map is used to find the graphs that should be removed because of deoptimization, and to
+ * enforce the graph cache size restriction.
+ */
+public class HotSpotGraphCache implements RiGraphCache {
+
+    private static final PrintStream out = System.out;
+
+    private volatile long hitCounter;
+    private volatile long missCounter;
+    private volatile long removeHitCounter;
+    private volatile long removeCounter;
+    private volatile long putCounter;
+
+    /**
+     * An ordered hash map for looking up the methods corresponding to a specific graph id. It enforces the maximum
+     * graph cache size by removing the oldest (in insertion-order) element if the cache gets too big.
+     */
+    private final class LRUCache extends LinkedHashMap<Long, WeakReference<ResolvedJavaMethod>> {
+
+        private static final long serialVersionUID = -3973307040793397840L;
+
+        public LRUCache() {
+            super(GraalOptions.GraphCacheSize * 2, 0.75f, false);
+        }
+
+        @Override
+        protected boolean removeEldestEntry(Entry<Long, WeakReference<ResolvedJavaMethod>> eldest) {
+            if (size() > GraalOptions.GraphCacheSize) {
+                ResolvedJavaMethod method = eldest.getValue().get();
+                if (method != null) {
+                    StructuredGraph cachedGraph = (StructuredGraph) method.compilerStorage().get(HotSpotGraphCache.this);
+                    if (cachedGraph != null && cachedGraph.graphId() == eldest.getKey()) {
+                        method.compilerStorage().remove(HotSpotGraphCache.this);
+                    }
+                }
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    private final Map<Long, WeakReference<ResolvedJavaMethod>> cachedGraphIds = Collections.synchronizedMap(new LRUCache());
+
+    public HotSpotGraphCache() {
+        if (GraalOptions.PrintGraphCache) {
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+
+                @Override
+                public void run() {
+                    out.println("put: " + putCounter);
+                    out.println("get hit: " + hitCounter);
+                    out.println("get miss: " + missCounter);
+                    out.println("remove hit: " + removeHitCounter);
+                    out.println("remove miss: " + (removeCounter - removeHitCounter));
+                }
+            });
+        }
+    }
+
+    @Override
+    public StructuredGraph get(ResolvedJavaMethod method) {
+        StructuredGraph result = (StructuredGraph) method.compilerStorage().get(this);
+
+        if (GraalOptions.PrintGraphCache) {
+            if (result == null) {
+                missCounter++;
+            } else {
+                hitCounter++;
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void put(StructuredGraph graph) {
+        assert graph.method() != null;
+        cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method()));
+        graph.method().compilerStorage().put(this, graph);
+
+        if (GraalOptions.PrintGraphCache) {
+            putCounter++;
+        }
+    }
+
+    public void clear() {
+        synchronized (cachedGraphIds) {
+            for (WeakReference<ResolvedJavaMethod> ref : cachedGraphIds.values()) {
+                ResolvedJavaMethod method = ref.get();
+                if (method != null) {
+                    method.compilerStorage().remove(this);
+                }
+            }
+            cachedGraphIds.clear();
+            hitCounter = 0;
+            missCounter = 0;
+            removeHitCounter = 0;
+            removeCounter = 0;
+            putCounter = 0;
+        }
+    }
+
+    public void removeGraphs(long[] deoptedGraphs) {
+        for (long graphId : deoptedGraphs) {
+            WeakReference<ResolvedJavaMethod> ref = cachedGraphIds.get(graphId);
+            ResolvedJavaMethod method = ref == null ? null : ref.get();
+            if (method != null) {
+                StructuredGraph cachedGraph = (StructuredGraph) method.compilerStorage().get(this);
+                if (cachedGraph != null && cachedGraph.graphId() == graphId) {
+                    method.compilerStorage().remove(this);
+                    if (GraalOptions.PrintGraphCache) {
+                        removeHitCounter++;
+                    }
+                }
+            }
+            if (GraalOptions.PrintGraphCache) {
+                removeCounter++;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Common interface for all HotSpot RiType-implementations.
+ */
+public abstract class HotSpotJavaType extends CompilerObject implements JavaType {
+    private static final long serialVersionUID = -4252886265301910771L;
+    protected String name;
+
+    @Override
+    public final String name() {
+        return name;
+    }
+
+    /**
+     * Gets the object representing the C++ klassOop for this type.
+     * Such a value cannot be safely exposed to Java code.
+     */
+    public abstract HotSpotKlassOop klassOop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+
+public abstract class HotSpotMethod extends CompilerObject implements JavaMethod {
+
+    private static final long serialVersionUID = 7167491397941960839L;
+    protected String name;
+
+    @Override
+    public final String name() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,575 @@
+/*
+ * 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.hotspot.meta;
+
+import java.util.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaTypeProfile.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.hotspot.*;
+
+
+public final class HotSpotMethodData extends CompilerObject {
+
+    private static final long serialVersionUID = -8873133496591225071L;
+
+    static {
+        config = HotSpotGraalRuntime.getInstance().getConfig();
+    }
+
+    // TODO (chaeubl) use same logic as in NodeClass?
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(ExceptionSeen.FALSE);
+    private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(ExceptionSeen.NOT_SUPPORTED);
+    private static final HotSpotVMConfig config;
+    // sorted by tag
+    private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {
+        null, new BitData(), new CounterData(), new JumpData(),
+        new TypeCheckData(), new VirtualCallData(), new RetData(),
+        new BranchData(), new MultiBranchData(), new ArgInfoData()
+    };
+
+    private Object hotspotMirror;
+    private int normalDataSize;
+    private int extraDataSize;
+
+    private HotSpotMethodData() {
+        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
+    }
+
+    public boolean hasNormalData() {
+        return normalDataSize > 0;
+    }
+
+    public boolean hasExtraData() {
+        return extraDataSize > 0;
+    }
+
+    public int getExtraDataBeginOffset() {
+        return normalDataSize;
+    }
+
+    public boolean isWithin(int position) {
+        return position >= 0 && position < normalDataSize + extraDataSize;
+    }
+
+    public int getDeoptimizationCount(DeoptimizationReason reason) {
+        int reasonIndex = HotSpotGraalRuntime.getInstance().getRuntime().convertDeoptReason(reason);
+        return unsafe.getByte(hotspotMirror, (long) config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF;
+    }
+
+    public HotSpotMethodDataAccessor getNormalData(int position) {
+        if (position >= normalDataSize) {
+            return null;
+        }
+
+        HotSpotMethodDataAccessor result = getData(position);
+        assert result != null : "NO_DATA tag is not allowed";
+        return result;
+    }
+
+    public HotSpotMethodDataAccessor getExtraData(int position) {
+        if (position >= normalDataSize + extraDataSize) {
+            return null;
+        }
+        return getData(position);
+    }
+
+    public static HotSpotMethodDataAccessor getNoDataAccessor(boolean exceptionPossiblyNotRecorded) {
+        if (exceptionPossiblyNotRecorded) {
+            return NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR;
+        } else {
+            return NO_DATA_NO_EXCEPTION_ACCESSOR;
+        }
+    }
+
+    private HotSpotMethodDataAccessor getData(int position) {
+        assert position >= 0 : "out of bounds";
+        int tag = AbstractMethodData.readTag(this, position);
+        assert tag >= 0 && tag < PROFILE_DATA_ACCESSORS.length : "illegal tag";
+        return PROFILE_DATA_ACCESSORS[tag];
+    }
+
+    private int readUnsignedByte(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getByte(hotspotMirror, fullOffsetInBytes) & 0xFF;
+    }
+
+    private int readUnsignedShort(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getShort(hotspotMirror, fullOffsetInBytes) & 0xFFFF;
+    }
+
+    private long readUnsignedInt(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getInt(hotspotMirror, fullOffsetInBytes) & 0xFFFFFFFFL;
+    }
+
+    private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) {
+        long value = readUnsignedInt(position, offsetInBytes);
+        return truncateLongToInt(value);
+    }
+
+    private int readInt(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getInt(hotspotMirror, fullOffsetInBytes);
+    }
+
+    private Object readObject(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return unsafe.getObject(hotspotMirror, fullOffsetInBytes);
+    }
+
+    private static int truncateLongToInt(long value) {
+        return value > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) value;
+    }
+
+    private static int computeFullOffset(int position, int offsetInBytes) {
+        return config.methodDataOopDataOffset + position + offsetInBytes;
+    }
+
+    private static int cellIndexToOffset(int cells) {
+        return config.dataLayoutHeaderSize + cellsToBytes(cells);
+    }
+
+    private static int cellsToBytes(int cells) {
+        return cells * config.dataLayoutCellSize;
+    }
+
+    private abstract static class AbstractMethodData implements HotSpotMethodDataAccessor {
+        private static final int EXCEPTIONS_MASK = 0x80;
+
+        private final int tag;
+        private final int staticSize;
+
+        protected AbstractMethodData(int tag, int staticSize) {
+            this.tag = tag;
+            this.staticSize = staticSize;
+        }
+
+        public int getTag() {
+            return tag;
+        }
+
+        public static int readTag(HotSpotMethodData data, int position) {
+            return data.readUnsignedByte(position, config.dataLayoutTagOffset);
+        }
+
+        @Override
+        public int getBCI(HotSpotMethodData data, int position) {
+            return data.readUnsignedShort(position, config.dataLayoutBCIOffset);
+        }
+
+        @Override
+        public int getSize(HotSpotMethodData data, int position) {
+            return staticSize + getDynamicSize(data, position);
+        }
+
+        @Override
+        public ExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
+            return ExceptionSeen.get((getFlags(data, position) & EXCEPTIONS_MASK) != 0);
+        }
+
+        @Override
+        public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
+            return null;
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        @Override
+        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
+            return null;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+        protected int getFlags(HotSpotMethodData data, int position) {
+            return data.readUnsignedByte(position, config.dataLayoutFlagsOffset);
+        }
+
+        protected int getDynamicSize(@SuppressWarnings("unused") HotSpotMethodData data, @SuppressWarnings("unused") int position) {
+            return 0;
+        }
+    }
+
+    private static class NoMethodData extends AbstractMethodData {
+        private static final int NO_DATA_TAG = 0;
+        private static final int NO_DATA_SIZE = cellIndexToOffset(0);
+
+        private final ExceptionSeen exceptionSeen;
+
+        protected NoMethodData(ExceptionSeen exceptionSeen) {
+            super(NO_DATA_TAG, NO_DATA_SIZE);
+            this.exceptionSeen = exceptionSeen;
+        }
+
+        @Override
+        public int getBCI(HotSpotMethodData data, int position) {
+            return -1;
+        }
+
+
+        @Override
+        public ExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
+            return exceptionSeen;
+        }
+    }
+
+    private static class BitData extends AbstractMethodData {
+        private static final int BIT_DATA_TAG = 1;
+        private static final int BIT_DATA_SIZE = cellIndexToOffset(0);
+        private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01;
+
+        private BitData() {
+            super(BIT_DATA_TAG, BIT_DATA_SIZE);
+        }
+
+        protected BitData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @SuppressWarnings("unused")
+        public boolean getNullSeen(HotSpotMethodData data, int position) {
+            return (getFlags(data, position) & BIT_DATA_NULL_SEEN_FLAG) != 0;
+        }
+    }
+
+    private static class CounterData extends BitData {
+        private static final int COUNTER_DATA_TAG = 2;
+        private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
+        private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0);
+
+        public CounterData() {
+            super(COUNTER_DATA_TAG, COUNTER_DATA_SIZE);
+        }
+
+        protected CounterData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return getCounterValue(data, position);
+        }
+
+        protected int getCounterValue(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, COUNTER_DATA_COUNT_OFFSET);
+        }
+    }
+
+    private static class JumpData extends AbstractMethodData {
+        private static final int JUMP_DATA_TAG = 3;
+        private static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
+        protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(0);
+        protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1);
+
+        public JumpData() {
+            super(JUMP_DATA_TAG, JUMP_DATA_SIZE);
+        }
+
+        protected JumpData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            return getExecutionCount(data, position) != 0 ? 1 : 0;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return data.readUnsignedIntAsSignedInt(position, TAKEN_COUNT_OFFSET);
+        }
+
+        @SuppressWarnings("unused")
+        public int getTakenDisplacement(HotSpotMethodData data, int position) {
+            return data.readInt(position, TAKEN_DISPLACEMENT_OFFSET);
+        }
+    }
+
+    private abstract static class AbstractTypeData extends CounterData {
+        private static final int RECEIVER_TYPE_DATA_ROW_SIZE = cellsToBytes(2);
+        private static final int RECEIVER_TYPE_DATA_SIZE = cellIndexToOffset(1) + RECEIVER_TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
+        private static final int RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET = cellIndexToOffset(1);
+        private static final int RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET = cellIndexToOffset(2);
+
+        protected AbstractTypeData(int tag) {
+            super(tag, RECEIVER_TYPE_DATA_SIZE);
+        }
+
+        @Override
+        public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
+            int typeProfileWidth = config.typeProfileWidth;
+
+            ResolvedJavaType[] types = new ResolvedJavaType[typeProfileWidth];
+            long[] counts = new long[typeProfileWidth];
+            long totalCount = 0;
+            int entries = 0;
+
+            for (int i = 0; i < typeProfileWidth; i++) {
+                Object receiverKlassOop = data.readObject(position, getReceiverOffset(i));
+                if (receiverKlassOop != null) {
+                    Object graalMirror = unsafe.getObject(receiverKlassOop, (long) config.graalMirrorKlassOffset);
+                    if (graalMirror == null) {
+                        Class<?> javaClass = (Class<?>) unsafe.getObject(receiverKlassOop, (long) config.classMirrorOffset);
+                        graalMirror = HotSpotGraalRuntime.getInstance().getCompilerToVM().getType(javaClass);
+                        assert graalMirror != null : "must not return null";
+                    }
+
+
+                    types[entries] = (ResolvedJavaType) graalMirror;
+
+                    long count = data.readUnsignedInt(position, getCountOffset(i));
+                    totalCount += count;
+                    counts[entries] = count;
+
+                    entries++;
+                }
+            }
+
+            totalCount += getTypesNotRecordedExecutionCount(data, position);
+            return createRiTypeProfile(types, counts, totalCount, entries);
+        }
+
+        protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) {
+            // checkcast/aastore/instanceof profiling in the HotSpot template-based interpreter was adjusted so that the counter
+            // is incremented to indicate the polymorphic case instead of decrementing it for failed type checks
+            return getCounterValue(data, position);
+        }
+
+        private static JavaTypeProfile createRiTypeProfile(ResolvedJavaType[] types, long[] counts, long totalCount, int entries) {
+            if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) {
+                return null;
+            }
+
+            ProfiledType[] ptypes = new ProfiledType[entries];
+            double totalProbability = 0.0;
+            for (int i = 0; i < entries; i++) {
+                double p = counts[i];
+                p = p / totalCount;
+                totalProbability += p;
+                ptypes[i] = new ProfiledType(types[i], p);
+            }
+
+            Arrays.sort(ptypes);
+
+            double notRecordedTypeProbability = entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability));
+            return new JavaTypeProfile(notRecordedTypeProbability, ptypes);
+        }
+
+        private static int getReceiverOffset(int row) {
+            return RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET + row * RECEIVER_TYPE_DATA_ROW_SIZE;
+        }
+
+        protected static int getCountOffset(int row) {
+            return RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET + row * RECEIVER_TYPE_DATA_ROW_SIZE;
+        }
+    }
+
+    private static class TypeCheckData extends AbstractTypeData {
+        private static final int RECEIVER_TYPE_DATA_TAG = 4;
+
+        public TypeCheckData() {
+            super(RECEIVER_TYPE_DATA_TAG);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            return -1;
+        }
+    }
+
+    private static class VirtualCallData extends AbstractTypeData {
+        private static final int VIRTUAL_CALL_DATA_TAG = 5;
+
+        public VirtualCallData() {
+            super(VIRTUAL_CALL_DATA_TAG);
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            int typeProfileWidth = config.typeProfileWidth;
+
+            long total = 0;
+            for (int i = 0; i < typeProfileWidth; i++) {
+                total += data.readUnsignedInt(position, getCountOffset(i));
+            }
+
+            total += getCounterValue(data, position);
+            return truncateLongToInt(total);
+        }
+    }
+
+    private static class RetData extends CounterData {
+        private static final int RET_DATA_TAG = 6;
+        private static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
+        private static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth;
+
+        public RetData() {
+            super(RET_DATA_TAG, RET_DATA_SIZE);
+        }
+    }
+
+    private static class BranchData extends JumpData {
+        private static final int BRANCH_DATA_TAG = 7;
+        private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
+        private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2);
+
+        public BranchData() {
+            super(BRANCH_DATA_TAG, BRANCH_DATA_SIZE);
+        }
+
+        @Override
+        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
+            long takenCount = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET);
+            long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
+            long total = takenCount + notTakenCount;
+
+            if (total < GraalOptions.MatureExecutionsBranch) {
+                return -1;
+            } else {
+                return takenCount / (double) total;
+            }
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            long count = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET) + data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
+            return truncateLongToInt(count);
+        }
+    }
+
+    private static class ArrayData extends AbstractMethodData {
+        private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(0);
+        protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(1);
+
+        public ArrayData(int tag, int staticSize) {
+            super(tag, staticSize);
+        }
+
+        @Override
+        protected int getDynamicSize(HotSpotMethodData data, int position) {
+            return cellsToBytes(getLength(data, position));
+        }
+
+        protected static int getLength(HotSpotMethodData data, int position) {
+            return data.readInt(position, ARRAY_DATA_LENGTH_OFFSET);
+        }
+    }
+
+    private static class MultiBranchData extends ArrayData {
+        private static final int MULTI_BRANCH_DATA_TAG = 8;
+        private static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
+        private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = 2;
+        private static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
+        private static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
+        private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
+
+        public MultiBranchData() {
+            super(MULTI_BRANCH_DATA_TAG, MULTI_BRANCH_DATA_SIZE);
+        }
+
+        @Override
+        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
+            int arrayLength = getLength(data, position);
+            assert arrayLength > 0 : "switch must have at least the default case";
+            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
+
+            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
+            long totalCount = 0;
+            double[] result = new double[length];
+
+            // default case is first in HotSpot but last for the compiler
+            long count = readCount(data, position, 0);
+            totalCount += count;
+            result[length - 1] = count;
+
+            for (int i = 1; i < length; i++) {
+                count = readCount(data, position, i);
+                totalCount += count;
+                result[i - 1] = count;
+            }
+
+            if (totalCount < GraalOptions.MatureExecutionsPerSwitchCase * length) {
+                return null;
+            } else {
+                for (int i = 0; i < length; i++) {
+                    result[i] = result[i] / totalCount;
+                }
+                return result;
+            }
+        }
+
+        private static long readCount(HotSpotMethodData data, int position, int i) {
+            int offset;
+            long count;
+            offset = getCountOffset(i);
+            count = data.readUnsignedInt(position, offset);
+            return count;
+        }
+
+        @Override
+        public int getExecutionCount(HotSpotMethodData data, int position) {
+            int arrayLength = getLength(data, position);
+            assert arrayLength > 0 : "switch must have at least the default case";
+            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
+
+            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
+            long totalCount = 0;
+            for (int i = 0; i < length; i++) {
+                int offset = getCountOffset(i);
+                totalCount += data.readUnsignedInt(position, offset);
+            }
+
+            return truncateLongToInt(totalCount);
+        }
+
+        private static int getCountOffset(int index) {
+            return MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
+        }
+
+        @SuppressWarnings("unused")
+        private static int getDisplacementOffset(int index) {
+            return MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
+        }
+    }
+
+    private static class ArgInfoData extends ArrayData {
+        private static final int ARG_INFO_DATA_TAG = 9;
+        private static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1);
+
+        public ArgInfoData() {
+            super(ARG_INFO_DATA_TAG, ARG_INFO_DATA_SIZE);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Interface for accessor objects that encapsulate the logic for accessing the different kinds of data in a HotSpot methodDataOop.
+ * This interface is similar to the interface {@link ProfilingInfo}, but most methods require a MethodDataObject and the
+ * exact position within the methodData.
+ */
+public interface HotSpotMethodDataAccessor {
+    /**
+     * Returns the tag stored in the LayoutData header.
+     * @return An integer >= 0 or -1 if not supported.
+     */
+    int getTag();
+
+    /**
+     * Returns the BCI stored in the LayoutData header.
+     * @return An integer >= 0 and <= Short.MAX_VALUE, or -1 if not supported.
+     */
+    int getBCI(HotSpotMethodData data, int position);
+
+    /**
+     * Computes the size for the specific data at the given position.
+     * @return An integer > 0.
+     */
+    int getSize(HotSpotMethodData data, int position);
+
+    JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position);
+    double getBranchTakenProbability(HotSpotMethodData data, int position);
+    double[] getSwitchProbabilities(HotSpotMethodData data, int position);
+    ExceptionSeen getExceptionSeen(HotSpotMethodData data, int position);
+    int getExecutionCount(HotSpotMethodData data, int position);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Implementation of RiMethod for unresolved HotSpot methods.
+ */
+public final class HotSpotMethodUnresolved extends HotSpotMethod {
+    private static final long serialVersionUID = 5610263481791970079L;
+    private final Signature signature;
+    protected JavaType holder;
+
+    public HotSpotMethodUnresolved(String name, String signature, JavaType holder) {
+        this.name = name;
+        this.holder = holder;
+        this.signature = new HotSpotSignature(signature);
+    }
+
+    @Override
+    public Signature signature() {
+        return signature;
+    }
+
+    @Override
+    public JavaType holder() {
+        return holder;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotMethod<" + holder.name() + ". " + name + ", unresolved>";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,154 @@
+/*
+ * 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.hotspot.meta;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.*;
+
+
+public final class HotSpotProfilingInfo extends CompilerObject implements ProfilingInfo {
+
+    private static final long serialVersionUID = -8307682725047864875L;
+    private static final DebugMetric metricInsufficentSpace = Debug.metric("InsufficientSpaceForProfilingData");
+
+    private int position;
+    private int hintPosition;
+    private int hintBCI;
+    private HotSpotMethodDataAccessor dataAccessor;
+    private HotSpotMethodData methodData;
+    private final int codeSize;
+
+    public HotSpotProfilingInfo(HotSpotMethodData methodData, int codeSize) {
+        this.methodData = methodData;
+        this.codeSize = codeSize;
+        hintPosition = 0;
+        hintBCI = -1;
+    }
+
+    @Override
+    public int codeSize() {
+        return codeSize;
+    }
+
+    @Override
+    public JavaTypeProfile getTypeProfile(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getTypeProfile(methodData, position);
+    }
+
+    @Override
+    public double getBranchTakenProbability(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getBranchTakenProbability(methodData, position);
+    }
+
+    @Override
+    public double[] getSwitchProbabilities(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getSwitchProbabilities(methodData, position);
+    }
+
+    @Override
+    public ExceptionSeen getExceptionSeen(int bci) {
+        findBCI(bci, true);
+        return dataAccessor.getExceptionSeen(methodData, position);
+    }
+
+    @Override
+    public int getExecutionCount(int bci) {
+        findBCI(bci, false);
+        return dataAccessor.getExecutionCount(methodData, position);
+    }
+
+    @Override
+    public int getDeoptimizationCount(DeoptimizationReason reason) {
+        return methodData.getDeoptimizationCount(reason);
+    }
+
+    private void findBCI(int targetBCI, boolean searchExtraData) {
+        assert targetBCI >= 0 : "invalid BCI";
+
+        if (methodData.hasNormalData()) {
+            int currentPosition = targetBCI < hintBCI ? 0 : hintPosition;
+            HotSpotMethodDataAccessor currentAccessor;
+            while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) {
+                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
+                if (currentBCI == targetBCI) {
+                    normalDataFound(currentAccessor, currentPosition, currentBCI);
+                    return;
+                } else if (currentBCI > targetBCI) {
+                    break;
+                }
+                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
+            }
+        }
+
+        boolean exceptionPossiblyNotRecorded = false;
+        if (searchExtraData && methodData.hasExtraData()) {
+            int currentPosition = methodData.getExtraDataBeginOffset();
+            HotSpotMethodDataAccessor currentAccessor;
+            while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) {
+                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
+                if (currentBCI == targetBCI) {
+                    extraDataFound(currentAccessor, currentPosition);
+                    return;
+                }
+                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
+            }
+
+            if (!methodData.isWithin(currentPosition)) {
+                exceptionPossiblyNotRecorded = true;
+                metricInsufficentSpace.increment();
+            }
+        }
+
+        noDataFound(exceptionPossiblyNotRecorded);
+    }
+
+    private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) {
+        setCurrentData(data, pos);
+        this.hintPosition = position;
+        this.hintBCI = bci;
+    }
+
+    private void extraDataFound(HotSpotMethodDataAccessor data, int pos) {
+        setCurrentData(data, pos);
+    }
+
+    private void noDataFound(boolean exceptionPossiblyNotRecorded) {
+        HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded);
+        setCurrentData(accessor, -1);
+    }
+
+    private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) {
+        this.dataAccessor = dataAccessor;
+        this.position = position;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotProfilingInfo<" + CodeUtil.profileToString(this, null, "; ") + ">";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegisterConfig.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.max.asm.target.amd64.AMD64.*;
+
+import java.util.*;
+
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.*;
+import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+
+public class HotSpotRegisterConfig implements RegisterConfig {
+
+    // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp
+    private final Register[] allocatable = {
+        rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/
+        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+    };
+
+    private final EnumMap<RegisterFlag, Register[]> categorized = Register.categorize(allocatable);
+
+    private final RegisterAttributes[] attributesMap;
+
+    @Override
+    public Register[] getAllocatableRegisters() {
+        return allocatable;
+    }
+
+    @Override
+    public EnumMap<RegisterFlag, Register[]> getCategorizedAllocatableRegisters() {
+        return categorized;
+    }
+
+    @Override
+    public RegisterAttributes[] getAttributesMap() {
+        return attributesMap;
+    }
+
+    private final Register[] generalParameterRegisters;
+    private final Register[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7};
+    private final Register[] allParameterRegisters;
+
+    private final CalleeSaveLayout csl;
+
+    public HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) {
+        if (config.windowsOs) {
+            generalParameterRegisters = new Register[] {rdx, r8, r9, rdi, rsi, rcx};
+        } else {
+            generalParameterRegisters = new Register[] {rsi, rdx, rcx, r8, r9, rdi};
+        }
+
+        if (globalStubConfig) {
+            Register[] regs = {
+                rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
+                r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
+                xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
+                xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
+            };
+            csl = new CalleeSaveLayout(0, -1, 8, regs);
+        } else {
+            // We reserve space for saving RBP but don't explicitly specify
+            // it as a callee save register since we explicitly do the saving
+            // with push and pop in HotSpotFrameContext
+            final int size = 8;
+            final Register[] regs = {};
+            csl = new CalleeSaveLayout(0, size, 8, regs);
+        }
+
+        attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters);
+        allParameterRegisters = Arrays.copyOf(generalParameterRegisters, generalParameterRegisters.length + xmmParameterRegisters.length);
+        System.arraycopy(xmmParameterRegisters, 0, allParameterRegisters, generalParameterRegisters.length, xmmParameterRegisters.length);
+    }
+
+    @Override
+    public Register[] getCallerSaveRegisters() {
+        return getAllocatableRegisters();
+    }
+
+    @Override
+    public Register getRegisterForRole(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CallingConvention getCallingConvention(Type type, Kind[] parameters, TargetDescription target, boolean stackOnly) {
+        if (type == Type.NativeCall) {
+            throw new UnsupportedOperationException();
+        }
+        return callingConvention(parameters, type, target, stackOnly);
+    }
+
+    public Register[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
+        return allParameterRegisters;
+    }
+
+    private CallingConvention callingConvention(Kind[] types, Type type, TargetDescription target, boolean stackOnly) {
+        Value[] locations = new Value[types.length];
+
+        int currentGeneral = 0;
+        int currentXMM = 0;
+        int currentStackOffset = 0;
+
+        for (int i = 0; i < types.length; i++) {
+            final Kind kind = types[i];
+
+            switch (kind) {
+                case Byte:
+                case Boolean:
+                case Short:
+                case Char:
+                case Int:
+                case Long:
+                case Object:
+                    if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
+                        Register register = generalParameterRegisters[currentGeneral++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+                case Float:
+                case Double:
+                    if (!stackOnly && currentXMM < xmmParameterRegisters.length) {
+                        Register register = xmmParameterRegisters[currentXMM++];
+                        locations[i] = register.asValue(kind);
+                    }
+                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+
+            if (locations[i] == null) {
+                locations[i] = StackSlot.get(kind.stackKind(), currentStackOffset, !type.out);
+                currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize);
+            }
+        }
+
+        return new CallingConvention(locations, currentStackOffset);
+    }
+
+    @Override
+    public Register getReturnRegister(Kind kind) {
+        switch (kind) {
+            case Boolean:
+            case Byte:
+            case Char:
+            case Short:
+            case Int:
+            case Long:
+            case Object:
+                return rax;
+            case Float:
+            case Double:
+                return xmm0;
+            case Void:
+            case Illegal:
+                return null;
+            default:
+                throw new UnsupportedOperationException("no return register for type " + kind);
+        }
+    }
+
+    @Override
+    public Register getScratchRegister() {
+        return r10;
+    }
+
+    @Override
+    public Register getFrameRegister() {
+        return rsp;
+    }
+
+    public CalleeSaveLayout getCalleeSaveLayout() {
+        return csl;
+    }
+
+    @Override
+    public String toString() {
+        String res = String.format(
+             "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
+             "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
+             "CalleeSave:  " + getCalleeSaveLayout() + "%n" +
+             "Scratch:     " + getScratchRegister() + "%n");
+        return res;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.hotspot.meta;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Represents a field in a HotSpot type.
+ */
+public class HotSpotResolvedJavaField extends CompilerObject implements ResolvedJavaField {
+
+    private static final long serialVersionUID = 7692985878836955683L;
+    private final ResolvedJavaType holder;
+    private final String name;
+    private final JavaType type;
+    private final int offset;
+    private final int accessFlags;
+    private Constant constant;                // Constant part only valid for static fields.
+
+    public HotSpotResolvedJavaField(ResolvedJavaType holder, String name, JavaType type, int offset, int accessFlags) {
+        this.holder = holder;
+        this.name = name;
+        this.type = type;
+        assert offset != -1;
+        this.offset = offset;
+        this.accessFlags = accessFlags;
+    }
+
+    @Override
+    public int accessFlags() {
+        return accessFlags;
+    }
+
+    @Override
+    public Constant constantValue(Constant receiver) {
+        if (receiver == null) {
+            assert Modifier.isStatic(accessFlags);
+            if (constant == null) {
+                if (holder.isInitialized() && holder.toJava() != System.class) {
+                    if (Modifier.isFinal(accessFlags()) || assumeStaticFieldsFinal(holder.toJava())) {
+                        constant = getValue(receiver);
+                    }
+                }
+            }
+            return constant;
+        } else {
+            assert !Modifier.isStatic(accessFlags);
+            // TODO (chaeubl) HotSpot does not trust final non-static fields (see ciField.cpp)
+            if (Modifier.isFinal(accessFlags())) {
+                return getValue(receiver);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Constant getValue(Constant receiver) {
+        if (receiver == null) {
+            assert Modifier.isStatic(accessFlags);
+            if (holder.isInitialized()) {
+                Constant encoding = holder.getEncoding(Representation.StaticFields);
+                return this.kind().readUnsafeConstant(encoding.asObject(), offset);
+            }
+            return null;
+        } else {
+            assert !Modifier.isStatic(accessFlags);
+            return this.kind().readUnsafeConstant(receiver.asObject(), offset);
+        }
+    }
+
+    private static boolean assumeStaticFieldsFinal(Class< ? > clazz) {
+        return clazz == GraalOptions.class;
+    }
+
+    @Override
+    public ResolvedJavaType holder() {
+        return holder;
+    }
+
+    @Override
+    public Kind kind() {
+        return type().kind();
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public JavaType type() {
+        return type;
+    }
+
+    public int offset() {
+        return offset;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotField<" + CodeUtil.format("%h.%n", this) + ":" + offset + ">";
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        Field javaField = toJava();
+        if (javaField != null) {
+            return javaField.getAnnotation(annotationClass);
+        }
+        return null;
+    }
+
+    private Field toJava() {
+        try {
+            return holder.toJava().getDeclaredField(name);
+        } catch (NoSuchFieldException e) {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.bytecode.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.counters.*;
+import com.oracle.max.criutils.*;
+
+/**
+ * Implementation of RiMethod for resolved HotSpot methods.
+ */
+public final class HotSpotResolvedJavaMethod extends HotSpotMethod implements ResolvedJavaMethod {
+
+    private static final long serialVersionUID = -5486975070147586588L;
+
+    /** DO NOT USE IN JAVA CODE! */
+    @SuppressWarnings("unused")
+    @Deprecated
+    private Object javaMirror;
+
+    // cached values
+    private final int codeSize;
+    private final int accessFlags;
+    private final int maxLocals;
+    private final int maxStackSize;
+    private Signature signature;
+    private Boolean hasBalancedMonitors;
+    private Map<Object, Object> compilerStorage;
+    private ResolvedJavaType holder;
+    private HotSpotMethodData methodData;
+    private byte[] code;
+    private boolean canBeInlined;
+    private int compilationComplexity;
+
+    private CompilationTask currentTask;
+
+    private HotSpotResolvedJavaMethod() {
+        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
+    }
+
+    @Override
+    public ResolvedJavaType holder() {
+        return holder;
+    }
+
+    @Override
+    public int accessFlags() {
+        return accessFlags;
+    }
+
+    @Override
+    public boolean canBeStaticallyBound() {
+        return isLeafMethod() || Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public byte[] code() {
+        if (code == null) {
+            code = HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_code(this);
+            assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length;
+        }
+        return code;
+    }
+
+    @Override
+    public int codeSize() {
+        return codeSize;
+    }
+
+    @Override
+    public ExceptionHandler[] exceptionHandlers() {
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_exceptionHandlers(this);
+    }
+
+    @Override
+    public boolean hasBalancedMonitors() {
+        if (hasBalancedMonitors == null) {
+            hasBalancedMonitors = HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_hasBalancedMonitors(this);
+        }
+        return hasBalancedMonitors;
+    }
+
+    @Override
+    public boolean isClassInitializer() {
+        return "<clinit>".equals(name) && Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public boolean isConstructor() {
+        return "<init>".equals(name) && !Modifier.isStatic(accessFlags());
+    }
+
+    @Override
+    public boolean isLeafMethod() {
+        return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags());
+    }
+
+    @Override
+    public String jniSymbol() {
+        throw new UnsupportedOperationException("jniSymbol");
+    }
+
+    @Override
+    public int maxLocals() {
+        return maxLocals;
+    }
+
+    @Override
+    public int maxStackSize() {
+        return maxStackSize;
+    }
+
+    @Override
+    public StackTraceElement toStackTraceElement(int bci) {
+        if (bci < 0 || bci >= codeSize) {
+            // HotSpot code can only construct stack trace elements for valid bcis
+            StackTraceElement ste = HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_toStackTraceElement(this, 0);
+            return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
+        }
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_toStackTraceElement(this, bci);
+    }
+
+    public ResolvedJavaMethod uniqueConcreteMethod() {
+        return (ResolvedJavaMethod) HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_uniqueConcreteMethod(this);
+    }
+
+    @Override
+    public Signature signature() {
+        if (signature == null) {
+            signature = new HotSpotSignature(HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_signature(this));
+        }
+        return signature;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotMethod<" + CodeUtil.format("%h.%n", this) + ">";
+    }
+
+    public boolean hasCompiledCode() {
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_hasCompiledCode(this);
+    }
+
+    public int compiledCodeSize() {
+        int result = HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_getCompiledCodeSize(this);
+        if (result > 0) {
+            assert result > MethodEntryCounters.getCodeSize();
+            result =  result - MethodEntryCounters.getCodeSize();
+        }
+        return result;
+    }
+
+    @Override
+    public int invocationCount() {
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_invocationCount(this);
+    }
+
+    @Override
+    public int compilationComplexity() {
+        if (compilationComplexity <= 0 && codeSize() > 0) {
+            BytecodeStream s = new BytecodeStream(code());
+            int result = 0;
+            int currentBC;
+            while ((currentBC = s.currentBC()) != Bytecodes.END) {
+                result += Bytecodes.compilationComplexity(currentBC);
+                s.next();
+            }
+            assert result > 0;
+            compilationComplexity = result;
+        }
+        return compilationComplexity;
+    }
+
+    private static final MethodFilter profilingInfoFilter = GraalOptions.PIFilter == null ? null : new MethodFilter(GraalOptions.PIFilter);
+
+    /**
+     * Determines if the profiling info cache should be used for this method.
+     */
+    private boolean useProfilingInfoCache() {
+        return GraalOptions.PICache != null && (profilingInfoFilter == null || profilingInfoFilter.matches(this));
+    }
+
+    private ProfilingInfo loadProfilingInfo() {
+        if (!useProfilingInfoCache()) {
+            return null;
+        }
+        synchronized (this) {
+            File file = new File(GraalOptions.PICache, JniMangle.mangleMethod(holder, name, signature(), false));
+            if (file.exists()) {
+                try {
+                    SnapshotProfilingInfo snapshot = SnapshotProfilingInfo.load(file, HotSpotGraalRuntime.getInstance().getRuntime());
+                    if (snapshot.codeSize() != codeSize) {
+                        // The class file was probably changed - ignore the saved profile
+                        return null;
+                    }
+                    return snapshot;
+                } catch (Exception e) {
+                    // ignore
+                }
+            }
+            return null;
+        }
+    }
+
+    private void saveProfilingInfo(ProfilingInfo info) {
+        if (useProfilingInfoCache()) {
+            synchronized (this) {
+                String base = JniMangle.mangleMethod(holder, name, signature(), false);
+                File file = new File(GraalOptions.PICache, base);
+                File txtFile = new File(GraalOptions.PICache, base + ".txt");
+                SnapshotProfilingInfo snapshot = info instanceof SnapshotProfilingInfo ? (SnapshotProfilingInfo) info : new SnapshotProfilingInfo(info);
+                try {
+                    snapshot.save(file, txtFile);
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    @Override
+    public ProfilingInfo profilingInfo() {
+        ProfilingInfo info = loadProfilingInfo();
+        if (info != null) {
+            return info;
+        }
+
+        if (GraalOptions.UseProfilingInformation && methodData == null) {
+            methodData = HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_methodData(this);
+        }
+
+        if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) {
+            // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in case of a deoptimization.
+            info = BaseProfilingInfo.get(ExceptionSeen.FALSE);
+        } else {
+            info = new HotSpotProfilingInfo(methodData, codeSize);
+            saveProfilingInfo(info);
+        }
+        return info;
+    }
+
+    @Override
+    public Map<Object, Object> compilerStorage() {
+        if (compilerStorage == null) {
+            compilerStorage = new ConcurrentHashMap<>();
+        }
+        return compilerStorage;
+    }
+
+    @Override
+    public ConstantPool getConstantPool() {
+        return ((HotSpotResolvedJavaType) holder()).constantPool();
+    }
+
+    @Override
+    public Annotation[][] getParameterAnnotations() {
+        if (isConstructor()) {
+            Constructor javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getParameterAnnotations();
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getParameterAnnotations();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        if (isConstructor()) {
+            Constructor<?> javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass);
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
+    }
+
+    @Override
+    public Type[] getGenericParameterTypes() {
+        if (isConstructor()) {
+            Constructor javaConstructor = toJavaConstructor();
+            return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes();
+        }
+        Method javaMethod = toJava();
+        return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
+    }
+
+    private Method toJava() {
+        try {
+            return holder.toJava().getDeclaredMethod(name, CodeUtil.signatureToTypes(signature(), holder));
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    private Constructor toJavaConstructor() {
+        try {
+            return holder.toJava().getDeclaredConstructor(CodeUtil.signatureToTypes(signature(), holder));
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean canBeInlined() {
+        return canBeInlined;
+    }
+
+    public int vtableEntryOffset() {
+        return HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaMethod_vtableEntryOffset(this);
+    }
+
+    public void setCurrentTask(CompilationTask task) {
+        currentTask = task;
+    }
+
+    public CompilationTask currentTask() {
+        return currentTask;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of RiType for resolved non-primitive HotSpot classes.
+ */
+public final class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {
+
+    private static final long serialVersionUID = 3481514353553840471L;
+
+    private Class javaMirror;
+    private String simpleName;
+    private int accessFlags;
+    private boolean hasFinalizer;
+    private boolean hasFinalizableSubclass;
+    private int superCheckOffset;
+    private boolean isArrayClass;
+    private boolean isInstanceClass;
+    private boolean isInterface;
+    private int instanceSize;
+    private HashMap<Long, ResolvedJavaField> fieldCache;
+    private ResolvedJavaType superType;
+    private boolean superTypeSet;
+    private ResolvedJavaField[] fields;
+    private ConstantPool constantPool;
+    private boolean isInitialized;
+    private ResolvedJavaType arrayOfType;
+    private long prototypeHeader;
+
+    private HotSpotResolvedJavaType() {
+        throw new GraalInternalError(HotSpotResolvedJavaType.class + " should only be created from C++ code");
+    }
+
+    @Override
+    public int accessFlags() {
+        return accessFlags;
+    }
+
+    @Override
+    public ResolvedJavaType arrayOf() {
+        if (arrayOfType == null) {
+           arrayOfType = (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_arrayOf(this);
+        }
+        return arrayOfType;
+    }
+
+    @Override
+    public ResolvedJavaType componentType() {
+        assert isArrayClass();
+        return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_componentType(this);
+    }
+
+    @Override
+    public ResolvedJavaType uniqueConcreteSubtype() {
+        if (isArrayClass()) {
+            return Modifier.isFinal(componentType().accessFlags()) ? this : null;
+        } else {
+            return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_uniqueConcreteSubtype(this);
+        }
+    }
+
+    @Override
+    public ResolvedJavaType superType() {
+        if (!superTypeSet) {
+            superType = (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_superType(this);
+            superTypeSet = true;
+        }
+        return superType;
+    }
+
+    @Override
+    public ResolvedJavaType leastCommonAncestor(ResolvedJavaType otherType) {
+        if (otherType instanceof HotSpotTypePrimitive) {
+            return null;
+        } else {
+            return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_leastCommonAncestor(this, (HotSpotResolvedJavaType) otherType);
+        }
+    }
+
+    @Override
+    public ResolvedJavaType exactType() {
+        if (Modifier.isFinal(accessFlags)) {
+            return this;
+        }
+        return null;
+    }
+
+    @Override
+    public Constant getEncoding(Representation r) {
+        switch (r) {
+            case JavaClass:
+                return Constant.forObject(javaMirror);
+            case ObjectHub:
+                return Constant.forObject(klassOop());
+            case StaticFields:
+                return Constant.forObject(javaMirror);
+            default:
+                assert false : "Should not reach here.";
+                return null;
+        }
+    }
+
+    @Override
+    public Kind getRepresentationKind(Representation r) {
+        return Kind.Object;
+    }
+
+    @Override
+    public boolean hasFinalizableSubclass() {
+        return hasFinalizableSubclass;
+    }
+
+    @Override
+    public boolean hasFinalizer() {
+        return hasFinalizer;
+    }
+
+    @Override
+    public boolean isArrayClass() {
+        return isArrayClass;
+    }
+
+    @Override
+    public boolean isInitialized() {
+        if (!isInitialized) {
+            isInitialized = HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_isInitialized(this);
+        }
+        return isInitialized;
+    }
+
+    @Override
+    public boolean isInstance(Constant obj) {
+        return javaMirror.isInstance(obj);
+    }
+
+    @Override
+    public boolean isInstanceClass() {
+        return isInstanceClass;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return isInterface;
+    }
+
+    @Override
+    public boolean isSubtypeOf(ResolvedJavaType other) {
+        if (other instanceof HotSpotResolvedJavaType) {
+            return HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_isSubtypeOf(this, other);
+        }
+        // No resolved type is a subtype of an unresolved type.
+        return false;
+    }
+
+    @Override
+    public Kind kind() {
+        return Kind.Object;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveMethodImpl(ResolvedJavaMethod method) {
+        assert method instanceof HotSpotMethod;
+        return (ResolvedJavaMethod) HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_resolveMethodImpl(this, method.name(), method.signature().asString());
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotType<" + simpleName + ", resolved>";
+    }
+
+    public ConstantPool constantPool() {
+        if (constantPool == null) {
+            constantPool = new HotSpotConstantPool(this);
+        }
+        return constantPool;
+    }
+
+    /**
+     * Gets the instance size of this type. If an instance of this type cannot
+     * be fast path allocated, then the returned value is negative (its absolute
+     * value gives the size).
+     */
+    public int instanceSize() {
+        return instanceSize;
+    }
+
+    public synchronized ResolvedJavaField createRiField(String fieldName, JavaType type, int offset, int flags) {
+        ResolvedJavaField result = null;
+
+        long id = offset + ((long) flags << 32);
+
+        // (thomaswue) Must cache the fields, because the local load elimination only works if the objects from two field lookups are identical.
+        if (fieldCache == null) {
+            fieldCache = new HashMap<>(8);
+        } else {
+            result = fieldCache.get(id);
+        }
+
+        if (result == null) {
+            result = new HotSpotResolvedJavaField(this, fieldName, type, offset, flags);
+            fieldCache.put(id, result);
+        } else {
+            assert result.name().equals(fieldName);
+            assert result.accessFlags() == flags;
+        }
+
+        return result;
+    }
+
+    @Override
+    public ResolvedJavaMethod uniqueConcreteMethod(ResolvedJavaMethod method) {
+        return ((HotSpotResolvedJavaMethod) method).uniqueConcreteMethod();
+    }
+
+    @Override
+    public ResolvedJavaField[] declaredFields() {
+        if (fields == null) {
+            fields = HotSpotGraalRuntime.getInstance().getCompilerToVM().JavaType_fields(this);
+        }
+        return fields;
+    }
+
+    @Override
+    public Class< ? > toJava() {
+        return javaMirror;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return toJava().getAnnotation(annotationClass);
+    }
+
+    @Override
+    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+        return this;
+    }
+
+    // this value may require identity semantics so cache it
+    private HotSpotKlassOop klassOopCache;
+
+    @Override
+    public synchronized HotSpotKlassOop klassOop() {
+        if (klassOopCache == null) {
+            klassOopCache = new HotSpotKlassOop(this);
+        }
+        return klassOopCache;
+    }
+
+    private static final int SECONDARY_SUPER_CACHE_OFFSET = HotSpotGraalRuntime.getInstance().getConfig().secondarySuperCacheOffset;
+
+    public boolean isPrimaryType() {
+        return SECONDARY_SUPER_CACHE_OFFSET != superCheckOffset;
+    }
+
+    public int superCheckOffset() {
+        return superCheckOffset;
+    }
+
+    public long prototypeHeader() {
+        return prototypeHeader;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.max.cri.util.MemoryBarriers.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.code.CodeUtil.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.snippets.*;
+import com.oracle.graal.hotspot.target.amd64.*;
+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.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.max.criutils.*;
+
+/**
+ * CRI runtime implementation for the HotSpot VM.
+ */
+public class HotSpotRuntime implements ExtendedRiRuntime {
+    public final HotSpotVMConfig config;
+    final HotSpotRegisterConfig regConfig;
+    private final HotSpotRegisterConfig globalStubRegConfig;
+    private final HotSpotGraalRuntime compiler;
+    private CheckCastSnippets.Templates checkcastSnippets;
+    private NewInstanceSnippets.Templates newInstanceSnippets;
+
+    public HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime compiler) {
+        this.config = config;
+        this.compiler = compiler;
+        regConfig = new HotSpotRegisterConfig(config, false);
+        globalStubRegConfig = new HotSpotRegisterConfig(config, true);
+
+        System.setProperty(Backend.BACKEND_CLASS_PROPERTY, HotSpotAMD64Backend.class.getName());
+    }
+
+    public void installSnippets(SnippetInstaller installer) {
+        installer.install(SystemSnippets.class);
+        installer.install(UnsafeSnippets.class);
+        installer.install(ArrayCopySnippets.class);
+        installer.install(CheckCastSnippets.class);
+        installer.install(NewInstanceSnippets.class);
+        checkcastSnippets = new CheckCastSnippets.Templates(this);
+        newInstanceSnippets = new NewInstanceSnippets.Templates(this, config.useTLAB);
+    }
+
+
+    public HotSpotGraalRuntime getCompiler() {
+        return compiler;
+    }
+
+    @Override
+    public String disassemble(CodeInfo info, CompilationResult tm) {
+        byte[] code = info.code();
+        TargetDescription target = compiler.getTarget();
+        HexCodeFile hcf = new HexCodeFile(code, info.start(), target.arch.name, target.wordSize * 8);
+        if (tm != null) {
+            HexCodeFile.addAnnotations(hcf, tm.annotations());
+            addExceptionHandlersComment(tm, hcf);
+            Register fp = regConfig.getFrameRegister();
+            RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0);
+            for (Safepoint safepoint : tm.getSafepoints()) {
+                if (safepoint instanceof Call) {
+                    Call call = (Call) safepoint;
+                    if (call.debugInfo != null) {
+                        hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
+                    }
+                    addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}");
+                } else {
+                    if (safepoint.debugInfo != null) {
+                        hcf.addComment(safepoint.pcOffset, CodeUtil.append(new StringBuilder(100), safepoint.debugInfo, slotFormatter).toString());
+                    }
+                    addOperandComment(hcf, safepoint.pcOffset, "{safepoint}");
+                }
+            }
+            for (DataPatch site : tm.getDataReferences()) {
+                hcf.addOperandComment(site.pcOffset, "{" + site.constant + "}");
+            }
+            for (Mark mark : tm.getMarks()) {
+                hcf.addComment(mark.pcOffset, getMarkName(mark));
+            }
+        }
+        return hcf.toEmbeddedString();
+    }
+
+    /**
+     * Decodes a call target to a mnemonic if possible.
+     */
+    private String getTargetName(Call call) {
+        Field[] fields = config.getClass().getDeclaredFields();
+        for (Field f : fields) {
+            if (f.getName().endsWith("Stub")) {
+                f.setAccessible(true);
+                try {
+                    if (f.get(config).equals(call.target)) {
+                        return f.getName();
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return String.valueOf(call.target);
+    }
+
+    /**
+     * Decodes a mark to a mnemonic if possible.
+     */
+    private static String getMarkName(Mark mark) {
+        Field[] fields = HotSpotXirGenerator.class.getDeclaredFields();
+        for (Field f : fields) {
+            if (Modifier.isStatic(f.getModifiers()) && f.getName().startsWith("MARK_")) {
+                f.setAccessible(true);
+                try {
+                    if (f.get(null).equals(mark.id)) {
+                        return f.getName();
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return "MARK:" + mark.id;
+    }
+
+    private static void addExceptionHandlersComment(CompilationResult tm, HexCodeFile hcf) {
+        if (!tm.getExceptionHandlers().isEmpty()) {
+            String nl = HexCodeFile.NEW_LINE;
+            StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl);
+            for (CompilationResult.ExceptionHandler e : tm.getExceptionHandlers()) {
+                buf.append("    ").
+                    append(e.pcOffset).append(" -> ").
+                    append(e.handlerPos).
+                    append(nl);
+                hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]");
+                hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]");
+            }
+            hcf.addComment(0, buf.toString());
+        }
+    }
+
+    private static void addOperandComment(HexCodeFile hcf, int pos, String comment) {
+        String oldValue = hcf.addOperandComment(pos, comment);
+        assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue;
+    }
+
+    @Override
+    public String disassemble(ResolvedJavaMethod method) {
+        return compiler.getCompilerToVM().disassembleJava((HotSpotResolvedJavaMethod) method);
+    }
+
+    @Override
+    public ResolvedJavaType getResolvedJavaType(Kind kind) {
+        return (ResolvedJavaType) compiler.getCompilerToVM().getType(kind.toJavaClass());
+    }
+
+    @Override
+    public ResolvedJavaType getTypeOf(Constant constant) {
+        return (ResolvedJavaType) compiler.getCompilerToVM().getJavaType(constant);
+    }
+
+    @Override
+    public int sizeOfLockData() {
+        // TODO shouldn't be hard coded
+        return 8;
+    }
+
+    @Override
+    public boolean areConstantObjectsEqual(Constant x, Constant y) {
+        return compiler.getCompilerToVM().compareConstantObjects(x, y);
+    }
+
+    @Override
+    public RegisterConfig getRegisterConfig(JavaMethod method) {
+        return regConfig;
+    }
+
+    /**
+     * HotSpots needs an area suitable for storing a program counter for temporary use during the deoptimization process.
+     */
+    @Override
+    public int getCustomStackAreaSize() {
+        // TODO shouldn't be hard coded
+        return 8;
+    }
+
+    @Override
+    public int getMinimumOutgoingSize() {
+        return config.runtimeCallStackSize;
+    }
+
+    @Override
+    public int getArrayLength(Constant array) {
+        return compiler.getCompilerToVM().getArrayLength(array);
+    }
+
+    @Override
+    public void lower(Node n, CiLoweringTool tool) {
+        StructuredGraph graph = (StructuredGraph) n.graph();
+        if (n instanceof ArrayLengthNode) {
+            ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
+            SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.array(), StructuredGraph.INVALID_GRAPH_ID);
+            graph.replaceFixedWithFixed(arrayLengthNode, safeReadArrayLength);
+        } else if (n instanceof LoadFieldNode) {
+            LoadFieldNode field = (LoadFieldNode) n;
+            int displacement = ((HotSpotResolvedJavaField) field.field()).offset();
+            assert field.kind() != Kind.Illegal;
+            ReadNode memoryRead = graph.add(new ReadNode(field.object(), LocationNode.create(field.field(), field.field().kind(), displacement, graph), field.stamp()));
+            memoryRead.dependencies().add(tool.createNullCheckGuard(field.object(), field.leafGraphId()));
+            graph.replaceFixedWithFixed(field, memoryRead);
+            if (field.isVolatile()) {
+                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
+                graph.addBeforeFixed(memoryRead, preMembar);
+                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
+                graph.addAfterFixed(memoryRead, postMembar);
+            }
+        } else if (n instanceof StoreFieldNode) {
+            StoreFieldNode storeField = (StoreFieldNode) n;
+            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
+            WriteNode memoryWrite = graph.add(new WriteNode(storeField.object(), storeField.value(), LocationNode.create(storeField.field(), storeField.field().kind(), field.offset(), graph)));
+            memoryWrite.dependencies().add(tool.createNullCheckGuard(storeField.object(), storeField.leafGraphId()));
+            memoryWrite.setStateAfter(storeField.stateAfter());
+            graph.replaceFixedWithFixed(storeField, memoryWrite);
+
+            FixedWithNextNode last = memoryWrite;
+            if (field.kind() == Kind.Object && !memoryWrite.value().isNullConstant()) {
+                FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(memoryWrite.object()));
+                graph.addAfterFixed(memoryWrite, writeBarrier);
+                last = writeBarrier;
+            }
+            if (storeField.isVolatile()) {
+                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
+                graph.addBeforeFixed(memoryWrite, preMembar);
+                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
+                graph.addAfterFixed(last, postMembar);
+            }
+        } else if (n instanceof CompareAndSwapNode) {
+            // Separate out GC barrier semantics
+            CompareAndSwapNode cas = (CompareAndSwapNode) n;
+            ValueNode expected = cas.expected();
+            if (expected.kind() == Kind.Object && !cas.newValue().isNullConstant()) {
+                ResolvedJavaType type = cas.object().objectStamp().type();
+                if (type != null && !type.isArrayClass() && type.toJava() != Object.class) {
+                    // Use a field write barrier since it's not an array store
+                    FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object()));
+                    graph.addAfterFixed(cas, writeBarrier);
+                } else {
+                    // This may be an array store so use an array write barrier
+                    LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, false);
+                    graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), location)));
+                }
+            }
+        } else if (n instanceof LoadIndexedNode) {
+            LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
+
+            ValueNode boundsCheck = createBoundsCheck(loadIndexed, tool);
+
+            Kind elementKind = loadIndexed.elementKind();
+            LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index());
+            ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp()));
+            memoryRead.dependencies().add(boundsCheck);
+            graph.replaceFixedWithFixed(loadIndexed, memoryRead);
+        } else if (n instanceof StoreIndexedNode) {
+            StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
+            ValueNode boundsCheck = createBoundsCheck(storeIndexed, tool);
+
+            Kind elementKind = storeIndexed.elementKind();
+            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index());
+            ValueNode value = storeIndexed.value();
+            CheckCastNode checkcast = null;
+            ValueNode array = storeIndexed.array();
+            if (elementKind == Kind.Object && !value.isNullConstant()) {
+                // Store check!
+                ResolvedJavaType arrayType = array.objectStamp().type();
+                if (arrayType != null && array.objectStamp().isExactType()) {
+                    ResolvedJavaType elementType = arrayType.componentType();
+                    if (elementType.superType() != null) {
+                        ConstantNode type = ConstantNode.forConstant(elementType.getEncoding(Representation.ObjectHub), this, graph);
+                        checkcast = graph.add(new CheckCastNode(type, elementType, value));
+                        graph.addBeforeFixed(storeIndexed, checkcast);
+                        value = checkcast;
+                    } else {
+                        assert elementType.name().equals("Ljava/lang/Object;") : elementType.name();
+                    }
+                } else {
+                    ValueNode guard = tool.createNullCheckGuard(array, StructuredGraph.INVALID_GRAPH_ID);
+                    FloatingReadNode arrayClass = graph.unique(new FloatingReadNode(array, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.hubOffset, graph), null, StampFactory.objectNonNull()));
+                    arrayClass.dependencies().add(guard);
+                    FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.arrayClassElementOffset, graph), null, StampFactory.objectNonNull()));
+                    checkcast = graph.add(new CheckCastNode(arrayElementKlass, null, value));
+                    graph.addBeforeFixed(storeIndexed, checkcast);
+                    value = checkcast;
+                }
+            }
+            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation));
+            memoryWrite.dependencies().add(boundsCheck);
+            memoryWrite.setStateAfter(storeIndexed.stateAfter());
+
+            graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
+
+            if (elementKind == Kind.Object && !value.isNullConstant()) {
+                graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation)));
+            }
+        } else if (n instanceof UnsafeLoadNode) {
+            UnsafeLoadNode load = (UnsafeLoadNode) n;
+            assert load.kind() != Kind.Illegal;
+            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph, false);
+            ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp()));
+            if (load.object().kind().isObject()) {
+                memoryRead.dependencies().add(tool.createNullCheckGuard(load.object(), StructuredGraph.INVALID_GRAPH_ID));
+            }
+            graph.replaceFixedWithFixed(load, memoryRead);
+        } else if (n instanceof UnsafeStoreNode) {
+            UnsafeStoreNode store = (UnsafeStoreNode) n;
+            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.storeKind(), store.displacement(), store.offset(), graph, false);
+            ValueNode object = store.object();
+            WriteNode write = graph.add(new WriteNode(object, store.value(), location));
+            write.setStateAfter(store.stateAfter());
+            graph.replaceFixedWithFixed(store, write);
+            if (write.value().kind() == Kind.Object && !write.value().isNullConstant()) {
+                ResolvedJavaType type = object.objectStamp().type();
+                WriteBarrier writeBarrier;
+                if (type != null && !type.isArrayClass() && type.toJava() != Object.class) {
+                    // Use a field write barrier since it's not an array store
+                    writeBarrier = graph.add(new FieldWriteBarrier(object));
+                } else {
+                    // This may be an array store so use an array write barrier
+                    writeBarrier = graph.add(new ArrayWriteBarrier(object, location));
+                }
+                graph.addAfterFixed(write, writeBarrier);
+            }
+        } else if (n instanceof ReadHubNode) {
+            ReadHubNode objectClassNode = (ReadHubNode) n;
+            LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.hubOffset, graph);
+            ReadNode memoryRead = graph.add(new ReadNode(objectClassNode.object(), location, StampFactory.objectNonNull()));
+            memoryRead.dependencies().add(tool.createNullCheckGuard(objectClassNode.object(), StructuredGraph.INVALID_GRAPH_ID));
+            graph.replaceFixed(objectClassNode, memoryRead);
+        } else if (n instanceof CheckCastNode) {
+            if (shouldLower(graph, GraalOptions.HIRLowerCheckcast)) {
+                checkcastSnippets.lower((CheckCastNode) n, tool);
+            }
+        } else if (n instanceof NewInstanceNode) {
+            if (shouldLower(graph, GraalOptions.HIRLowerNewInstance)) {
+                newInstanceSnippets.lower((NewInstanceNode) n, tool);
+            }
+        } else if (n instanceof TLABAllocateNode) {
+            newInstanceSnippets.lower((TLABAllocateNode) n, tool);
+        } else if (n instanceof InitializeNode) {
+            newInstanceSnippets.lower((InitializeNode) n, tool);
+        } else {
+            assert false : "Node implementing Lowerable not handled: " + n;
+        }
+    }
+
+    private static boolean shouldLower(StructuredGraph graph, String option) {
+        if (option != null) {
+            if (option.length() == 0) {
+                return true;
+            }
+            ResolvedJavaMethod method = graph.method();
+            return method != null && CodeUtil.format("%H.%n", method).contains(option);
+        }
+        return false;
+    }
+
+    private IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
+        return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, config.getArrayOffset(elementKind), index, graph, true);
+    }
+
+    private SafeReadNode safeReadArrayLength(ValueNode array, long leafGraphId) {
+        return safeRead(array.graph(), Kind.Int, array, config.arrayLengthOffset, StampFactory.positiveInt(), leafGraphId);
+    }
+
+    private static ValueNode createBoundsCheck(AccessIndexedNode n, CiLoweringTool tool) {
+        StructuredGraph graph = (StructuredGraph) n.graph();
+        ArrayLengthNode arrayLength = graph.add(new ArrayLengthNode(n.array()));
+        ValueNode guard = tool.createGuard(graph.unique(new IntegerBelowThanNode(n.index(), arrayLength)), DeoptimizationReason.BoundsCheckException, DeoptimizationAction.InvalidateReprofile, n.leafGraphId());
+
+        graph.addBeforeFixed(n, arrayLength);
+        return guard;
+    }
+
+    @Override
+    public StructuredGraph intrinsicGraph(ResolvedJavaMethod caller, int bci, ResolvedJavaMethod method, List<? extends Node> parameters) {
+        JavaType holder = method.holder();
+        String fullName = method.name() + method.signature().asString();
+        String holderName = holder.name();
+        if (holderName.equals("Ljava/lang/Object;")) {
+            if (fullName.equals("getClass()Ljava/lang/Class;")) {
+                ValueNode obj = (ValueNode) parameters.get(0);
+                ObjectStamp stamp = (ObjectStamp) obj.stamp();
+                if (stamp.nonNull() && stamp.isExactType()) {
+                    StructuredGraph graph = new StructuredGraph();
+                    ValueNode result = ConstantNode.forObject(stamp.type().toJava(), this, graph);
+                    ReturnNode ret = graph.add(new ReturnNode(result));
+                    graph.start().setNext(ret);
+                    return graph;
+                }
+                StructuredGraph graph = new StructuredGraph();
+                LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
+                SafeReadNode klassOop = safeReadHub(graph, receiver, StructuredGraph.INVALID_GRAPH_ID);
+                Stamp resultStamp = StampFactory.declaredNonNull(getResolvedJavaType(Class.class));
+                FloatingReadNode result = graph.unique(new FloatingReadNode(klassOop, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Object, config.classMirrorOffset, graph), null, resultStamp));
+                ReturnNode ret = graph.add(new ReturnNode(result));
+                graph.start().setNext(klassOop);
+                klassOop.setNext(ret);
+                return graph;
+            }
+        } else if (holderName.equals("Ljava/lang/Class;")) {
+            if (fullName.equals("getModifiers()I")) {
+                StructuredGraph graph = new StructuredGraph();
+                LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull()));
+                SafeReadNode klassOop = safeRead(graph, Kind.Object, receiver, config.klassOopOffset, StampFactory.objectNonNull(), StructuredGraph.INVALID_GRAPH_ID);
+                graph.start().setNext(klassOop);
+                // TODO(thomaswue): Care about primitive classes! Crashes for primitive classes at the moment (klassOop == null)
+                FloatingReadNode result = graph.unique(new FloatingReadNode(klassOop, LocationNode.create(LocationNode.FINAL_LOCATION, Kind.Int, config.klassModifierFlagsOffset, graph), null, StampFactory.intValue()));
+                ReturnNode ret = graph.add(new ReturnNode(result));
+                klassOop.setNext(ret);
+                return graph;
+            }
+        } else if (holderName.equals("Ljava/lang/Thread;")) {
+            if (fullName.equals("currentThread()Ljava/lang/Thread;")) {
+                StructuredGraph graph = new StructuredGraph();
+                ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset, this))));
+                graph.start().setNext(ret);
+                return graph;
+            }
+        }
+        return null;
+    }
+
+    private SafeReadNode safeReadHub(Graph graph, ValueNode value, long leafGraphId) {
+        return safeRead(graph, Kind.Object, value, config.hubOffset, StampFactory.objectNonNull(), leafGraphId);
+    }
+
+    private static SafeReadNode safeRead(Graph graph, Kind kind, ValueNode value, int offset, Stamp stamp, long leafGraphId) {
+        return graph.add(new SafeReadNode(value, LocationNode.create(LocationNode.FINAL_LOCATION, kind, offset, graph), stamp, leafGraphId));
+    }
+
+    public ResolvedJavaType getResolvedJavaType(Class<?> clazz) {
+        return (ResolvedJavaType) compiler.getCompilerToVM().getType(clazz);
+    }
+
+    public Object asCallTarget(Object target) {
+        return target;
+    }
+
+    public long getMaxCallTargetOffset(RuntimeCall rtcall) {
+        return compiler.getCompilerToVM().getMaxCallTargetOffset(rtcall);
+    }
+
+    public ResolvedJavaMethod getResolvedJavaMethod(Method reflectionMethod) {
+        return (ResolvedJavaMethod) compiler.getCompilerToVM().getJavaMethod(reflectionMethod);
+    }
+
+    private static HotSpotCodeInfo makeInfo(ResolvedJavaMethod method, CompilationResult code, CodeInfo[] info) {
+        HotSpotCodeInfo hsInfo = null;
+        if (info != null && info.length > 0) {
+            hsInfo = new HotSpotCodeInfo(code, (HotSpotResolvedJavaMethod) method);
+            info[0] = hsInfo;
+        }
+        return hsInfo;
+    }
+
+    public void installMethod(ResolvedJavaMethod method, CompilationResult code, CodeInfo[] info) {
+        HotSpotCodeInfo hsInfo = makeInfo(method, code, info);
+        compiler.getCompilerToVM().installMethod(new HotSpotTargetMethod((HotSpotResolvedJavaMethod) method, code), true, hsInfo);
+    }
+
+    @Override
+    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult code, CodeInfo[] info) {
+        HotSpotCodeInfo hsInfo = makeInfo(method, code, info);
+        return compiler.getCompilerToVM().installMethod(new HotSpotTargetMethod((HotSpotResolvedJavaMethod) method, code), false, hsInfo);
+    }
+
+    @Override
+    public RegisterConfig getGlobalStubRegisterConfig() {
+        return globalStubRegConfig;
+    }
+
+    @Override
+    public CompilationResult compile(ResolvedJavaMethod method, StructuredGraph graph) {
+        OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL;
+        return compiler.getCompiler().compileMethod(method, graph, -1, compiler.getCache(), compiler.getVMToCompiler().createPhasePlan(optimisticOpts), optimisticOpts);
+    }
+
+    @Override
+    public int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
+        final int actionShift = 0;
+        final int reasonShift = 3;
+
+        int actionValue = convertDeoptAction(action);
+        int reasonValue = convertDeoptReason(reason);
+        return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift)));
+    }
+
+    @Override
+    public int convertDeoptAction(DeoptimizationAction 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();
+        }
+    }
+
+    @Override
+    public int convertDeoptReason(DeoptimizationReason 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();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.java.*;
+
+/**
+ * Represents a method signature.
+ */
+public class HotSpotSignature extends CompilerObject implements Signature {
+
+    private static final long serialVersionUID = -2890917956072366116L;
+    private final List<String> arguments = new ArrayList<>();
+    private final String returnType;
+    private final String originalString;
+    private JavaType[] argumentTypes;
+    private JavaType returnTypeCache;
+
+    public HotSpotSignature(String signature) {
+        assert signature.length() > 0;
+        this.originalString = signature;
+
+        if (signature.charAt(0) == '(') {
+            int cur = 1;
+            while (cur < signature.length() && signature.charAt(cur) != ')') {
+                int nextCur = parseSignature(signature, cur);
+                arguments.add(signature.substring(cur, nextCur));
+                cur = nextCur;
+            }
+
+            cur++;
+            int nextCur = parseSignature(signature, cur);
+            returnType = signature.substring(cur, nextCur);
+            assert nextCur == signature.length();
+        } else {
+            returnType = null;
+        }
+    }
+
+    private static int parseSignature(String signature, int start) {
+        int cur = start;
+        char first;
+        do {
+            first = signature.charAt(cur++);
+        } while (first == '[');
+
+        switch (first) {
+            case 'L':
+                while (signature.charAt(cur) != ';') {
+                    cur++;
+                }
+                cur++;
+                break;
+            case 'V':
+            case 'I':
+            case 'B':
+            case 'C':
+            case 'D':
+            case 'F':
+            case 'J':
+            case 'S':
+            case 'Z':
+                break;
+            default:
+                assert false;
+        }
+        return cur;
+    }
+
+    @Override
+    public int argumentCount(boolean withReceiver) {
+        return arguments.size() + (withReceiver ? 1 : 0);
+    }
+
+    @Override
+    public Kind argumentKindAt(int index) {
+        return Kind.fromTypeString(arguments.get(index));
+    }
+
+    @Override
+    public int argumentSlots(boolean withReceiver) {
+        int argSlots = 0;
+        for (int i = 0; i < argumentCount(false); i++) {
+            argSlots += FrameStateBuilder.stackSlots(argumentKindAt(i));
+        }
+        return argSlots + (withReceiver ? 1 : 0);
+    }
+
+    @Override
+    public JavaType argumentTypeAt(int index, ResolvedJavaType accessingClass) {
+        if (argumentTypes == null) {
+            argumentTypes = new JavaType[arguments.size()];
+        }
+        JavaType type = argumentTypes[index];
+        if (type == null || !(type instanceof ResolvedJavaType)) {
+            type = HotSpotGraalRuntime.getInstance().lookupType(arguments.get(index), (HotSpotResolvedJavaType) accessingClass, true);
+            argumentTypes[index] = type;
+        }
+        return type;
+    }
+
+    @Override
+    public String asString() {
+        return originalString;
+    }
+
+    @Override
+    public Kind returnKind() {
+        return Kind.fromTypeString(returnType);
+    }
+
+    @Override
+    public JavaType returnType(JavaType accessingClass) {
+        if (returnTypeCache == null) {
+            returnTypeCache = HotSpotGraalRuntime.getInstance().lookupType(returnType, (HotSpotResolvedJavaType) accessingClass, false);
+        }
+        return returnTypeCache;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotSignature<" + originalString + ">";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of RiType for primitive HotSpot types.
+ */
+public final class HotSpotTypePrimitive extends HotSpotJavaType implements ResolvedJavaType {
+
+    private static final long serialVersionUID = -6208552348908071473L;
+    private Kind kind;
+    private final HotSpotKlassOop klassOop;
+
+    public HotSpotTypePrimitive(Kind kind) {
+        this.kind = kind;
+        this.name = String.valueOf(Character.toUpperCase(kind.typeChar));
+        this.klassOop = new HotSpotKlassOop(this);
+    }
+
+    @Override
+    public int accessFlags() {
+        assert kind != null && kind.toJavaClass() != null;
+        return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
+    }
+
+    @Override
+    public ResolvedJavaType arrayOf() {
+        return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrimitiveArrayType(kind);
+    }
+
+    @Override
+    public ResolvedJavaType componentType() {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaType exactType() {
+        return this;
+    }
+
+    @Override
+    public ResolvedJavaType superType() {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaType leastCommonAncestor(ResolvedJavaType otherType) {
+        return null;
+    }
+
+    @Override
+    public Constant getEncoding(Representation r) {
+        throw GraalInternalError.unimplemented("HotSpotTypePrimitive.getEncoding");
+    }
+
+    @Override
+    public Kind getRepresentationKind(Representation r) {
+        return kind;
+    }
+
+    @Override
+    public boolean hasFinalizableSubclass() {
+        return false;
+    }
+
+    @Override
+    public boolean hasFinalizer() {
+        return false;
+    }
+
+    @Override
+    public boolean isArrayClass() {
+        return false;
+    }
+
+    @Override
+    public boolean isInitialized() {
+        return true;
+    }
+
+    @Override
+    public boolean isInstance(Constant obj) {
+        return false;
+    }
+
+    @Override
+    public boolean isInstanceClass() {
+        return false;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return false;
+    }
+
+    @Override
+    public boolean isSubtypeOf(ResolvedJavaType other) {
+        return false;
+    }
+
+    @Override
+    public Kind kind() {
+        return kind;
+    }
+
+    @Override
+    public ResolvedJavaMethod resolveMethodImpl(ResolvedJavaMethod method) {
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotTypePrimitive<" + kind + ">";
+    }
+
+    @Override
+    public ResolvedJavaType uniqueConcreteSubtype() {
+        return this;
+    }
+
+    @Override
+    public ResolvedJavaMethod uniqueConcreteMethod(ResolvedJavaMethod method) {
+        return null;
+    }
+
+    @Override
+    public ResolvedJavaField[] declaredFields() {
+        return null;
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return toJava().getAnnotation(annotationClass);
+    }
+
+    @Override
+    public Class< ? > toJava() {
+        return kind.toJavaClass();
+    }
+
+    @Override
+    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+        return this;
+    }
+
+    @Override
+    public HotSpotKlassOop klassOop() {
+        return klassOop;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * Implementation of RiType for unresolved HotSpot classes.
+ */
+public class HotSpotTypeUnresolved extends HotSpotJavaType {
+
+    private static final long serialVersionUID = -2320936267633521314L;
+    public final String simpleName;
+    public final int dimensions;
+
+    /**
+     * Creates a new unresolved type for a specified type descriptor.
+     */
+    public HotSpotTypeUnresolved(String name) {
+        assert name.length() > 0 : "name cannot be empty";
+
+        int dims = 0;
+        int startIndex = 0;
+        while (name.charAt(startIndex) == '[') {
+            startIndex++;
+            dims++;
+        }
+
+        // Decode name if necessary.
+        if (name.charAt(name.length() - 1) == ';') {
+            assert name.charAt(startIndex) == 'L';
+            this.simpleName = name.substring(startIndex + 1, name.length() - 1);
+            this.name = name;
+        } else {
+            this.simpleName = name;
+            this.name = getFullName(name, dims);
+        }
+
+        this.dimensions = dims;
+    }
+
+    public HotSpotTypeUnresolved(String name, int dimensions) {
+        assert dimensions >= 0;
+        this.simpleName = name;
+        this.dimensions = dimensions;
+        this.name = getFullName(name, dimensions);
+    }
+
+    private static String getFullName(String name, int dimensions) {
+        StringBuilder str = new StringBuilder(name.length() + dimensions + 2);
+        for (int i = 0; i < dimensions; i++) {
+            str.append('[');
+        }
+        str.append('L').append(name).append(';');
+        return str.toString();
+    }
+
+    @Override
+    public JavaType componentType() {
+        assert dimensions > 0 : "no array class" + name();
+        return new HotSpotTypeUnresolved(simpleName, dimensions - 1);
+    }
+
+    @Override
+    public JavaType arrayOf() {
+        return new HotSpotTypeUnresolved(simpleName, dimensions + 1);
+    }
+
+    @Override
+    public Kind kind() {
+        return Kind.Object;
+    }
+
+    @Override
+    public int hashCode() {
+        return simpleName.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return o == this;
+    }
+
+    @Override
+    public String toString() {
+        return "HotSpotType<" + simpleName + ", unresolved>";
+    }
+
+    @Override
+    public Kind getRepresentationKind(JavaType.Representation r) {
+        return Kind.Object;
+    }
+
+    @Override
+    public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
+        return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().lookupType(name, (HotSpotResolvedJavaType) accessingClass, true);
+    }
+
+    @Override
+    public HotSpotKlassOop klassOop() {
+        throw GraalInternalError.shouldNotReachHere("HotSpotTypeUnresolved.klassOop");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotXirGenerator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,1050 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.hotspot.meta.TemplateFlag.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Address.*;
+import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.cri.xir.*;
+import com.oracle.max.cri.xir.CiXirAssembler.XirConstant;
+import com.oracle.max.cri.xir.CiXirAssembler.XirLabel;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.max.cri.xir.CiXirAssembler.XirOperand;
+import com.oracle.max.cri.xir.CiXirAssembler.XirParameter;
+import com.oracle.max.criutils.*;
+
+public class HotSpotXirGenerator implements RiXirGenerator {
+
+    // this needs to correspond to graal_CodeInstaller.hpp
+    // @formatter:off
+    public static final Integer MARK_VERIFIED_ENTRY            = 0x0001;
+    public static final Integer MARK_UNVERIFIED_ENTRY          = 0x0002;
+    public static final Integer MARK_OSR_ENTRY                 = 0x0003;
+    public static final Integer MARK_UNWIND_ENTRY              = 0x0004;
+    public static final Integer MARK_EXCEPTION_HANDLER_ENTRY   = 0x0005;
+    public static final Integer MARK_DEOPT_HANDLER_ENTRY       = 0x0006;
+
+    public static final Integer MARK_STATIC_CALL_STUB          = 0x1000;
+
+    public static final Integer MARK_INVOKEINTERFACE           = 0x2001;
+    public static final Integer MARK_INVOKESTATIC              = 0x2002;
+    public static final Integer MARK_INVOKESPECIAL             = 0x2003;
+    public static final Integer MARK_INVOKEVIRTUAL             = 0x2004;
+
+    public static final Integer MARK_IMPLICIT_NULL             = 0x3000;
+    public static final Integer MARK_POLL_NEAR                 = 0x3001;
+    public static final Integer MARK_POLL_RETURN_NEAR          = 0x3002;
+    public static final Integer MARK_POLL_FAR                  = 0x3003;
+    public static final Integer MARK_POLL_RETURN_FAR           = 0x3004;
+
+    // @formatter:on
+
+    private final HotSpotVMConfig config;
+    private final TargetDescription target;
+    private final RegisterConfig registerConfig;
+    private final HotSpotGraalRuntime compiler;
+
+
+    private CiXirAssembler globalAsm;
+
+    public HotSpotXirGenerator(HotSpotVMConfig config, TargetDescription target, RegisterConfig registerConfig, HotSpotGraalRuntime compiler) {
+        this.config = config;
+        this.target = target;
+        this.registerConfig = registerConfig;
+        this.compiler = compiler;
+    }
+
+    private XirConstant wordConst(CiXirAssembler asm, long value) {
+        if (target.wordKind == Kind.Long) {
+            return asm.createConstant(Constant.forLong(value));
+        } else {
+            assert target.wordKind == Kind.Int;
+            return asm.createConstant(Constant.forInt((int) value));
+        }
+    }
+
+    private XirArgument wordArg(long value) {
+        if (target.wordKind == Kind.Long) {
+            return XirArgument.forLong(value);
+        } else {
+            assert target.wordKind == Kind.Int;
+            return XirArgument.forInt((int) value);
+        }
+    }
+
+    private SimpleTemplates invokeInterfaceTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter receiver = asm.createInputParameter("receiver", Kind.Object);
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
+            XirOperand tempO = asm.createRegister("tempO", Kind.Object, AMD64.rax);
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, temp, receiver, true);
+            }
+            asm.mark(MARK_INVOKEINTERFACE);
+            asm.mov(tempO, asm.createConstant(Constant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
+
+            return asm.finishTemplate(addr, "invokeinterface");
+        }
+    };
+
+    private SimpleTemplates invokeVirtualTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter receiver = asm.createInputParameter("receiver", Kind.Object);
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
+            XirOperand tempO = asm.createRegister("tempO", Kind.Object, AMD64.rax);
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, temp, receiver, true);
+            }
+            asm.mark(MARK_INVOKEVIRTUAL);
+            asm.mov(tempO, asm.createConstant(Constant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
+
+            return asm.finishTemplate(addr, "invokevirtual");
+        }
+    };
+
+    private IndexTemplates inlinedInvokeVirtualTemplates = new IndexTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int vtableEntryOffset) {
+            asm.restart();
+            XirParameter receiver = asm.createInputParameter("receiver", Kind.Object);
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
+            XirOperand method = asm.createRegisterTemp("method", Kind.Object, AMD64.rbx);
+
+            // load class from receiver
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+            }
+            asm.pload(target.wordKind, temp, receiver, asm.i(config.hubOffset), true);
+            // load vtable entry
+            asm.pload(target.wordKind, method, temp, asm.i(vtableEntryOffset), false);
+            // load entry point from methodOop
+            asm.mark(MARK_IMPLICIT_NULL);
+            asm.pload(target.wordKind, temp, method, asm.i(config.methodCompiledEntryOffset), true);
+            asm.mark(MARK_INVOKEVIRTUAL);
+
+            return asm.finishTemplate(temp, "invokevirtual");
+        }
+    };
+
+    private SimpleTemplates invokeSpecialTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter receiver = asm.createInputParameter("receiver", Kind.Object);
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
+            XirLabel stub = asm.createOutOfLineLabel("call stub");
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, temp, receiver, true);
+            }
+            asm.mark(MARK_INVOKESPECIAL);
+
+            // -- out of line -------------------------------------------------------
+            asm.bindOutOfLine(stub);
+            XirOperand method = asm.createRegisterTemp("method", target.wordKind, AMD64.rbx);
+            asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
+            asm.mov(method, wordConst(asm, 0));
+            XirLabel dummy = asm.createOutOfLineLabel("dummy");
+            asm.jmp(dummy);
+            asm.bindOutOfLine(dummy);
+
+            return asm.finishTemplate(addr, "invokespecial");
+        }
+    };
+
+    private SimpleTemplates invokeStaticTemplates = new SimpleTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart();
+            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
+
+            XirLabel stub = asm.createOutOfLineLabel("call stub");
+            asm.mark(MARK_INVOKESTATIC);
+
+            // -- out of line -------------------------------------------------------
+            asm.bindOutOfLine(stub);
+            XirOperand method = asm.createRegisterTemp("method", target.wordKind, AMD64.rbx);
+            asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
+            asm.mov(method, wordConst(asm, 0));
+            XirLabel dummy = asm.createOutOfLineLabel("dummy");
+            asm.jmp(dummy);
+            asm.bindOutOfLine(dummy);
+
+            return asm.finishTemplate(addr, "invokestatic");
+        }
+    };
+
+    private SimpleTemplates monitorEnterTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart(Kind.Void);
+            XirParameter object = asm.createInputParameter("object", Kind.Object);
+            XirParameter lock = asm.createInputParameter("lock", target.wordKind);
+
+            if (is(NULL_CHECK, flags)) {
+                asm.mark(MARK_IMPLICIT_NULL);
+                asm.pload(target.wordKind, asm.createTemp("temp", target.wordKind), object, true);
+            }
+
+
+            // (thomaswue) It is important to use for this runtime call the debug info AFTER the monitor enter. Otherwise the monitor object
+            // is not correctly garbage collected.
+            final boolean useInfoAfter = true;
+
+            if (config.useFastLocking) {
+                useRegisters(asm, AMD64.rax, AMD64.rbx);
+                useRegisters(asm, getGeneralParameterRegister(0));
+                useRegisters(asm, getGeneralParameterRegister(1));
+                asm.callRuntime(config.fastMonitorEnterStub, null, useInfoAfter, object, lock);
+            } else {
+                asm.reserveOutgoingStack(target.wordSize * 2);
+                XirOperand rsp = asm.createRegister("rsp", target.wordKind, asRegister(AMD64.RSP));
+                asm.pstore(Kind.Object, rsp, asm.i(target.wordSize), object, false);
+                asm.pstore(target.wordKind, rsp, asm.i(0), lock, false);
+                asm.callRuntime(config.monitorEnterStub, null, useInfoAfter);
+            }
+
+            return asm.finishTemplate("monitorEnter");
+        }
+    };
+
+    private Register getGeneralParameterRegister(int index) {
+        return registerConfig.getCallingConventionRegisters(CallingConvention.Type.RuntimeCall, RegisterFlag.CPU)[index];
+    }
+
+    private SimpleTemplates monitorExitTemplates = new SimpleTemplates(NULL_CHECK) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            asm.restart(Kind.Void);
+            XirParameter object = asm.createInputParameter("object", Kind.Object);
+            XirParameter lock = asm.createInputParameter("lock", target.wordKind);
+
+            if (config.useFastLocking) {
+                useRegisters(asm, AMD64.rax, AMD64.rbx);
+                useRegisters(asm, getGeneralParameterRegister(0));
+                useRegisters(asm, getGeneralParameterRegister(1));
+                asm.callRuntime(config.fastMonitorExitStub, null, object, lock);
+            } else {
+                asm.reserveOutgoingStack(target.wordSize);
+                asm.pstore(target.wordKind, asm.createRegister("rsp", target.wordKind, asRegister(AMD64.RSP)), asm.i(0), lock, false);
+                asm.callRuntime(config.monitorExitStub, null);
+            }
+
+            return asm.finishTemplate("monitorExit");
+        }
+    };
+
+    private final IndexTemplates newInstanceTemplates = new IndexTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int size) {
+            XirOperand result = asm.restart(target.wordKind);
+            XirOperand hub = asm.createInputParameter("hub", Kind.Object);
+
+            XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx);
+            XirOperand temp1o = asm.createRegister("temp1o", Kind.Object, AMD64.rcx);
+            XirOperand temp2 = asm.createRegisterTemp("temp2", target.wordKind, AMD64.rbx);
+            XirOperand temp2i = asm.createRegister("temp2i", Kind.Int, AMD64.rbx);
+            useRegisters(asm, AMD64.rsi);
+            XirLabel tlabFull = asm.createOutOfLineLabel("tlab full");
+            XirLabel resume = asm.createInlineLabel("resume");
+
+            // check if the class is already initialized
+            asm.pload(Kind.Int, temp2i, hub, asm.i(config.klassStateOffset), false);
+            asm.jneq(tlabFull, temp2i, asm.i(config.klassStateFullyInitialized));
+
+            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
+            asm.pload(target.wordKind, result, thread, asm.i(config.threadTlabTopOffset), false);
+            asm.add(temp1, result, wordConst(asm, size));
+            asm.pload(target.wordKind, temp2, thread, asm.i(config.threadTlabEndOffset), false);
+
+            asm.jgt(tlabFull, temp1, temp2);
+            asm.pstore(target.wordKind, thread, asm.i(config.threadTlabTopOffset), temp1, false);
+
+            asm.bindInline(resume);
+
+            asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false);
+            asm.pstore(target.wordKind, result, temp1, false);
+            asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory
+            asm.pstore(Kind.Object, result, asm.i(config.hubOffset), temp1o, false);
+
+            if (size > 2 * target.wordSize) {
+                asm.mov(temp1, wordConst(asm, 0));
+                for (int offset = 2 * target.wordSize; offset < size; offset += target.wordSize) {
+                    asm.pstore(target.wordKind, result, asm.i(offset), temp1, false);
+                }
+            }
+
+            // -- out of line -------------------------------------------------------
+            asm.bindOutOfLine(tlabFull);
+            XirOperand arg = asm.createRegisterTemp("runtime call argument", Kind.Object, AMD64.rdx);
+            asm.mov(arg, hub);
+            useRegisters(asm, AMD64.rax);
+            asm.callRuntime(config.newInstanceStub, result);
+            asm.jmp(resume);
+
+            return asm.finishTemplate("new instance");
+        }
+    };
+
+    private SimpleTemplates newObjectArrayTemplates = new SimpleTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags) {
+            emitNewTypeArray(asm, Kind.Object, config.useFastNewObjectArray, config.newObjectArrayStub);
+            return asm.finishTemplate("newObjectArray");
+        }
+    };
+
+    private void emitNewTypeArray(CiXirAssembler asm, Kind kind, boolean useFast, long slowPathStub) {
+        XirOperand result = asm.restart(target.wordKind);
+
+        XirParameter lengthParam = asm.createInputParameter("length", Kind.Int, true);
+
+        XirOperand length = asm.createRegisterTemp("length", Kind.Int, AMD64.rbx);
+        XirOperand hub = asm.createRegisterTemp("hub", Kind.Object, AMD64.rdx);
+
+        // Registers rsi, rcx, rdi, and rax are needed by the runtime call.
+        // Hub needs to be on rdx, length on rbx.
+        XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx);
+        XirOperand temp1o = asm.createRegister("temp1o", Kind.Object, AMD64.rcx);
+        XirOperand temp2 = asm.createRegisterTemp("temp2", target.wordKind, AMD64.rax);
+        XirOperand temp3 = asm.createRegisterTemp("temp3", target.wordKind, AMD64.rdi);
+        XirOperand size = asm.createRegisterTemp("size", Kind.Int, AMD64.rsi);
+
+        asm.mov(hub, asm.createConstantInputParameter("hub", Kind.Object));
+        asm.mov(length, lengthParam);
+
+        if (useFast) {
+
+            XirLabel slowPath = asm.createOutOfLineLabel("slowPath");
+
+            XirLabel done = asm.createInlineLabel("done");
+
+            // Check for negative array size.
+            // TODO: Also check for upper bound
+            asm.jlt(slowPath, length, asm.i(0));
+
+            final int aligning = target.wordSize;
+            final int arrayLengthOffset = target.wordSize * 2;
+            final int arrayElementOffset = config.getArrayOffset(kind);
+
+            // Calculate aligned size
+            asm.mov(size, length);
+            int scale = CodeUtil.log2(target.sizeInBytes(kind));
+            if (scale != 0) {
+                asm.shl(size, size, asm.i(scale));
+            }
+            asm.add(size, size, asm.i(arrayElementOffset + aligning - 1));
+            long mask = 0xFFFFFFFFL;
+            mask <<= CodeUtil.log2(aligning);
+            asm.and(size, size, asm.i((int) mask));
+
+            // Try tlab allocation
+            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
+            asm.pload(target.wordKind, result, thread, asm.i(config.threadTlabTopOffset), false);
+            asm.add(temp1, result, size);
+            asm.pload(target.wordKind, temp2, thread, asm.i(config.threadTlabEndOffset), false);
+            asm.jgt(slowPath, temp1, temp2);
+            asm.pstore(target.wordKind, thread, asm.i(config.threadTlabTopOffset), temp1, false);
+
+            // Now the new object is in result, store mark word and klass
+            asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false);
+            asm.pstore(target.wordKind, result, temp1, false);
+            asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory
+            asm.pstore(Kind.Object, result, asm.i(config.hubOffset), temp1o, false);
+
+            // Store array length
+            asm.pstore(Kind.Int, result, asm.i(arrayLengthOffset), length, false);
+
+            // Initialize with 0
+            XirLabel top = asm.createInlineLabel("top");
+            asm.sub(size, size, asm.i(arrayElementOffset));
+            asm.shr(size, size, asm.i(Scale.Times8.log2));
+            asm.jeq(done, size, asm.i(0));
+            asm.xor(temp3, temp3, temp3);
+            asm.bindInline(top);
+            asm.pstore(target.wordKind, result, size, temp3, arrayElementOffset - target.wordSize, Scale.Times8, false);
+            asm.decAndJumpNotZero(top, size);
+
+            asm.bindInline(done);
+
+            // Slow path
+            asm.bindOutOfLine(slowPath);
+            asm.callRuntime(slowPathStub, result);
+            asm.jmp(done);
+        } else {
+            asm.callRuntime(slowPathStub, result);
+        }
+    }
+
+    private KindTemplates newTypeArrayTemplates = new KindTemplates() {
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, Kind kind) {
+            emitNewTypeArray(asm, kind, config.useFastNewTypeArray, config.newTypeArrayStub);
+            return asm.finishTemplate("newTypeArray<" + kind.toString() + ">");
+        }
+    };
+
+    private final IndexTemplates multiNewArrayTemplate = new IndexTemplates() {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int dimensions) {
+            XirOperand result = asm.restart(Kind.Object);
+
+            XirOperand hub = asm.createRegisterTemp("hub", Kind.Object, AMD64.rax);
+            XirOperand rank = asm.createRegisterTemp("rank", Kind.Int, AMD64.rbx);
+            XirOperand sizes = asm.createRegisterTemp("sizes", Kind.Long, AMD64.rcx);
+            XirOperand thread = asm.createRegisterTemp("thread", Kind.Long, AMD64.r15);
+            asm.add(sizes, thread, asm.l(config.threadMultiNewArrayStorage));
+            for (int i = 0; i < dimensions; i++) {
+                XirParameter length = asm.createInputParameter("length" + i, Kind.Int, true);
+                asm.pstore(Kind.Int, sizes, asm.i(i * target.sizeInBytes(Kind.Int)), length, false);
+            }
+
+            asm.mov(hub, asm.createConstantInputParameter("hub", Kind.Object));
+
+            asm.mov(rank, asm.i(dimensions));
+            // not necessary because we already have a temp in rax:  useRegisters(asm, AMD64.rax);
+            asm.callRuntime(config.newMultiArrayStub, result);
+            return asm.finishTemplate("multiNewArray" + dimensions);
+        }
+    };
+
+    enum CheckcastCounter {
+        hintsHit("hit a hint type"),
+        hintsMissed("missed the hint types"),
+        exact("tested type is (statically) final"),
+        noHints_class("profile information is not used (test type is a class)"),
+        noHints_iface("profile information is not used (test type is an interface)"),
+        noHints_unknown("test type is not a compile-time constant"),
+        isNull("object tested is null"),
+        exception("type test failed with a ClassCastException");
+
+        public final String desc;
+
+        private CheckcastCounter(String desc) {
+            this.desc = desc;
+        }
+
+        static final CheckcastCounter[] VALUES = values();
+    }
+
+    private static final long[] checkcastCounters = new long[CheckcastCounter.VALUES.length];
+
+    private IndexTemplates checkCastTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
+
+        private void incCounter(CiXirAssembler asm, XirOperand counter, XirParameter counters, CheckcastCounter offset) {
+            int disp = Unsafe.getUnsafe().arrayBaseOffset(long[].class);
+            Scale scale = Scale.fromInt(Unsafe.getUnsafe().arrayIndexScale(long[].class));
+            XirConstant index = asm.i(offset.ordinal());
+            asm.pload(Kind.Long, counter, counters, index, disp, scale, false);
+            asm.add(counter, counter, asm.i(1));
+            asm.pstore(Kind.Long, counters, index, counter, disp, scale, false);
+        }
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
+            asm.restart(Kind.Void);
+            boolean exact = is(EXACT_HINTS, flags);
+            XirParameter counters = GraalOptions.CheckcastCounters ? asm.createConstantInputParameter("counters", Kind.Object) : null;
+            XirParameter object = asm.createInputParameter("object", Kind.Object);
+            final XirOperand hub = exact ? null : asm.createConstantInputParameter("hub", Kind.Object);
+
+            XirOperand objHub = asm.createTemp("objHub", Kind.Object);
+            XirOperand counter = counters != null ? asm.createTemp("counter", Kind.Long) : null;
+
+            XirLabel success = asm.createInlineLabel("success");
+            XirLabel slowPath = asm.createOutOfLineLabel("slow path");
+
+            if (is(NULL_CHECK, flags)) {
+                // null can be cast to anything
+                if (counters != null) {
+                    XirLabel isNotNull = asm.createInlineLabel("isNull");
+                    asm.jneq(isNotNull, object, asm.o(null));
+                    incCounter(asm, counter, counters, CheckcastCounter.isNull);
+                    asm.jmp(success);
+                    asm.bindInline(isNotNull);
+                } else {
+                    asm.jeq(success, object, asm.o(null));
+                }
+
+            }
+
+            asm.pload(Kind.Object, objHub, object, asm.i(config.hubOffset), false);
+            if (hintCount == 0) {
+                assert !exact;
+                if (counters != null) {
+                    CheckcastCounter cc;
+                    if (is(NULL_TYPE, flags)) {
+                        cc = CheckcastCounter.noHints_unknown;
+                    } else if (is(INTERFACE_TYPE, flags)) {
+                        cc = CheckcastCounter.noHints_iface;
+                    } else {
+                        cc = CheckcastCounter.noHints_class;
+                    }
+                    incCounter(asm, counter, counters, cc);
+                }
+
+                checkSubtype(asm, objHub, objHub, hub);
+                asm.jeq(slowPath, objHub, asm.o(null));
+                asm.bindInline(success);
+
+                // -- out of line -------------------------------------------------------
+                asm.bindOutOfLine(slowPath);
+            } else {
+                XirLabel hintsSuccess = counters == null ? success : asm.createInlineLabel("hintsSuccess");
+                XirOperand scratchObject = asm.createRegisterTemp("scratch", Kind.Object, AMD64.r10);
+                // if we get an exact match: succeed immediately
+                for (int i = 0; i < hintCount; i++) {
+                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, Kind.Object);
+                    asm.mov(scratchObject, hintHub);
+                    if (i < hintCount - 1) {
+                        asm.jeq(hintsSuccess, objHub, scratchObject);
+                    } else {
+                        asm.jneq(slowPath, objHub, scratchObject);
+                    }
+                }
+
+                if (counters != null) {
+                    asm.bindInline(hintsSuccess);
+                    incCounter(asm, counter, counters, exact ? CheckcastCounter.exact : CheckcastCounter.hintsHit);
+                }
+
+                asm.bindInline(success);
+
+                // -- out of line -------------------------------------------------------
+                asm.bindOutOfLine(slowPath);
+                if (!exact) {
+                    if (counters != null) {
+                        incCounter(asm, counter, counters, CheckcastCounter.hintsMissed);
+                    }
+                    checkSubtype(asm, objHub, objHub, hub);
+                    asm.jneq(success, objHub, asm.o(null));
+                }
+            }
+
+            if (counters != null) {
+                incCounter(asm, counter, counters, CheckcastCounter.exception);
+            }
+            DeoptimizationReason deoptReason = exact ? DeoptimizationReason.OptimizedTypeCheckViolated : DeoptimizationReason.ClassCastException;
+            XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10);
+            asm.mov(scratch, wordConst(asm, compiler.getRuntime().encodeDeoptActionAndReason(DeoptimizationAction.InvalidateReprofile, deoptReason)));
+            asm.callRuntime(RuntimeCall.Deoptimize, null);
+            asm.shouldNotReachHere();
+
+            return asm.finishTemplate("checkcast");
+        }
+    };
+
+    private IndexTemplates instanceOfTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
+            asm.restart(Kind.Void);
+            XirParameter object = asm.createInputParameter("object", Kind.Object);
+            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", Kind.Object);
+
+            XirOperand objHub = asm.createTemp("objHub", Kind.Object);
+
+            XirLabel trueSucc = asm.createInlineLabel(XirLabel.TrueSuccessor);
+            XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor);
+
+            if (is(NULL_CHECK, flags)) {
+                // null isn't "instanceof" anything
+                asm.jeq(falseSucc, object, asm.o(null));
+            }
+
+            asm.pload(Kind.Object, objHub, object, asm.i(config.hubOffset), false);
+            if (hintCount == 0) {
+                assert !is(EXACT_HINTS, flags);
+                checkSubtype(asm, objHub, objHub, hub);
+                asm.jeq(falseSucc, objHub, asm.o(null));
+                asm.jmp(trueSucc);
+            } else {
+                XirLabel slowPath = null;
+                XirOperand scratchObject = asm.createRegisterTemp("scratch", Kind.Object, AMD64.r10);
+
+                // if we get an exact match: succeed immediately
+                for (int i = 0; i < hintCount; i++) {
+                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, Kind.Object);
+                    asm.mov(scratchObject, hintHub);
+                    if (i < hintCount - 1) {
+                        asm.jeq(trueSucc, objHub, scratchObject);
+                    } else {
+                        if (is(EXACT_HINTS, flags)) {
+                            asm.jneq(falseSucc, objHub, scratchObject);
+                            asm.jmp(trueSucc);
+                        } else {
+                            slowPath = asm.createOutOfLineLabel("slow path");
+                            asm.jneq(slowPath, objHub, scratchObject);
+                            asm.jmp(trueSucc);
+                        }
+                    }
+                }
+
+                // -- out of line -------------------------------------------------------
+                if (slowPath != null) {
+                    asm.bindOutOfLine(slowPath);
+                    checkSubtype(asm, objHub, objHub, hub);
+                    asm.jeq(falseSucc, objHub, asm.o(null));
+                    asm.jmp(trueSucc);
+                }
+            }
+
+            return asm.finishTemplate("instanceof");
+        }
+    };
+
+    private IndexTemplates materializeInstanceOfTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
+
+        @Override
+        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
+            XirOperand result = asm.restart(Kind.Int);
+            XirParameter object = asm.createInputParameter("object", Kind.Object);
+            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", Kind.Object);
+            XirOperand trueValue = asm.createInputParameter("trueValue", Kind.Int);
+            XirOperand falseValue = asm.createInputParameter("falseValue", Kind.Int);
+
+            XirOperand objHub = asm.createTemp("objHub", Kind.Object);
+
+            XirLabel end = asm.createInlineLabel("end");
+            XirLabel falseSucc = asm.createInlineLabel("ko");
+
+            if (is(NULL_CHECK, flags)) {
+                // null isn't "instanceof" anything
+                asm.jeq(falseSucc, object, asm.o(null));
+            }
+
+            asm.pload(Kind.Object, objHub, object, asm.i(config.hubOffset), false);
+            asm.mov(result, trueValue);
+
+            if (hintCount == 0) {
+                assert !is(EXACT_HINTS, flags);
+                checkSubtype(asm, objHub, objHub, hub);
+                asm.jneq(end, objHub, asm.o(null));
+                asm.bindInline(falseSucc);
+                asm.mov(result, falseValue);
+                asm.bindInline(end);
+            } else {
+                XirLabel slowPath = null;
+                XirOperand scratchObject = asm.createRegisterTemp("scratch", Kind.Object, AMD64.r10);
+
+                // if we get an exact match: succeed immediately
+                for (int i = 0; i < hintCount; i++) {
+                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, Kind.Object);
+                    asm.mov(scratchObject, hintHub);
+                    if (i < hintCount - 1) {
+                        asm.jeq(end, objHub, scratchObject);
+                    } else {
+                        if (is(EXACT_HINTS, flags)) {
+                            asm.jeq(end, objHub, scratchObject);
+                        } else {
+                            slowPath = asm.createOutOfLineLabel("slow path");
+                            asm.jeq(end, objHub, scratchObject);
+                            asm.jmp(slowPath);
+                        }
+                    }
+                }
+                asm.bindInline(falseSucc);
+                asm.mov(result, falseValue);
+                asm.bindInline(end);
+
+                // -- out of line -------------------------------------------------------
+                if (slowPath != null) {
+                    asm.bindOutOfLine(slowPath);
+                    checkSubtype(asm, objHub, objHub, hub);
+                    asm.jeq(falseSucc, objHub, asm.o(null));
+                    asm.jmp(end);
+                }
+            }
+
+            return asm.finishTemplate("instanceof");
+        }
+    };
+
+    private SimpleTemplates typeCheckTemplates = new SimpleTemplates(NULL_CHECK) {
+       @Override
+       protected XirTemplate create(CiXirAssembler asm, long flags) {
+           asm.restart(Kind.Void);
+           XirParameter objHub = asm.createInputParameter("objectHub", Kind.Object);
+           XirOperand hub = asm.createConstantInputParameter("hub", Kind.Object);
+           XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor);
+
+           XirOperand checkHub = asm.createTemp("checkHub", Kind.Object);
+
+           if (is(NULL_CHECK, flags)) {
+               asm.mark(MARK_IMPLICIT_NULL);
+           }
+
+           asm.mov(checkHub, hub);
+           // if we get an exact match: continue.
+           asm.jneq(falseSucc, objHub, checkHub);
+
+           return asm.finishTemplate("typeCheck");
+       }
+    };
+
+    @Override
+    public XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, JavaMethod method) {
+        return new XirSnippet(invokeInterfaceTemplates.get(site), receiver, wordArg(0));
+    }
+
+    @Override
+    public XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, JavaMethod method, boolean megamorph) {
+        int vtableEntryOffset = 0;
+
+        if (GraalOptions.InlineVTableStubs && (GraalOptions.AlwaysInlineVTableStubs || megamorph)) {
+            HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
+            if (!hsMethod.holder().isInterface()) {
+                vtableEntryOffset = hsMethod.vtableEntryOffset();
+            }
+        }
+        if (vtableEntryOffset > 0) {
+            return new XirSnippet(inlinedInvokeVirtualTemplates.get(site, vtableEntryOffset), receiver);
+        } else {
+            return new XirSnippet(invokeVirtualTemplates.get(site), receiver, wordArg(0));
+        }
+    }
+
+    @Override
+    public XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, JavaMethod method) {
+        return new XirSnippet(invokeSpecialTemplates.get(site), receiver, wordArg(0));
+    }
+
+    @Override
+    public XirSnippet genInvokeStatic(XirSite site, JavaMethod method) {
+        return new XirSnippet(invokeStaticTemplates.get(site), wordArg(0));
+    }
+
+    @Override
+    public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress) {
+        return new XirSnippet(monitorEnterTemplates.get(site), receiver, lockAddress);
+    }
+
+    @Override
+    public XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress) {
+        return new XirSnippet(monitorExitTemplates.get(site), receiver, lockAddress);
+    }
+
+    @Override
+    public XirSnippet genNewInstance(XirSite site, JavaType type) {
+        HotSpotResolvedJavaType resolvedType = (HotSpotResolvedJavaType) type;
+        int instanceSize = resolvedType.instanceSize();
+        assert instanceSize >= 0;
+        return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(resolvedType.klassOop()));
+    }
+
+    @Override
+    public XirSnippet genNewArray(XirSite site, XirArgument length, Kind elementKind, JavaType componentType, JavaType arrayType) {
+        if (elementKind == Kind.Object) {
+            assert arrayType instanceof ResolvedJavaType;
+            return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(((HotSpotJavaType) arrayType).klassOop()));
+        } else {
+            assert arrayType == null;
+            JavaType primitiveArrayType = compiler.getCompilerToVM().getPrimitiveArrayType(elementKind);
+            return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(((HotSpotJavaType) primitiveArrayType).klassOop()));
+        }
+    }
+
+    @Override
+    public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, JavaType type) {
+        XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1);
+        params[lengths.length] = XirArgument.forObject(((HotSpotJavaType) type).klassOop());
+        return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length), params);
+    }
+
+    @Override
+    public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, ResolvedJavaType type, JavaTypeProfile profile) {
+        final boolean useCounters = GraalOptions.CheckcastCounters;
+        TypeCheckHints hints = new TypeCheckHints(type, profile, site.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints);
+        int hintsLength = hints.types.length;
+        if (hintsLength == 0) {
+            if (useCounters) {
+                if (type == null) {
+                    return new XirSnippet(checkCastTemplates.get(site, 0, NULL_TYPE), XirArgument.forObject(checkcastCounters), receiver, hub);
+                } else if (type.isInterface()) {
+                    return new XirSnippet(checkCastTemplates.get(site, 0, INTERFACE_TYPE), XirArgument.forObject(checkcastCounters), receiver, hub);
+                } else {
+                    return new XirSnippet(checkCastTemplates.get(site, 0), XirArgument.forObject(checkcastCounters), receiver, hub);
+                }
+            } else {
+                return new XirSnippet(checkCastTemplates.get(site, 0), receiver, hub);
+            }
+        } else {
+            XirArgument[] params = new XirArgument[(useCounters ? 1 : 0) + hintsLength + (hints.exact ? 1 : 2)];
+            int i = 0;
+            if (useCounters) {
+                params[i++] = XirArgument.forObject(checkcastCounters);
+            }
+            params[i++] = receiver;
+            if (!hints.exact) {
+                params[i++] = hub;
+            }
+            for (ResolvedJavaType hint : hints.types) {
+                params[i++] = XirArgument.forObject(((HotSpotJavaType) hint).klassOop());
+            }
+            XirTemplate template = hints.exact ? checkCastTemplates.get(site, hintsLength, EXACT_HINTS) : checkCastTemplates.get(site, hintsLength);
+            return new XirSnippet(template, params);
+        }
+    }
+
+    @Override
+    public XirSnippet genInstanceOf(XirSite site, XirArgument object, XirArgument hub, ResolvedJavaType type, JavaTypeProfile profile) {
+        TypeCheckHints hints = new TypeCheckHints(type, profile, site.assumptions(), GraalOptions.InstanceOfMinHintHitProbability, GraalOptions.InstanceOfMaxHints);
+        int hintsLength = hints.types.length;
+        if (hintsLength == 0) {
+            return new XirSnippet(instanceOfTemplates.get(site, 0), object, hub);
+        } else {
+            XirArgument[] params = new XirArgument[hintsLength + (hints.exact ? 1 : 2)];
+            int i = 0;
+            params[i++] = object;
+            if (!hints.exact) {
+                params[i++] = hub;
+            }
+            for (ResolvedJavaType hint : hints.types) {
+                params[i++] = XirArgument.forObject(((HotSpotJavaType) hint).klassOop());
+            }
+            XirTemplate template = hints.exact ? instanceOfTemplates.get(site, hintsLength, EXACT_HINTS) : instanceOfTemplates.get(site, hintsLength);
+            return new XirSnippet(template, params);
+        }
+    }
+
+    @Override
+    public XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument object, XirArgument hub, XirArgument trueValue, XirArgument falseValue, ResolvedJavaType type, JavaTypeProfile profile) {
+        TypeCheckHints hints = new TypeCheckHints(type, profile, site.assumptions(), GraalOptions.InstanceOfMinHintHitProbability, GraalOptions.InstanceOfMaxHints);
+        int hintsLength = hints.types.length;
+        if (hintsLength == 0) {
+            return new XirSnippet(materializeInstanceOfTemplates.get(site, 0), object, hub, trueValue, falseValue);
+        } else {
+            XirArgument[] params = new XirArgument[hintsLength + (hints.exact ? 3 : 4)];
+            int i = 0;
+            params[i++] = object;
+            if (!hints.exact) {
+                params[i++] = hub;
+            }
+            params[i++] = trueValue;
+            params[i++] = falseValue;
+            for (ResolvedJavaType hint : hints.types) {
+                params[i++] = XirArgument.forObject(((HotSpotJavaType) hint).klassOop());
+            }
+            XirTemplate template = hints.exact ? materializeInstanceOfTemplates.get(site, hintsLength, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hintsLength);
+            return new XirSnippet(template, params);
+        }
+    }
+
+    @Override
+    public XirSnippet genTypeBranch(XirSite site, XirArgument thisHub, XirArgument otherHub, JavaType type) {
+        assert type instanceof ResolvedJavaType;
+        return new XirSnippet(typeCheckTemplates.get(site), thisHub, otherHub);
+    }
+
+    @Override
+    public void initialize(CiXirAssembler asm) {
+        this.globalAsm = asm;
+    }
+
+    private void checkSubtype(CiXirAssembler asm, XirOperand result, XirOperand objHub, XirOperand hub) {
+        asm.push(objHub);
+        asm.push(hub);
+        asm.callRuntime(config.instanceofStub, null);
+        asm.pop(result);
+        asm.pop(result);
+    }
+
+    private static void useRegisters(CiXirAssembler asm, Register... registers) {
+        if (registers != null) {
+            for (Register register : registers) {
+                asm.createRegisterTemp("reg", Kind.Illegal, register);
+            }
+        }
+    }
+
+    public boolean is(TemplateFlag check, long flags) {
+        return (flags & check.bits()) == check.bits();
+    }
+
+    /**
+     * Base class for all the ondemand template generators. It is not normally subclassed directly, but through one of
+     * its subclasses (SimpleTemplates, KindTemplates, IndexTemplates).
+     */
+    private abstract class Templates {
+
+        private ConcurrentHashMap<Long, XirTemplate> templates = new ConcurrentHashMap<>();
+        private final long mask;
+
+        /**
+         * Each flag passed to this method will cause templates with and without it to be generated.
+         */
+        public Templates(TemplateFlag... flags) {
+            this.mask = getBits((int) INDEX_MASK, null, flags);
+        }
+
+        protected abstract XirTemplate create(CiXirAssembler asm, long flags);
+
+        protected long getBits(int index, XirSite site, TemplateFlag... flags) {
+            long bits = index;
+            if (site != null) {
+                bits |= site.requiresNullCheck() ? NULL_CHECK.bits() : 0;
+                bits |= site.requiresReadBarrier() ? READ_BARRIER.bits() : 0;
+                bits |= site.requiresWriteBarrier() ? WRITE_BARRIER.bits() : 0;
+                bits |= site.requiresArrayStoreCheck() ? STORE_CHECK.bits() : 0;
+                bits |= site.requiresBoundsCheck() ? BOUNDS_CHECK.bits() : 0;
+            }
+            if (flags != null) {
+                for (TemplateFlag flag : flags) {
+                    bits |= flag.bits();
+                }
+            }
+            return bits;
+        }
+
+        protected XirTemplate getInternal(long flags) {
+            long maskedFlags = flags & mask;
+            XirTemplate template = templates.get(maskedFlags);
+            if (template == null) {
+                template = create(HotSpotXirGenerator.this.globalAsm.copy(), maskedFlags);
+                templates.put(maskedFlags, template);
+            }
+            return template;
+        }
+    }
+
+    private abstract class SimpleTemplates extends Templates {
+
+        public SimpleTemplates(TemplateFlag... flags) {
+            super(flags);
+        }
+
+        public XirTemplate get(XirSite site, TemplateFlag... flags) {
+            return getInternal(getBits(0, site, flags));
+        }
+    }
+
+    private abstract class IndexTemplates extends Templates {
+
+        public IndexTemplates(TemplateFlag... flags) {
+            super(flags);
+        }
+
+        @Override
+        protected final XirTemplate create(CiXirAssembler asm, long flags) {
+            return create(asm, flags & FLAGS_MASK, (int) (flags & INDEX_MASK));
+        }
+
+        protected abstract XirTemplate create(CiXirAssembler asm, long flags, int index);
+
+        public XirTemplate get(XirSite site, int size, TemplateFlag... flags) {
+            return getInternal(getBits(size, site, flags));
+        }
+    }
+
+    private abstract class KindTemplates extends Templates {
+
+        public KindTemplates(TemplateFlag... flags) {
+            super(flags);
+        }
+
+        @Override
+        protected final XirTemplate create(CiXirAssembler asm, long flags) {
+            return create(asm, flags & FLAGS_MASK, Kind.VALUES[(int) (flags & INDEX_MASK)]);
+        }
+
+        protected abstract XirTemplate create(CiXirAssembler asm, long flags, Kind kind);
+
+        public XirTemplate get(XirSite site, Kind kind, TemplateFlag... flags) {
+            return getInternal(getBits(kind.ordinal(), site, flags));
+        }
+    }
+
+    private static void printCounter(PrintStream out, CheckcastCounter name, long count, long total) {
+        double percent = total == 0D ? 0D : ((double) (count * 100)) / total;
+        out.println(String.format("%16s: %5.2f%%%10d  // %s", name, percent, count, name.desc));
+    }
+
+    public static  void printCheckcastCounters(PrintStream out) {
+        class Count implements Comparable<Count> {
+            long c;
+            CheckcastCounter name;
+            Count(long c, CheckcastCounter name) {
+                this.c = c;
+                this.name = name;
+            }
+            public int compareTo(Count o) {
+                return (int) (o.c - c);
+            }
+        }
+
+        long total = 0;
+        Count[] counters = new Count[checkcastCounters.length];
+        for (int i = 0; i < counters.length; i++) {
+            counters[i] = new Count(checkcastCounters[i], CheckcastCounter.VALUES[i]);
+            total += checkcastCounters[i];
+        }
+        Arrays.sort(counters);
+
+        out.println();
+        out.println("** XIR checkcast counters **");
+        for (Count c : counters) {
+            printCounter(out, c.name, c.c, total);
+        }
+    }
+
+    public static void printCounters(PrintStream out) {
+        if (GraalOptions.CheckcastCounters) {
+            printCheckcastCounters(out);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/TemplateFlag.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+enum TemplateFlag {
+    NULL_CHECK,
+    READ_BARRIER,
+    WRITE_BARRIER,
+    STORE_CHECK,
+    BOUNDS_CHECK,
+    GIVEN_LENGTH,
+    INPUTS_DIFFERENT,
+    INPUTS_SAME,
+    STATIC_METHOD,
+    SYNCHRONIZED,
+    INTERFACE_TYPE,
+    NULL_TYPE,
+    EXACT_HINTS;
+
+    private static final long FIRST_FLAG = 0x0000000100000000L;
+    public static final long FLAGS_MASK = 0x0000FFFF00000000L;
+    public static final long INDEX_MASK = 0x00000000FFFFFFFFL;
+
+    public long bits() {
+        assert ((FIRST_FLAG << ordinal()) & FLAGS_MASK) != 0;
+        return FIRST_FLAG << ordinal();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayWriteBarrier.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -47,7 +47,7 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        CiValue addr = gen.emitLea(gen.makeAddress(location(), object()));
+        Value addr = gen.emitLea(gen.makeAddress(location(), object()));
         generateBarrier(addr, gen);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CastFromHub.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.snippets.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * This node is used by the {@link NewInstanceSnippets} to give a formatted new instance its exact type.
+ */
+public final class CastFromHub extends FloatingNode implements Canonicalizable {
+
+    @Input private ValueNode object;
+    @Input private ValueNode hub;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public CastFromHub(ValueNode object, ValueNode hubObject) {
+        // TODO: the non-nullness should really be derived from 'object' but until
+        // control flow sensitive type analysis is implemented, the object coming
+        // from the TLAB fast path is not non-null
+        super(StampFactory.objectNonNull());
+        this.object = object;
+        this.hub = hubObject;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (hub.isConstant()) {
+            ResolvedJavaType type = ((HotSpotKlassOop) this.hub.asConstant().asObject()).type;
+            return graph().unique(new UnsafeCastNode(object, type, true, true));
+        }
+        return this;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <T> T castFromHub(Object object, Object hub) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,7 +23,8 @@
 package com.oracle.graal.hotspot.nodes;
 
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -32,19 +33,19 @@
 
     private int threadObjectOffset;
 
-    public CurrentThread(int threadObjectOffset) {
-        super(StampFactory.forKind(CiKind.Object));
+    public CurrentThread(int threadObjectOffset, CodeCacheProvider runtime) {
+        super(StampFactory.declaredNonNull(runtime.getResolvedJavaType(Thread.class)));
         this.threadObjectOffset = threadObjectOffset;
     }
 
     @Override
     public void generate(LIRGeneratorTool generator) {
-        generator.setResult(this, generator.emitLoad(new CiAddress(CiKind.Object, AMD64.r15.asValue(generator.target().wordKind), threadObjectOffset), false));
+        generator.setResult(this, generator.emitLoad(new Address(Kind.Object, AMD64.r15.asValue(generator.target().wordKind), threadObjectOffset), false));
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static Object get(int threadObjectOffset) {
+    public static Object get(@ConstantNodeParameter int threadObjectOffset) {
         throw new UnsupportedOperationException();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/FieldWriteBarrier.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -40,7 +40,7 @@
 
     @Override
     public void generate(LIRGeneratorTool generator) {
-        CiValue obj = generator.newVariable(generator.target().wordKind);
+        Value obj = generator.newVariable(generator.target().wordKind);
         generator.emitMove(generator.operand(object()), obj);
         generateBarrier(obj, generator);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,66 @@
+/*
+ * 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.hotspot.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Initializes the header and body of an uninitialized object cell.
+ * This node calls out to a stub to do both the allocation and formatting
+ * if the memory address it is given is zero/null (e.g. due to
+ * {@linkplain TLABAllocateNode TLAB allocation} failing).
+ */
+public final class InitializeNode extends FixedWithNextNode implements Lowerable {
+
+    @Input private final ValueNode memory;
+    private final ResolvedJavaType type;
+
+    public InitializeNode(ValueNode memory, ResolvedJavaType type) {
+        super(StampFactory.exactNonNull(type));
+        this.memory = memory;
+        this.type = type;
+    }
+
+    public ValueNode memory() {
+        return memory;
+    }
+
+    public ResolvedJavaType type() {
+        return type;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Object initialize(Object memory, @ConstantNodeParameter ResolvedJavaType type) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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.hotspot.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.max.asm.target.amd64.*;
+
+/**
+ * Node implementing a call to HotSpot's {@code new_instance} stub.
+ *
+ * @see AMD64NewInstanceStubCallOp
+ */
+public class NewInstanceStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+    private static final Stamp defaultStamp = StampFactory.objectNonNull();
+
+    @Input private final ValueNode hub;
+
+    public NewInstanceStubCall(ValueNode hub) {
+        super(defaultStamp);
+        this.hub = hub;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        if (stamp() == defaultStamp && hub.isConstant()) {
+            HotSpotKlassOop klassOop = (HotSpotKlassOop) this.hub.asConstant().asObject();
+            updateStamp(StampFactory.exactNonNull(klassOop.type));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        Variable result = gen.newVariable(Kind.Object);
+        gen.emitMove(gen.operand(hub), AMD64.rdx.asValue(Kind.Object));
+        LIRDebugInfo info = gen.state();
+        AMD64NewInstanceStubCallOp op = new AMD64NewInstanceStubCallOp(result, AMD64.rdx.asValue(Kind.Object), info);
+        gen.append(op);
+        gen.setResult(this, result);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Object call(Object hub) {
+        throw new UnsupportedOperationException();
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,80 @@
+/*
+ * 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.hotspot.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Access the value of a specific register.
+ */
+public final class RegisterNode extends FixedWithNextNode implements LIRLowerable {
+
+    private final Register register;
+
+    public RegisterNode(Register register, Kind kind) {
+        super(StampFactory.forKind(kind));
+        this.register = register;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        Value result;
+        if (generator.attributes(register).isAllocatable()) {
+            // The register allocator would prefer us not to tie up an allocatable
+            // register for the complete lifetime of this node.
+            result = generator.newVariable(kind());
+            generator.emitMove(register.asValue(kind()), result);
+        } else {
+            result = register.asValue(kind());
+        }
+        generator.setResult(this, result);
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(Verbosity.Name) + "%" + register;
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> properties = super.getDebugProperties();
+        properties.put("register", register.toString());
+        return properties;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <T> T register(@ConstantNodeParameter Register register, @ConstantNodeParameter Kind kind) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,62 @@
+/*
+ * 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.hotspot.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.*;
+
+/**
+ * Allocates some uninitialized area. This is used for TLAB allocation
+ * only. If allocation fails, zero/null is produced by this node.
+ */
+public final class TLABAllocateNode extends FixedWithNextNode implements Lowerable {
+
+    private final int size;
+
+    public TLABAllocateNode(int size, Kind wordKind) {
+        super(StampFactory.forWord(wordKind, true));
+        this.size = size;
+    }
+
+    public int size() {
+        return size;
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    /**
+     * @return null if allocation fails
+     */
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Word allocate(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,8 +25,8 @@
 import java.lang.reflect.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.target.amd64.*;
@@ -49,7 +49,7 @@
      * @param frameState the parameters will be taken from this FrameState
      */
     public TailcallNode(ValueNode target, FrameState frameState) {
-        super(StampFactory.illegal());
+        super(StampFactory.forVoid());
         this.target = target;
         this.frameState = frameState;
     }
@@ -57,20 +57,20 @@
     @Override
     public void generate(LIRGeneratorTool generator) {
         LIRGenerator gen = (LIRGenerator) generator;
-        HotSpotVMConfig config = CompilerImpl.getInstance().getConfig();
-        RiResolvedMethod method = frameState.method();
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        ResolvedJavaMethod method = frameState.method();
         boolean isStatic = Modifier.isStatic(method.accessFlags());
 
-        CiKind[] signature = CiUtil.signatureToKinds(method.signature(), isStatic ? null : method.holder().kind(true));
-        CiCallingConvention cc = gen.frameMap().registerConfig.getCallingConvention(CiCallingConvention.Type.JavaCall, signature, gen.target(), false);
-        gen.frameMap().callsMethod(cc, CiCallingConvention.Type.JavaCall); // TODO (aw): I think this is unnecessary for a tail call.
+        Kind[] signature = CodeUtil.signatureToKinds(method.signature(), isStatic ? null : method.holder().kind());
+        CallingConvention cc = gen.frameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, signature, gen.target(), false);
+        gen.frameMap().callsMethod(cc, CallingConvention.Type.JavaCall); // TODO (aw): I think this is unnecessary for a tail call.
         List<ValueNode> parameters = new ArrayList<>();
         for (int i = 0, slot = 0; i < cc.locations.length; i++, slot += FrameStateBuilder.stackSlots(frameState.localAt(slot).kind())) {
             parameters.add(frameState.localAt(slot));
         }
-        List<CiValue> argList = gen.visitInvokeArguments(cc, parameters);
+        List<Value> argList = gen.visitInvokeArguments(cc, parameters);
 
-        CiValue entry = gen.emitLoad(new CiAddress(CiKind.Long, gen.operand(target), config.nmethodEntryOffset), false);
+        Value entry = gen.emitLoad(new Address(Kind.Long, gen.operand(target), config.nmethodEntryOffset), false);
 
         gen.append(new AMD64TailcallOp(argList, entry, cc.locations));
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,58 @@
+/*
+ * 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.hotspot.nodes;
+
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.target.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Node implementing a call to HotSpot's object pointer verification stub.
+ *
+ * @see AMD64VerifyOopStubCallOp
+ */
+public class VerifyOopStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+    @Input private final ValueNode object;
+
+    public VerifyOopStubCall(ValueNode object) {
+        super(StampFactory.objectNonNull());
+        this.object = object;
+    }
+
+    @Override
+    public void generate(LIRGenerator gen) {
+        LIRDebugInfo info = gen.state();
+        AMD64VerifyOopStubCallOp op = new AMD64VerifyOopStubCallOp(gen.operand(object), info);
+        gen.append(op);
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Object call(Object object) {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -31,20 +32,20 @@
 public abstract class WriteBarrier extends FixedWithNextNode {
 
     public WriteBarrier() {
-        super(StampFactory.illegal());
+        super(StampFactory.forVoid());
     }
 
-    protected void generateBarrier(CiValue adr, LIRGeneratorTool gen) {
-        HotSpotVMConfig config = CompilerImpl.getInstance().getConfig();
-        CiValue base = gen.emitUShr(adr, CiConstant.forInt(config.cardtableShift));
+    protected void generateBarrier(Value adr, LIRGeneratorTool gen) {
+        HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
+        Value base = gen.emitUShr(adr, Constant.forInt(config.cardtableShift));
 
         long startAddress = config.cardtableStartAddress;
         int displacement = 0;
         if (((int) startAddress) == startAddress) {
             displacement = (int) startAddress;
         } else {
-            base = gen.emitAdd(base, CiConstant.forLong(config.cardtableStartAddress));
+            base = gen.emitAdd(base, Constant.forLong(config.cardtableStartAddress));
         }
-        gen.emitStore(new CiAddress(CiKind.Boolean, base, displacement), CiConstant.FALSE, false);
+        gen.emitStore(new Address(Kind.Boolean, base, displacement), Constant.FALSE, false);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCodeInfo.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-
-/**
- * Implementation of {@link RiCodeInfo} for HotSpot.
- */
-public class HotSpotCodeInfo extends CompilerObject implements RiCodeInfo {
-
-    private static final long serialVersionUID = -6766490427732498354L;
-
-    private long start;
-    private byte[] code;
-    public final CiTargetMethod targetMethod;
-    private HotSpotMethodResolved method;
-
-    public HotSpotCodeInfo(Compiler compiler, CiTargetMethod targetMethod, HotSpotMethodResolved method) {
-        super(compiler);
-        assert targetMethod != null;
-        this.method = method;
-        this.targetMethod = targetMethod;
-    }
-
-    @Override
-    public long start() {
-        return start;
-    }
-
-    @Override
-    public byte[] code() {
-        return code;
-    }
-
-    @Override
-    public String toString() {
-        int size = code == null ? 0 : code.length;
-        return "installed code @[" + Long.toHexString(start) + "-" + Long.toHexString(start + size) + "]";
-
-    }
-
-    @Override
-    public CiTargetMethod targetMethod() {
-        return targetMethod;
-    }
-
-    @Override
-    public RiResolvedMethod method() {
-        return method;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotCompiledMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import java.lang.reflect.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-
-/**
- * Implementation of RiCompiledMethod for HotSpot.
- * Stores a reference to the nmethod which contains the compiled code.
- * The nmethod also stores a weak reference to the HotSpotCompiledMethod
- * instance which is necessary to keep the nmethod from being unloaded.
- */
-public class HotSpotCompiledMethod extends CompilerObject implements RiCompiledMethod {
-
-    private static final long serialVersionUID = 156632908220561612L;
-
-    private final RiResolvedMethod method;
-    private long nmethod;
-
-    public HotSpotCompiledMethod(Compiler compiler, RiResolvedMethod method) {
-        super(compiler);
-        this.method = method;
-    }
-
-    @Override
-    public RiResolvedMethod method() {
-        return method;
-    }
-
-    @Override
-    public boolean isValid() {
-        return nmethod != 0;
-    }
-
-    @Override
-    public String toString() {
-        return "compiled method " + method + " @" + nmethod;
-    }
-
-    @Override
-    public Object execute(Object arg1, Object arg2, Object arg3) {
-        assert method.signature().argumentCount(!Modifier.isStatic(method.accessFlags())) == 3;
-        assert method.signature().argumentKindAt(0, false) == CiKind.Object;
-        assert method.signature().argumentKindAt(1, false) == CiKind.Object;
-        assert !Modifier.isStatic(method.accessFlags()) || method.signature().argumentKindAt(2, false) == CiKind.Object;
-        return compiler.getCompilerToVM().executeCompiledMethod(this, arg1, arg2, arg3);
-    }
-
-    private boolean checkArgs(Object... args) {
-        CiKind[] sig = CiUtil.signatureToKinds(method);
-        assert args.length == sig.length : CiUtil.format("%H.%n(%p): expected ", method) + sig.length + " args, got " + args.length;
-        for (int i = 0; i < sig.length; i++) {
-            Object arg = args[i];
-            if (arg == null) {
-                assert sig[i].isObject() : CiUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i];
-            } else if (!sig[i].isObject()) {
-                assert sig[i].toUnboxedJavaClass() == arg.getClass() : CiUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass();
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public Object executeVarargs(Object... args) {
-        assert checkArgs(args);
-        return compiler.getCompilerToVM().executeCompiledMethodVarargs(this, args);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotConstantPool.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-
-/**
- * Implementation of RiConstantPool for HotSpot.
- */
-public class HotSpotConstantPool extends CompilerObject implements RiConstantPool {
-
-    private static final long serialVersionUID = -5443206401485234850L;
-
-    private final HotSpotTypeResolvedImpl type;
-
-    public HotSpotConstantPool(Compiler compiler, HotSpotTypeResolvedImpl type) {
-        super(compiler);
-        this.type = type;
-    }
-
-    @Override
-    public Object lookupConstant(int cpi) {
-        Object constant = compiler.getCompilerToVM().RiConstantPool_lookupConstant(type, cpi);
-        return constant;
-    }
-
-    @Override
-    public RiSignature lookupSignature(int cpi) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public RiMethod lookupMethod(int cpi, int byteCode) {
-        return compiler.getCompilerToVM().RiConstantPool_lookupMethod(type, cpi, (byte) byteCode);
-    }
-
-    @Override
-    public RiType lookupType(int cpi, int opcode) {
-        return compiler.getCompilerToVM().RiConstantPool_lookupType(type, cpi);
-    }
-
-    @Override
-    public RiField lookupField(int cpi, int opcode) {
-        return compiler.getCompilerToVM().RiConstantPool_lookupField(type, cpi, (byte) opcode);
-    }
-
-    @Override
-    public void loadReferencedType(int cpi, int bytecode) {
-        compiler.getCompilerToVM().RiConstantPool_loadReferencedType(type, cpi, (byte) bytecode);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotExceptionHandler.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.*;
-
-
-public final class HotSpotExceptionHandler extends CompilerObject implements RiExceptionHandler {
-    /**
-     *
-     */
-    private static final long serialVersionUID = 7110038548061733686L;
-    private int startBci;
-    private int endBci;
-    private int handlerBci;
-    private int catchClassIndex;
-    private RiType catchClass;
-
-    private HotSpotExceptionHandler() {
-        super(null);
-    }
-
-    @Override
-    public int startBCI() {
-        return startBci;
-    }
-
-    @Override
-    public int endBCI() {
-        return endBci;
-    }
-
-    @Override
-    public int handlerBCI() {
-        return handlerBci;
-    }
-
-    @Override
-    public int catchTypeCPI() {
-        return catchClassIndex;
-    }
-
-    @Override
-    public boolean isCatchAll() {
-        return catchClassIndex == 0;
-    }
-
-    @Override
-    public RiType catchType() {
-        return catchClass;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("HotSpotExceptionHandler[startBci=%d, endBci=%d, handlerBci=%d, catchClassIndex=%d, catchClass=%s", startBci, endBci, handlerBci, catchClassIndex, catchClass);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotField.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.graal.hotspot.ri;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-
-/**
- * Represents a field in a HotSpot type.
- */
-public class HotSpotField extends CompilerObject implements RiResolvedField {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 7692985878836955683L;
-    private final RiResolvedType holder;
-    private final String name;
-    private final RiType type;
-    private final int offset;
-    private final int accessFlags;
-    private CiConstant constant;                // Constant part only valid for static fields.
-
-    public HotSpotField(Compiler compiler, RiResolvedType holder, String name, RiType type, int offset, int accessFlags) {
-        super(compiler);
-        this.holder = holder;
-        this.name = name;
-        this.type = type;
-        assert offset != -1;
-        this.offset = offset;
-        this.accessFlags = accessFlags;
-    }
-
-    @Override
-    public int accessFlags() {
-        return accessFlags;
-    }
-
-    @Override
-    public CiConstant constantValue(CiConstant receiver) {
-        if (receiver == null) {
-            assert Modifier.isStatic(accessFlags);
-            if (constant == null) {
-                if (holder.isInitialized() && holder.toJava() != System.class) {
-                    if (Modifier.isFinal(accessFlags()) || assumeStaticFieldsFinal(holder.toJava())) {
-                        CiConstant encoding = holder.getEncoding(Representation.StaticFields);
-                        constant = this.kind(false).readUnsafeConstant(encoding.asObject(), offset);
-                    }
-                }
-            }
-            return constant;
-        } else {
-            assert !Modifier.isStatic(accessFlags);
-            // TODO (chaeubl) HotSpot does not trust final non-static fields (see ciField.cpp)
-            if (Modifier.isFinal(accessFlags())) {
-                return this.kind(false).readUnsafeConstant(receiver.asObject(), offset);
-            }
-        }
-        return null;
-    }
-
-    private static boolean assumeStaticFieldsFinal(Class< ? > clazz) {
-        return clazz == GraalOptions.class;
-    }
-
-    @Override
-    public RiResolvedType holder() {
-        return holder;
-    }
-
-    @Override
-    public CiKind kind(boolean architecture) {
-        return type().kind(architecture);
-    }
-
-    @Override
-    public String name() {
-        return name;
-    }
-
-    @Override
-    public RiType type() {
-        return type;
-    }
-
-    public int offset() {
-        return offset;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotField<" + CiUtil.format("%h.%n", this) + ":" + offset + ">";
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        Field javaField = toJava();
-        if (javaField != null) {
-            return javaField.getAnnotation(annotationClass);
-        }
-        return null;
-    }
-
-    private Field toJava() {
-        try {
-            return holder.toJava().getDeclaredField(name);
-        } catch (NoSuchFieldException e) {
-            return null;
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-
-public abstract class HotSpotMethod extends CompilerObject implements RiMethod {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 7167491397941960839L;
-    protected String name;
-
-    protected HotSpotMethod(Compiler compiler) {
-        super(compiler);
-    }
-
-    @Override
-    public final String name() {
-        return name;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodData.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,582 +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.graal.hotspot.ri;
-
-import java.util.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-import com.oracle.max.cri.ri.*;
-
-
-public final class HotSpotMethodData extends CompilerObject {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = -8873133496591225071L;
-
-    static {
-        config = CompilerImpl.getInstance().getConfig();
-    }
-
-    // TODO (chaeubl) use same logic as in NodeClass?
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-    private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(RiExceptionSeen.FALSE);
-    private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(RiExceptionSeen.NOT_SUPPORTED);
-    private static final HotSpotVMConfig config;
-    // sorted by tag
-    private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {
-        null, new BitData(), new CounterData(), new JumpData(),
-        new TypeCheckData(), new VirtualCallData(), new RetData(),
-        new BranchData(), new MultiBranchData(), new ArgInfoData()
-    };
-
-    private Object hotspotMirror;
-    private int normalDataSize;
-    private int extraDataSize;
-
-    private HotSpotMethodData(Compiler compiler) {
-        super(compiler);
-        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
-    }
-
-    public boolean hasNormalData() {
-        return normalDataSize > 0;
-    }
-
-    public boolean hasExtraData() {
-        return extraDataSize > 0;
-    }
-
-    public int getExtraDataBeginOffset() {
-        return normalDataSize;
-    }
-
-    public boolean isWithin(int position) {
-        return position >= 0 && position < normalDataSize + extraDataSize;
-    }
-
-    public int getDeoptimizationCount(RiDeoptReason reason) {
-        int reasonIndex = compiler.getRuntime().convertDeoptReason(reason);
-        return unsafe.getByte(hotspotMirror, (long) config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF;
-    }
-
-    public HotSpotMethodDataAccessor getNormalData(int position) {
-        if (position >= normalDataSize) {
-            return null;
-        }
-
-        HotSpotMethodDataAccessor result = getData(position);
-        assert result != null : "NO_DATA tag is not allowed";
-        return result;
-    }
-
-    public HotSpotMethodDataAccessor getExtraData(int position) {
-        if (position >= normalDataSize + extraDataSize) {
-            return null;
-        }
-        return getData(position);
-    }
-
-    public static HotSpotMethodDataAccessor getNoDataAccessor(boolean exceptionPossiblyNotRecorded) {
-        if (exceptionPossiblyNotRecorded) {
-            return NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR;
-        } else {
-            return NO_DATA_NO_EXCEPTION_ACCESSOR;
-        }
-    }
-
-    private HotSpotMethodDataAccessor getData(int position) {
-        assert position >= 0 : "out of bounds";
-        int tag = AbstractMethodData.readTag(this, position);
-        assert tag >= 0 && tag < PROFILE_DATA_ACCESSORS.length : "illegal tag";
-        return PROFILE_DATA_ACCESSORS[tag];
-    }
-
-    private int readUnsignedByte(int position, int offsetInBytes) {
-        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getByte(hotspotMirror, fullOffsetInBytes) & 0xFF;
-    }
-
-    private int readUnsignedShort(int position, int offsetInBytes) {
-        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getShort(hotspotMirror, fullOffsetInBytes) & 0xFFFF;
-    }
-
-    private long readUnsignedInt(int position, int offsetInBytes) {
-        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getInt(hotspotMirror, fullOffsetInBytes) & 0xFFFFFFFFL;
-    }
-
-    private int readUnsignedIntAsSignedInt(int position, int offsetInBytes) {
-        long value = readUnsignedInt(position, offsetInBytes);
-        return truncateLongToInt(value);
-    }
-
-    private int readInt(int position, int offsetInBytes) {
-        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getInt(hotspotMirror, fullOffsetInBytes);
-    }
-
-    private Object readObject(int position, int offsetInBytes) {
-        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getObject(hotspotMirror, fullOffsetInBytes);
-    }
-
-    private static int truncateLongToInt(long value) {
-        return value > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) value;
-    }
-
-    private static int computeFullOffset(int position, int offsetInBytes) {
-        return config.methodDataOopDataOffset + position + offsetInBytes;
-    }
-
-    private static int cellIndexToOffset(int cells) {
-        return config.dataLayoutHeaderSize + cellsToBytes(cells);
-    }
-
-    private static int cellsToBytes(int cells) {
-        return cells * config.dataLayoutCellSize;
-    }
-
-    private abstract static class AbstractMethodData implements HotSpotMethodDataAccessor {
-        private static final int EXCEPTIONS_MASK = 0x80;
-
-        private final int tag;
-        private final int staticSize;
-
-        protected AbstractMethodData(int tag, int staticSize) {
-            this.tag = tag;
-            this.staticSize = staticSize;
-        }
-
-        public int getTag() {
-            return tag;
-        }
-
-        public static int readTag(HotSpotMethodData data, int position) {
-            return data.readUnsignedByte(position, config.dataLayoutTagOffset);
-        }
-
-        @Override
-        public int getBCI(HotSpotMethodData data, int position) {
-            return data.readUnsignedShort(position, config.dataLayoutBCIOffset);
-        }
-
-        @Override
-        public int getSize(HotSpotMethodData data, int position) {
-            return staticSize + getDynamicSize(data, position);
-        }
-
-        @Override
-        public RiExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
-            return RiExceptionSeen.get((getFlags(data, position) & EXCEPTIONS_MASK) != 0);
-        }
-
-        @Override
-        public RiTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
-            return null;
-        }
-
-        @Override
-        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
-            return -1;
-        }
-
-        @Override
-        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
-            return null;
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            return -1;
-        }
-
-        protected int getFlags(HotSpotMethodData data, int position) {
-            return data.readUnsignedByte(position, config.dataLayoutFlagsOffset);
-        }
-
-        protected int getDynamicSize(@SuppressWarnings("unused") HotSpotMethodData data, @SuppressWarnings("unused") int position) {
-            return 0;
-        }
-    }
-
-    private static class NoMethodData extends AbstractMethodData {
-        private static final int NO_DATA_TAG = 0;
-        private static final int NO_DATA_SIZE = cellIndexToOffset(0);
-
-        private final RiExceptionSeen exceptionSeen;
-
-        protected NoMethodData(RiExceptionSeen exceptionSeen) {
-            super(NO_DATA_TAG, NO_DATA_SIZE);
-            this.exceptionSeen = exceptionSeen;
-        }
-
-        @Override
-        public int getBCI(HotSpotMethodData data, int position) {
-            return -1;
-        }
-
-
-        @Override
-        public RiExceptionSeen getExceptionSeen(HotSpotMethodData data, int position) {
-            return exceptionSeen;
-        }
-    }
-
-    private static class BitData extends AbstractMethodData {
-        private static final int BIT_DATA_TAG = 1;
-        private static final int BIT_DATA_SIZE = cellIndexToOffset(0);
-        private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01;
-
-        private BitData() {
-            super(BIT_DATA_TAG, BIT_DATA_SIZE);
-        }
-
-        protected BitData(int tag, int staticSize) {
-            super(tag, staticSize);
-        }
-
-        @SuppressWarnings("unused")
-        public boolean getNullSeen(HotSpotMethodData data, int position) {
-            return (getFlags(data, position) & BIT_DATA_NULL_SEEN_FLAG) != 0;
-        }
-    }
-
-    private static class CounterData extends BitData {
-        private static final int COUNTER_DATA_TAG = 2;
-        private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
-        private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0);
-
-        public CounterData() {
-            super(COUNTER_DATA_TAG, COUNTER_DATA_SIZE);
-        }
-
-        protected CounterData(int tag, int staticSize) {
-            super(tag, staticSize);
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            return getCounterValue(data, position);
-        }
-
-        protected int getCounterValue(HotSpotMethodData data, int position) {
-            return data.readUnsignedIntAsSignedInt(position, COUNTER_DATA_COUNT_OFFSET);
-        }
-    }
-
-    private static class JumpData extends AbstractMethodData {
-        private static final int JUMP_DATA_TAG = 3;
-        private static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
-        protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(0);
-        protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1);
-
-        public JumpData() {
-            super(JUMP_DATA_TAG, JUMP_DATA_SIZE);
-        }
-
-        protected JumpData(int tag, int staticSize) {
-            super(tag, staticSize);
-        }
-
-        @Override
-        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
-            return getExecutionCount(data, position) != 0 ? 1 : 0;
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            return data.readUnsignedIntAsSignedInt(position, TAKEN_COUNT_OFFSET);
-        }
-
-        @SuppressWarnings("unused")
-        public int getTakenDisplacement(HotSpotMethodData data, int position) {
-            return data.readInt(position, TAKEN_DISPLACEMENT_OFFSET);
-        }
-    }
-
-    private abstract static class AbstractTypeData extends CounterData {
-        private static final int RECEIVER_TYPE_DATA_ROW_SIZE = cellsToBytes(2);
-        private static final int RECEIVER_TYPE_DATA_SIZE = cellIndexToOffset(1) + RECEIVER_TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
-        private static final int RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET = cellIndexToOffset(1);
-        private static final int RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET = cellIndexToOffset(2);
-
-        protected AbstractTypeData(int tag) {
-            super(tag, RECEIVER_TYPE_DATA_SIZE);
-        }
-
-        @Override
-        public RiTypeProfile getTypeProfile(HotSpotMethodData data, int position) {
-            int typeProfileWidth = config.typeProfileWidth;
-
-            RiResolvedType[] sparseTypes = new RiResolvedType[typeProfileWidth];
-            double[] counts = new double[typeProfileWidth];
-            long totalCount = 0;
-            int entries = 0;
-
-            for (int i = 0; i < typeProfileWidth; i++) {
-                Object receiverKlassOop = data.readObject(position, getReceiverOffset(i));
-                if (receiverKlassOop != null) {
-                    Object graalMirror = unsafe.getObject(receiverKlassOop, (long) config.graalMirrorKlassOffset);
-                    if (graalMirror == null) {
-                        Class<?> javaClass = (Class<?>) unsafe.getObject(receiverKlassOop, (long) config.classMirrorOffset);
-                        graalMirror = CompilerImpl.getInstance().getCompilerToVM().getType(javaClass);
-                        assert graalMirror != null : "must not return null";
-                    }
-                    sparseTypes[entries] = (RiResolvedType) graalMirror;
-
-                    long count = data.readUnsignedInt(position, getCountOffset(i));
-                    totalCount += count;
-                    counts[entries] = count;
-
-                    entries++;
-                }
-            }
-
-            totalCount += getTypesNotRecordedExecutionCount(data, position);
-            return createRiTypeProfile(sparseTypes, counts, totalCount, entries);
-        }
-
-        protected long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position) {
-            // checkcast/aastore/instanceof profiling in the HotSpot template-based interpreter was adjusted so that the counter
-            // is incremented to indicate the polymorphic case instead of decrementing it for failed type checks
-            return getCounterValue(data, position);
-        }
-
-        private static RiTypeProfile createRiTypeProfile(RiResolvedType[] sparseTypes, double[] counts, long totalCount, int entries) {
-            RiResolvedType[] types;
-            double[] probabilities;
-
-            if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) {
-                return null;
-            } else if (entries < sparseTypes.length) {
-                types = Arrays.copyOf(sparseTypes, entries);
-                probabilities = new double[entries];
-            } else {
-                types = sparseTypes;
-                probabilities = counts;
-            }
-
-            double totalProbability = 0.0;
-            for (int i = 0; i < entries; i++) {
-                double p = counts[i] / totalCount;
-                probabilities[i] = p;
-                totalProbability += p;
-            }
-
-            double notRecordedTypeProbability = entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability));
-            return new RiTypeProfile(types, notRecordedTypeProbability, probabilities);
-        }
-
-        private static int getReceiverOffset(int row) {
-            return RECEIVER_TYPE_DATA_FIRST_RECEIVER_OFFSET + row * RECEIVER_TYPE_DATA_ROW_SIZE;
-        }
-
-        protected static int getCountOffset(int row) {
-            return RECEIVER_TYPE_DATA_FIRST_COUNT_OFFSET + row * RECEIVER_TYPE_DATA_ROW_SIZE;
-        }
-    }
-
-    private static class TypeCheckData extends AbstractTypeData {
-        private static final int RECEIVER_TYPE_DATA_TAG = 4;
-
-        public TypeCheckData() {
-            super(RECEIVER_TYPE_DATA_TAG);
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            return -1;
-        }
-    }
-
-    private static class VirtualCallData extends AbstractTypeData {
-        private static final int VIRTUAL_CALL_DATA_TAG = 5;
-
-        public VirtualCallData() {
-            super(VIRTUAL_CALL_DATA_TAG);
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            int typeProfileWidth = config.typeProfileWidth;
-
-            long total = 0;
-            for (int i = 0; i < typeProfileWidth; i++) {
-                total += data.readUnsignedInt(position, getCountOffset(i));
-            }
-
-            total += getCounterValue(data, position);
-            return truncateLongToInt(total);
-        }
-    }
-
-    private static class RetData extends CounterData {
-        private static final int RET_DATA_TAG = 6;
-        private static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
-        private static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth;
-
-        public RetData() {
-            super(RET_DATA_TAG, RET_DATA_SIZE);
-        }
-    }
-
-    private static class BranchData extends JumpData {
-        private static final int BRANCH_DATA_TAG = 7;
-        private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
-        private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2);
-
-        public BranchData() {
-            super(BRANCH_DATA_TAG, BRANCH_DATA_SIZE);
-        }
-
-        @Override
-        public double getBranchTakenProbability(HotSpotMethodData data, int position) {
-            long takenCount = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET);
-            long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
-            long total = takenCount + notTakenCount;
-
-            if (total < GraalOptions.MatureExecutionsBranch) {
-                return -1;
-            } else {
-                return takenCount / (double) total;
-            }
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            long count = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET) + data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
-            return truncateLongToInt(count);
-        }
-    }
-
-    private static class ArrayData extends AbstractMethodData {
-        private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(0);
-        protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(1);
-
-        public ArrayData(int tag, int staticSize) {
-            super(tag, staticSize);
-        }
-
-        @Override
-        protected int getDynamicSize(HotSpotMethodData data, int position) {
-            return cellsToBytes(getLength(data, position));
-        }
-
-        protected static int getLength(HotSpotMethodData data, int position) {
-            return data.readInt(position, ARRAY_DATA_LENGTH_OFFSET);
-        }
-    }
-
-    private static class MultiBranchData extends ArrayData {
-        private static final int MULTI_BRANCH_DATA_TAG = 8;
-        private static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
-        private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = 2;
-        private static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
-        private static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
-        private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
-
-        public MultiBranchData() {
-            super(MULTI_BRANCH_DATA_TAG, MULTI_BRANCH_DATA_SIZE);
-        }
-
-        @Override
-        public double[] getSwitchProbabilities(HotSpotMethodData data, int position) {
-            int arrayLength = getLength(data, position);
-            assert arrayLength > 0 : "switch must have at least the default case";
-            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
-
-            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
-            long totalCount = 0;
-            double[] result = new double[length];
-
-            // default case is first in HotSpot but last for the compiler
-            long count = readCount(data, position, 0);
-            totalCount += count;
-            result[length - 1] = count;
-
-            for (int i = 1; i < length; i++) {
-                count = readCount(data, position, i);
-                totalCount += count;
-                result[i - 1] = count;
-            }
-
-            if (totalCount < GraalOptions.MatureExecutionsPerSwitchCase * length) {
-                return null;
-            } else {
-                for (int i = 0; i < length; i++) {
-                    result[i] = result[i] / totalCount;
-                }
-                return result;
-            }
-        }
-
-        private static long readCount(HotSpotMethodData data, int position, int i) {
-            int offset;
-            long count;
-            offset = getCountOffset(i);
-            count = data.readUnsignedInt(position, offset);
-            return count;
-        }
-
-        @Override
-        public int getExecutionCount(HotSpotMethodData data, int position) {
-            int arrayLength = getLength(data, position);
-            assert arrayLength > 0 : "switch must have at least the default case";
-            assert arrayLength % MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS == 0 : "array must have full rows";
-
-            int length = arrayLength / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS;
-            long totalCount = 0;
-            for (int i = 0; i < length; i++) {
-                int offset = getCountOffset(i);
-                totalCount += data.readUnsignedInt(position, offset);
-            }
-
-            return truncateLongToInt(totalCount);
-        }
-
-        private static int getCountOffset(int index) {
-            return MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
-        }
-
-        @SuppressWarnings("unused")
-        private static int getDisplacementOffset(int index) {
-            return MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE;
-        }
-    }
-
-    private static class ArgInfoData extends ArrayData {
-        private static final int ARG_INFO_DATA_TAG = 9;
-        private static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1);
-
-        public ArgInfoData() {
-            super(ARG_INFO_DATA_TAG, ARG_INFO_DATA_SIZE);
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodDataAccessor.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * Interface for accessor objects that encapsulate the logic for accessing the different kinds of data in a HotSpot methodDataOop.
- * This interface is similar to the interface {@link RiProfilingInfo}, but most methods require a MethodDataObject and the
- * exact position within the methodData.
- */
-public interface HotSpotMethodDataAccessor {
-    /**
-     * Returns the tag stored in the LayoutData header.
-     * @return An integer >= 0 or -1 if not supported.
-     */
-    int getTag();
-
-    /**
-     * Returns the BCI stored in the LayoutData header.
-     * @return An integer >= 0 and <= Short.MAX_VALUE, or -1 if not supported.
-     */
-    int getBCI(HotSpotMethodData data, int position);
-
-    /**
-     * Computes the size for the specific data at the given position.
-     * @return An integer > 0.
-     */
-    int getSize(HotSpotMethodData data, int position);
-
-    RiTypeProfile getTypeProfile(HotSpotMethodData data, int position);
-    double getBranchTakenProbability(HotSpotMethodData data, int position);
-    double[] getSwitchProbabilities(HotSpotMethodData data, int position);
-    RiExceptionSeen getExceptionSeen(HotSpotMethodData data, int position);
-    int getExecutionCount(HotSpotMethodData data, int position);
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolved.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.server.*;
-
-public interface HotSpotMethodResolved extends RiResolvedMethod, Remote {
-
-    RiResolvedMethod uniqueConcreteMethod();
-    void dumpProfile();
-    int vtableEntryOffset();
-
-    void setCurrentTask(CompilationTask task);
-    CompilationTask currentTask();
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,380 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.criutils.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.java.bytecode.*;
-
-/**
- * Implementation of RiMethod for resolved HotSpot methods.
- */
-public final class HotSpotMethodResolvedImpl extends HotSpotMethod implements HotSpotMethodResolved {
-
-    private static final long serialVersionUID = -5486975070147586588L;
-
-    /** DO NOT USE IN JAVA CODE! */
-    @SuppressWarnings("unused")
-    @Deprecated
-    private Object javaMirror;
-
-    // cached values
-    private final int codeSize;
-    private final int accessFlags;
-    private final int maxLocals;
-    private final int maxStackSize;
-    private RiSignature signature;
-    private Boolean hasBalancedMonitors;
-    private Map<Object, Object> compilerStorage;
-    private RiResolvedType holder;
-    private HotSpotMethodData methodData;
-    private byte[] code;
-    private boolean canBeInlined;
-    private int compilationComplexity;
-
-    private CompilationTask currentTask;
-
-    private HotSpotMethodResolvedImpl() {
-        super(null);
-        throw new IllegalStateException("this constructor is never actually called, because the objects are allocated from within the VM");
-    }
-
-    @Override
-    public RiResolvedType holder() {
-        return holder;
-    }
-
-    @Override
-    public int accessFlags() {
-        return accessFlags;
-    }
-
-    @Override
-    public boolean canBeStaticallyBound() {
-        return isLeafMethod() || Modifier.isStatic(accessFlags());
-    }
-
-    @Override
-    public byte[] code() {
-        if (code == null) {
-            code = compiler.getCompilerToVM().RiMethod_code(this);
-            assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length;
-        }
-        return code;
-    }
-
-    @Override
-    public int codeSize() {
-        return codeSize;
-    }
-
-    @Override
-    public RiExceptionHandler[] exceptionHandlers() {
-        return compiler.getCompilerToVM().RiMethod_exceptionHandlers(this);
-    }
-
-    @Override
-    public boolean hasBalancedMonitors() {
-        if (hasBalancedMonitors == null) {
-            hasBalancedMonitors = compiler.getCompilerToVM().RiMethod_hasBalancedMonitors(this);
-        }
-        return hasBalancedMonitors;
-    }
-
-    @Override
-    public boolean isClassInitializer() {
-        return "<clinit>".equals(name) && Modifier.isStatic(accessFlags());
-    }
-
-    @Override
-    public boolean isConstructor() {
-        return "<init>".equals(name) && !Modifier.isStatic(accessFlags());
-    }
-
-    @Override
-    public boolean isLeafMethod() {
-        return Modifier.isFinal(accessFlags()) || Modifier.isPrivate(accessFlags());
-    }
-
-    @Override
-    public boolean isOverridden() {
-        throw new UnsupportedOperationException("isOverridden");
-    }
-
-    @Override
-    public boolean noSafepointPolls() {
-        return false;
-    }
-
-    @Override
-    public String jniSymbol() {
-        throw new UnsupportedOperationException("jniSymbol");
-    }
-
-    public CiBitMap[] livenessMap() {
-        return null;
-    }
-
-    @Override
-    public int maxLocals() {
-        return maxLocals;
-    }
-
-    @Override
-    public int maxStackSize() {
-        return maxStackSize;
-    }
-
-    @Override
-    public StackTraceElement toStackTraceElement(int bci) {
-        if (bci < 0 || bci >= codeSize) {
-            // HotSpot code can only construct stack trace elements for valid bcis
-            StackTraceElement ste = compiler.getCompilerToVM().RiMethod_toStackTraceElement(this, 0);
-            return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
-        }
-        return compiler.getCompilerToVM().RiMethod_toStackTraceElement(this, bci);
-    }
-
-    @Override
-    public RiResolvedMethod uniqueConcreteMethod() {
-        return (RiResolvedMethod) compiler.getCompilerToVM().RiMethod_uniqueConcreteMethod(this);
-    }
-
-    @Override
-    public RiSignature signature() {
-        if (signature == null) {
-            signature = new HotSpotSignature(compiler, compiler.getCompilerToVM().RiMethod_signature(this));
-        }
-        return signature;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotMethod<" + CiUtil.format("%h.%n", this) + ">";
-    }
-
-    public boolean hasCompiledCode() {
-        return compiler.getCompilerToVM().RiMethod_hasCompiledCode(this);
-    }
-
-    public int compiledCodeSize() {
-        return compiler.getCompilerToVM().RiMethod_getCompiledCodeSize(this);
-    }
-
-    @Override
-    public RiResolvedType accessor() {
-        return null;
-    }
-
-    @Override
-    public String intrinsic() {
-        return null;
-    }
-
-    @Override
-    public int invocationCount() {
-        return compiler.getCompilerToVM().RiMethod_invocationCount(this);
-    }
-
-    @Override
-    public int compilationComplexity() {
-        if (compilationComplexity <= 0 && codeSize() > 0) {
-            BytecodeStream s = new BytecodeStream(code());
-            int result = 0;
-            int currentBC;
-            while ((currentBC = s.currentBC()) != Bytecodes.END) {
-                result += Bytecodes.compilationComplexity(currentBC);
-                s.next();
-            }
-            assert result > 0;
-            compilationComplexity = result;
-        }
-        return compilationComplexity;
-    }
-
-    @Override
-    public RiProfilingInfo profilingInfo() {
-        if (GraalOptions.UseProfilingInformation && methodData == null) {
-            methodData = compiler.getCompilerToVM().RiMethod_methodData(this);
-        }
-
-        if (methodData == null) {
-            // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in case of a deoptimization.
-            return BaseProfilingInfo.get(RiExceptionSeen.FALSE);
-        } else {
-            return new HotSpotProfilingInfo(compiler, methodData);
-        }
-    }
-
-    @Override
-    public Map<Object, Object> compilerStorage() {
-        if (compilerStorage == null) {
-            compilerStorage = new ConcurrentHashMap<>();
-        }
-        return compilerStorage;
-    }
-
-    @Override
-    public RiConstantPool getConstantPool() {
-        return ((HotSpotTypeResolvedImpl) holder()).constantPool();
-    }
-
-    @Override
-    public void dumpProfile() {
-        TTY.println("profile info for %s", this);
-        TTY.println("canBeStaticallyBound: " + canBeStaticallyBound());
-        TTY.println("invocationCount: " + invocationCount());
-        RiProfilingInfo profilingInfo = this.profilingInfo();
-        for (int i = 0; i < codeSize(); i++) {
-            if (profilingInfo.getExecutionCount(i) != -1) {
-                TTY.println("  executionCount@%d: %d", i, profilingInfo.getExecutionCount(i));
-            }
-
-            if (profilingInfo.getBranchTakenProbability(i) != -1) {
-                TTY.println("  branchProbability@%d: %f", i, profilingInfo.getBranchTakenProbability(i));
-            }
-
-            double[] switchProbabilities = profilingInfo.getSwitchProbabilities(i);
-            if (switchProbabilities != null) {
-                TTY.print("  switchProbabilities@%d:", i);
-                for (int j = 0; j < switchProbabilities.length; j++) {
-                    TTY.print(" %f", switchProbabilities[j]);
-                }
-                TTY.println();
-            }
-
-            if (profilingInfo.getExceptionSeen(i) != RiExceptionSeen.FALSE) {
-                TTY.println("  exceptionSeen@%d: %s", i, profilingInfo.getExceptionSeen(i).name());
-            }
-
-            RiTypeProfile typeProfile = profilingInfo.getTypeProfile(i);
-            if (typeProfile != null) {
-                RiResolvedType[] types = typeProfile.getTypes();
-                double[] probabilities = typeProfile.getProbabilities();
-                if (types != null && probabilities != null) {
-                    assert types.length == probabilities.length : "length must match";
-                    TTY.print("  types@%d:", i);
-                    for (int j = 0; j < types.length; j++) {
-                        TTY.print(" %s (%f)", types[j], probabilities[j]);
-                    }
-                    TTY.println(" not recorded (%f)", typeProfile.getNotRecordedProbability());
-                }
-            }
-        }
-
-        boolean firstDeoptReason = true;
-        for (RiDeoptReason reason: RiDeoptReason.values()) {
-            int count = profilingInfo.getDeoptimizationCount(reason);
-            if (count > 0) {
-                if (firstDeoptReason) {
-                    TTY.println("Deopt History");
-                    firstDeoptReason = false;
-                }
-                TTY.println("  %s: %d", reason.name(), count);
-            }
-        }
-    }
-
-    @Override
-    public Annotation[][] getParameterAnnotations() {
-        if (isConstructor()) {
-            Constructor javaConstructor = toJavaConstructor();
-            return javaConstructor == null ? null : javaConstructor.getParameterAnnotations();
-        }
-        Method javaMethod = toJava();
-        return javaMethod == null ? null : javaMethod.getParameterAnnotations();
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        if (isConstructor()) {
-            Constructor<?> javaConstructor = toJavaConstructor();
-            return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass);
-        }
-        Method javaMethod = toJava();
-        return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
-    }
-
-    @Override
-    public Type getGenericReturnType() {
-        if (isConstructor()) {
-            return void.class;
-        }
-        Method javaMethod = toJava();
-        return javaMethod == null ? null : javaMethod.getGenericReturnType();
-    }
-
-    @Override
-    public Type[] getGenericParameterTypes() {
-        if (isConstructor()) {
-            Constructor javaConstructor = toJavaConstructor();
-            return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes();
-        }
-        Method javaMethod = toJava();
-        return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
-    }
-
-    private Method toJava() {
-        try {
-            return holder.toJava().getDeclaredMethod(name, CiUtil.signatureToTypes(signature(), holder));
-        } catch (NoSuchMethodException e) {
-            return null;
-        }
-    }
-
-    private Constructor toJavaConstructor() {
-        try {
-            return holder.toJava().getDeclaredConstructor(CiUtil.signatureToTypes(signature(), holder));
-        } catch (NoSuchMethodException e) {
-            return null;
-        }
-    }
-
-    @Override
-    public boolean canBeInlined() {
-        return canBeInlined;
-    }
-
-    @Override
-    public int vtableEntryOffset() {
-        return compiler.getCompilerToVM().RiMethod_vtableEntryOffset(this);
-    }
-
-    @Override
-    public void setCurrentTask(CompilationTask task) {
-        currentTask = task;
-    }
-
-    @Override
-    public CompilationTask currentTask() {
-        return currentTask;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodUnresolved.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.Compiler;
-
-/**
- * Implementation of RiMethod for unresolved HotSpot methods.
- */
-public final class HotSpotMethodUnresolved extends HotSpotMethod {
-    /**
-     * 
-     */
-    private static final long serialVersionUID = 5610263481791970079L;
-    private final RiSignature signature;
-    protected RiType holder;
-
-    public HotSpotMethodUnresolved(Compiler compiler, String name, String signature, RiType holder) {
-        super(compiler);
-        this.name = name;
-        this.holder = holder;
-        this.signature = new HotSpotSignature(compiler, signature);
-    }
-
-    @Override
-    public RiSignature signature() {
-        return signature;
-    }
-
-    @Override
-    public RiType holder() {
-        return holder;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotMethod<" + holder.name() + ". " + name + ", unresolved>";
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotProfilingInfo.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +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.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-
-
-public final class HotSpotProfilingInfo extends CompilerObject implements RiProfilingInfo {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = -8307682725047864875L;
-    private static final DebugMetric metricInsufficentSpace = Debug.metric("InsufficientSpaceForProfilingData");
-
-    private int position;
-    private int hintPosition;
-    private int hintBCI;
-    private HotSpotMethodDataAccessor dataAccessor;
-    private HotSpotMethodData methodData;
-
-    public HotSpotProfilingInfo(Compiler compiler, HotSpotMethodData methodData) {
-        super(compiler);
-        this.methodData = methodData;
-        hintPosition = 0;
-        hintBCI = -1;
-    }
-
-    @Override
-    public RiTypeProfile getTypeProfile(int bci) {
-        findBCI(bci, false);
-        return dataAccessor.getTypeProfile(methodData, position);
-    }
-
-    @Override
-    public double getBranchTakenProbability(int bci) {
-        findBCI(bci, false);
-        return dataAccessor.getBranchTakenProbability(methodData, position);
-    }
-
-    @Override
-    public double[] getSwitchProbabilities(int bci) {
-        findBCI(bci, false);
-        return dataAccessor.getSwitchProbabilities(methodData, position);
-    }
-
-    @Override
-    public RiExceptionSeen getExceptionSeen(int bci) {
-        findBCI(bci, true);
-        return dataAccessor.getExceptionSeen(methodData, position);
-    }
-
-    @Override
-    public int getExecutionCount(int bci) {
-        findBCI(bci, false);
-        return dataAccessor.getExecutionCount(methodData, position);
-    }
-
-    @Override
-    public int getDeoptimizationCount(RiDeoptReason reason) {
-        return methodData.getDeoptimizationCount(reason);
-    }
-
-    private void findBCI(int targetBCI, boolean searchExtraData) {
-        assert targetBCI >= 0 : "invalid BCI";
-
-        if (methodData.hasNormalData()) {
-            int currentPosition = targetBCI < hintBCI ? 0 : hintPosition;
-            HotSpotMethodDataAccessor currentAccessor;
-            while ((currentAccessor = methodData.getNormalData(currentPosition)) != null) {
-                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
-                if (currentBCI == targetBCI) {
-                    normalDataFound(currentAccessor, currentPosition, currentBCI);
-                    return;
-                } else if (currentBCI > targetBCI) {
-                    break;
-                }
-                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
-            }
-        }
-
-        boolean exceptionPossiblyNotRecorded = false;
-        if (searchExtraData && methodData.hasExtraData()) {
-            int currentPosition = methodData.getExtraDataBeginOffset();
-            HotSpotMethodDataAccessor currentAccessor;
-            while ((currentAccessor = methodData.getExtraData(currentPosition)) != null) {
-                int currentBCI = currentAccessor.getBCI(methodData, currentPosition);
-                if (currentBCI == targetBCI) {
-                    extraDataFound(currentAccessor, currentPosition);
-                    return;
-                }
-                currentPosition = currentPosition + currentAccessor.getSize(methodData, currentPosition);
-            }
-
-            if (!methodData.isWithin(currentPosition)) {
-                exceptionPossiblyNotRecorded = true;
-                metricInsufficentSpace.increment();
-            }
-        }
-
-        noDataFound(exceptionPossiblyNotRecorded);
-    }
-
-    private void normalDataFound(HotSpotMethodDataAccessor data, int pos, int bci) {
-        setCurrentData(data, pos);
-        this.hintPosition = position;
-        this.hintBCI = bci;
-    }
-
-    private void extraDataFound(HotSpotMethodDataAccessor data, int pos) {
-        setCurrentData(data, pos);
-    }
-
-    private void noDataFound(boolean exceptionPossiblyNotRecorded) {
-        HotSpotMethodDataAccessor accessor = HotSpotMethodData.getNoDataAccessor(exceptionPossiblyNotRecorded);
-        setCurrentData(accessor, -1);
-    }
-
-    private void setCurrentData(HotSpotMethodDataAccessor dataAccessor, int position) {
-        this.dataAccessor = dataAccessor;
-        this.position = position;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRegisterConfig.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import static com.oracle.max.asm.target.amd64.AMD64.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiCallingConvention.Type;
-import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-
-public class HotSpotRegisterConfig implements RiRegisterConfig {
-
-    // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp
-    private final CiRegister[] allocatable = {
-        rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/
-        xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
-        xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
-    };
-
-    private final EnumMap<RegisterFlag, CiRegister[]> categorized = CiRegister.categorize(allocatable);
-
-    private final RiRegisterAttributes[] attributesMap;
-
-    @Override
-    public CiRegister[] getAllocatableRegisters() {
-        return allocatable;
-    }
-
-    @Override
-    public EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters() {
-        return categorized;
-    }
-
-    @Override
-    public RiRegisterAttributes[] getAttributesMap() {
-        return attributesMap;
-    }
-
-    private final CiRegister[] generalParameterRegisters;
-    private final CiRegister[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7};
-    private final CiRegister[] allParameterRegisters;
-
-    private final CiCalleeSaveLayout csl;
-
-    public HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) {
-        if (config.windowsOs) {
-            generalParameterRegisters = new CiRegister[] {rdx, r8, r9, rdi, rsi, rcx};
-        } else {
-            generalParameterRegisters = new CiRegister[] {rsi, rdx, rcx, r8, r9, rdi};
-        }
-
-        if (globalStubConfig) {
-            CiRegister[] regs = {
-                rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
-                r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
-                xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
-                xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
-            };
-            csl = new CiCalleeSaveLayout(0, -1, 8, regs);
-        } else {
-            // We reserve space for saving RBP but don't explicitly specify
-            // it as a callee save register since we explicitly do the saving
-            // with push and pop in HotSpotFrameContext
-            final int size = 8;
-            final CiRegister[] regs = {};
-            csl = new CiCalleeSaveLayout(0, size, 8, regs);
-        }
-
-        attributesMap = RiRegisterAttributes.createMap(this, AMD64.allRegisters);
-        allParameterRegisters = Arrays.copyOf(generalParameterRegisters, generalParameterRegisters.length + xmmParameterRegisters.length);
-        System.arraycopy(xmmParameterRegisters, 0, allParameterRegisters, generalParameterRegisters.length, xmmParameterRegisters.length);
-    }
-
-    @Override
-    public CiRegister[] getCallerSaveRegisters() {
-        return getAllocatableRegisters();
-    }
-
-    @Override
-    public CiRegister getRegisterForRole(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly) {
-        if (type == Type.NativeCall) {
-            throw new UnsupportedOperationException();
-        }
-        return callingConvention(parameters, type, target, stackOnly);
-    }
-
-    public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
-        return allParameterRegisters;
-    }
-
-    private CiCallingConvention callingConvention(CiKind[] types, Type type, CiTarget target, boolean stackOnly) {
-        CiValue[] locations = new CiValue[types.length];
-
-        int currentGeneral = 0;
-        int currentXMM = 0;
-        int currentStackOffset = 0;
-
-        for (int i = 0; i < types.length; i++) {
-            final CiKind kind = types[i];
-
-            switch (kind) {
-                case Byte:
-                case Boolean:
-                case Short:
-                case Char:
-                case Int:
-                case Long:
-                case Object:
-                    if (!stackOnly && currentGeneral < generalParameterRegisters.length) {
-                        CiRegister register = generalParameterRegisters[currentGeneral++];
-                        locations[i] = register.asValue(kind);
-                    }
-                    break;
-                case Float:
-                case Double:
-                    if (!stackOnly && currentXMM < xmmParameterRegisters.length) {
-                        CiRegister register = xmmParameterRegisters[currentXMM++];
-                        locations[i] = register.asValue(kind);
-                    }
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-
-            if (locations[i] == null) {
-                locations[i] = CiStackSlot.get(kind.stackKind(), currentStackOffset, !type.out);
-                currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize);
-            }
-        }
-
-        return new CiCallingConvention(locations, currentStackOffset);
-    }
-
-    @Override
-    public CiRegister getReturnRegister(CiKind kind) {
-        switch (kind) {
-            case Boolean:
-            case Byte:
-            case Char:
-            case Short:
-            case Int:
-            case Long:
-            case Object:
-                return rax;
-            case Float:
-            case Double:
-                return xmm0;
-            case Void:
-            case Illegal:
-                return null;
-            default:
-                throw new UnsupportedOperationException("no return register for type " + kind);
-        }
-    }
-
-    @Override
-    public CiRegister getScratchRegister() {
-        return r10;
-    }
-
-    @Override
-    public CiRegister getFrameRegister() {
-        return rsp;
-    }
-
-    public CiCalleeSaveLayout getCalleeSaveLayout() {
-        return csl;
-    }
-
-    @Override
-    public String toString() {
-        String res = String.format(
-             "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
-             "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
-             "CalleeSave:  " + getCalleeSaveLayout() + "%n" +
-             "Scratch:     " + getScratchRegister() + "%n");
-        return res;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,545 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import static com.oracle.max.cri.util.MemoryBarriers.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.phases.*;
-import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.cri.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.hotspot.target.amd64.*;
-import com.oracle.graal.java.*;
-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.graal.nodes.type.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.Call;
-import com.oracle.max.cri.ci.CiTargetMethod.DataPatch;
-import com.oracle.max.cri.ci.CiTargetMethod.Mark;
-import com.oracle.max.cri.ci.CiTargetMethod.Safepoint;
-import com.oracle.max.cri.ci.CiUtil.RefMapFormatter;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.Representation;
-import com.oracle.max.criutils.*;
-
-/**
- * CRI runtime implementation for the HotSpot VM.
- */
-public class HotSpotRuntime implements GraalRuntime {
-    public final HotSpotVMConfig config;
-    final HotSpotRegisterConfig regConfig;
-    private final HotSpotRegisterConfig globalStubRegConfig;
-    private final Compiler compiler;
-
-    public HotSpotRuntime(HotSpotVMConfig config, Compiler compiler) {
-        this.config = config;
-        this.compiler = compiler;
-        regConfig = new HotSpotRegisterConfig(config, false);
-        globalStubRegConfig = new HotSpotRegisterConfig(config, true);
-
-        System.setProperty(Backend.BACKEND_CLASS_PROPERTY, HotSpotAMD64Backend.class.getName());
-    }
-
-    @Override
-    public int codeOffset() {
-        return 0;
-    }
-
-
-    public Compiler getCompiler() {
-        return compiler;
-    }
-
-    @Override
-    public String disassemble(RiCodeInfo info) {
-        byte[] code = info.code();
-        CiTarget target = compiler.getTarget();
-        HexCodeFile hcf = new HexCodeFile(code, info.start(), target.arch.name, target.wordSize * 8);
-        CiTargetMethod tm = info.targetMethod();
-        if (tm != null) {
-            HexCodeFile.addAnnotations(hcf, tm.annotations());
-            addExceptionHandlersComment(tm, hcf);
-            CiRegister fp = regConfig.getFrameRegister();
-            RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0);
-            for (Safepoint safepoint : tm.safepoints) {
-                if (safepoint instanceof Call) {
-                    Call call = (Call) safepoint;
-                    if (call.debugInfo != null) {
-                        hcf.addComment(call.pcOffset + call.size, CiUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
-                    }
-                    addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}");
-                } else {
-                    if (safepoint.debugInfo != null) {
-                        hcf.addComment(safepoint.pcOffset, CiUtil.append(new StringBuilder(100), safepoint.debugInfo, slotFormatter).toString());
-                    }
-                    addOperandComment(hcf, safepoint.pcOffset, "{safepoint}");
-                }
-            }
-            for (DataPatch site : tm.dataReferences) {
-                hcf.addOperandComment(site.pcOffset, "{" + site.constant + "}");
-            }
-            for (Mark mark : tm.marks) {
-                hcf.addComment(mark.pcOffset, getMarkName(mark));
-            }
-        }
-        return hcf.toEmbeddedString();
-    }
-
-    /**
-     * Decodes a call target to a mnemonic if possible.
-     */
-    private String getTargetName(Call call) {
-        Field[] fields = config.getClass().getDeclaredFields();
-        for (Field f : fields) {
-            if (f.getName().endsWith("Stub")) {
-                f.setAccessible(true);
-                try {
-                    if (f.get(config).equals(call.target)) {
-                        return f.getName();
-                    }
-                } catch (Exception e) {
-                }
-            }
-        }
-        return String.valueOf(call.target);
-    }
-
-    /**
-     * Decodes a mark to a mnemonic if possible.
-     */
-    private static String getMarkName(Mark mark) {
-        Field[] fields = HotSpotXirGenerator.class.getDeclaredFields();
-        for (Field f : fields) {
-            if (Modifier.isStatic(f.getModifiers()) && f.getName().startsWith("MARK_")) {
-                f.setAccessible(true);
-                try {
-                    if (f.get(null).equals(mark.id)) {
-                        return f.getName();
-                    }
-                } catch (Exception e) {
-                }
-            }
-        }
-        return "MARK:" + mark.id;
-    }
-
-    private static void addExceptionHandlersComment(CiTargetMethod tm, HexCodeFile hcf) {
-        if (!tm.exceptionHandlers.isEmpty()) {
-            String nl = HexCodeFile.NEW_LINE;
-            StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl);
-            for (CiTargetMethod.ExceptionHandler e : tm.exceptionHandlers) {
-                buf.append("    ").
-                    append(e.pcOffset).append(" -> ").
-                    append(e.handlerPos).
-                    append(nl);
-                hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]");
-                hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]");
-            }
-            hcf.addComment(0, buf.toString());
-        }
-    }
-
-    private static void addOperandComment(HexCodeFile hcf, int pos, String comment) {
-        String oldValue = hcf.addOperandComment(pos, comment);
-        assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue;
-    }
-
-    @Override
-    public String disassemble(RiResolvedMethod method) {
-        return compiler.getCompilerToVM().disassembleJava((HotSpotMethodResolved) method);
-    }
-
-    @Override
-    public RiResolvedType asRiType(CiKind kind) {
-        return (RiResolvedType) compiler.getCompilerToVM().getType(kind.toJavaClass());
-    }
-
-    @Override
-    public RiResolvedType getTypeOf(CiConstant constant) {
-        return (RiResolvedType) compiler.getCompilerToVM().getRiType(constant);
-    }
-
-    @Override
-    public boolean isExceptionType(RiResolvedType type) {
-        return type.isSubtypeOf((RiResolvedType) compiler.getCompilerToVM().getType(Throwable.class));
-    }
-
-    @Override
-    public Object registerCompilerStub(CiTargetMethod targetMethod, String name, RiCodeInfo info) {
-        return HotSpotTargetMethod.installStub(compiler, targetMethod, name, (HotSpotCodeInfo) info);
-    }
-
-    @Override
-    public int sizeOfLockData() {
-        // TODO shouldn't be hard coded
-        return 8;
-    }
-
-    @Override
-    public int sizeOfBasicObjectLock() {
-        // TODO shouldn't be hard coded
-        return 2 * 8;
-    }
-
-    @Override
-    public int basicObjectLockOffsetInBytes() {
-        return 8;
-    }
-
-    @Override
-    public boolean areConstantObjectsEqual(CiConstant x, CiConstant y) {
-        return compiler.getCompilerToVM().compareConstantObjects(x, y);
-    }
-
-    @Override
-    public RiRegisterConfig getRegisterConfig(RiMethod method) {
-        return regConfig;
-    }
-
-    /**
-     * HotSpots needs an area suitable for storing a program counter for temporary use during the deoptimization process.
-     */
-    @Override
-    public int getCustomStackAreaSize() {
-        // TODO shouldn't be hard coded
-        return 8;
-    }
-
-    @Override
-    public int getMinimumOutgoingSize() {
-        return config.runtimeCallStackSize;
-    }
-
-    @Override
-    public int getArrayLength(CiConstant array) {
-        return compiler.getCompilerToVM().getArrayLength(array);
-    }
-
-    @Override
-    public Class<?> asJavaClass(CiConstant c) {
-        return (Class<?>) c.asObject();
-    }
-
-    @Override
-    public Object asJavaObject(CiConstant c) {
-        return c.asObject();
-    }
-
-    @Override
-    public void lower(Node n, CiLoweringTool tool) {
-        if (!GraalOptions.Lower) {
-            return;
-        }
-        StructuredGraph graph = (StructuredGraph) n.graph();
-
-        if (n instanceof ArrayLengthNode) {
-            ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
-            SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.graph(), arrayLengthNode.array(), arrayLengthNode.stamp(), StructuredGraph.INVALID_GRAPH_ID);
-            graph.replaceFixedWithFixed(arrayLengthNode, safeReadArrayLength);
-            safeReadArrayLength.lower(tool);
-        } else if (n instanceof LoadFieldNode) {
-            LoadFieldNode field = (LoadFieldNode) n;
-            int displacement = ((HotSpotField) field.field()).offset();
-            assert field.kind() != CiKind.Illegal;
-            ReadNode memoryRead = graph.add(new ReadNode(field.object(), LocationNode.create(field.field(), field.field().kind(true), displacement, graph), field.stamp()));
-            memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(field.object(), false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID));
-            graph.replaceFixedWithFixed(field, memoryRead);
-            if (field.isVolatile()) {
-                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
-                graph.addBeforeFixed(memoryRead, preMembar);
-                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
-                graph.addAfterFixed(memoryRead, postMembar);
-            }
-        } else if (n instanceof StoreFieldNode) {
-            StoreFieldNode storeField = (StoreFieldNode) n;
-            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.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID));
-            memoryWrite.setStateAfter(storeField.stateAfter());
-            graph.replaceFixedWithFixed(storeField, memoryWrite);
-
-            FixedWithNextNode last = memoryWrite;
-            if (field.kind(true) == CiKind.Object && !memoryWrite.value().isNullConstant()) {
-                FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(memoryWrite.object()));
-                graph.addAfterFixed(memoryWrite, writeBarrier);
-                last = writeBarrier;
-            }
-            if (storeField.isVolatile()) {
-                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
-                graph.addBeforeFixed(memoryWrite, preMembar);
-                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
-                graph.addAfterFixed(last, postMembar);
-            }
-        } else if (n instanceof CompareAndSwapNode) {
-            // Separate out GC barrier semantics
-            CompareAndSwapNode cas = (CompareAndSwapNode) n;
-            ValueNode expected = cas.expected();
-            if (expected.kind() == CiKind.Object && !cas.newValue().isNullConstant()) {
-                RiResolvedType declaredType = cas.object().declaredType();
-                if (declaredType != null && !declaredType.isArrayClass() && declaredType.toJava() != Object.class) {
-                    // Use a field write barrier since it's not an array store
-                    FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object()));
-                    graph.addAfterFixed(cas, writeBarrier);
-                } else {
-                    // This may be an array store so use an array write barrier
-                    LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, false);
-                    graph.addAfterFixed(cas, graph.add(new ArrayWriteBarrier(cas.object(), location)));
-                }
-            }
-        } else if (n instanceof LoadIndexedNode) {
-            LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
-            GuardNode boundsCheck = createBoundsCheck(loadIndexed, tool, loadIndexed.leafGraphId());
-
-            CiKind elementKind = loadIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index());
-            ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp()));
-            memoryRead.setGuard(boundsCheck);
-            graph.replaceFixedWithFixed(loadIndexed, memoryRead);
-        } else if (n instanceof StoreIndexedNode) {
-            StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
-            GuardNode boundsCheck = createBoundsCheck(storeIndexed, tool, storeIndexed.leafGraphId());
-
-            CiKind elementKind = storeIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index());
-            ValueNode value = storeIndexed.value();
-            ValueNode array = storeIndexed.array();
-            if (elementKind == CiKind.Object && !value.isNullConstant()) {
-                // Store check!
-                if (array.exactType() != null) {
-                    RiResolvedType elementType = array.exactType().componentType();
-                    if (elementType.superType() != null) {
-                        AnchorNode anchor = graph.add(new AnchorNode());
-                        graph.addBeforeFixed(storeIndexed, anchor);
-                        ConstantNode type = ConstantNode.forCiConstant(elementType.getEncoding(Representation.ObjectHub), this, graph);
-                        value = graph.unique(new CheckCastNode(anchor, type, elementType, value));
-                    } else {
-                        assert elementType.name().equals("Ljava/lang/Object;") : elementType.name();
-                    }
-                } else {
-                    AnchorNode anchor = graph.add(new AnchorNode());
-                    graph.addBeforeFixed(storeIndexed, anchor);
-                    GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(array, false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID);
-                    FloatingReadNode arrayClass = graph.unique(new FloatingReadNode(array, null, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph), StampFactory.objectNonNull()));
-                    arrayClass.setGuard(guard);
-                    FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, null, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.arrayClassElementOffset, graph), StampFactory.objectNonNull()));
-                    value = graph.unique(new CheckCastNode(anchor, arrayElementKlass, null, value));
-                }
-            }
-            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation));
-            memoryWrite.setGuard(boundsCheck);
-            memoryWrite.setStateAfter(storeIndexed.stateAfter());
-
-            graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
-
-            if (elementKind == CiKind.Object && !value.isNullConstant()) {
-                graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation)));
-            }
-        } else if (n instanceof UnsafeLoadNode) {
-            UnsafeLoadNode load = (UnsafeLoadNode) n;
-            assert load.kind() != CiKind.Illegal;
-            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph);
-            location.setIndexScalingEnabled(false);
-            ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp()));
-            memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(load.object(), false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID));
-            graph.replaceFixedWithFixed(load, memoryRead);
-        } else if (n instanceof UnsafeStoreNode) {
-            UnsafeStoreNode store = (UnsafeStoreNode) n;
-            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.storeKind(), store.displacement(), store.offset(), graph);
-            location.setIndexScalingEnabled(false);
-            WriteNode write = graph.add(new WriteNode(store.object(), store.value(), location));
-            write.setStateAfter(store.stateAfter());
-            graph.replaceFixedWithFixed(store, write);
-            if (write.value().kind() == CiKind.Object && !write.value().isNullConstant()) {
-                FieldWriteBarrier barrier = graph.add(new FieldWriteBarrier(write.object()));
-                graph.addBeforeFixed(write, barrier);
-            }
-        } else if (n instanceof ReadHubNode) {
-            ReadHubNode objectClassNode = (ReadHubNode) n;
-            LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph);
-            ReadNode memoryRead = graph.add(new ReadNode(objectClassNode.object(), location, StampFactory.objectNonNull()));
-            memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(objectClassNode.object(), false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID));
-            graph.replaceFixed(objectClassNode, memoryRead);
-        } else {
-            assert false : "Node implementing Lowerable not handled: " + n;
-        }
-    }
-
-    private IndexedLocationNode createArrayLocation(Graph graph, CiKind elementKind, ValueNode index) {
-        return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, config.getArrayOffset(elementKind), index, graph);
-    }
-
-    private static GuardNode createBoundsCheck(AccessIndexedNode n, CiLoweringTool tool, long leafGraphId) {
-        return (GuardNode) tool.createGuard(n.graph().unique(new CompareNode(n.index(), Condition.BT, n.length())), RiDeoptReason.BoundsCheckException, RiDeoptAction.InvalidateReprofile, leafGraphId);
-    }
-
-    @Override
-    public StructuredGraph intrinsicGraph(RiResolvedMethod caller, int bci, RiResolvedMethod method, List<? extends Node> parameters) {
-        RiType holder = method.holder();
-        String fullName = method.name() + method.signature().asString();
-        String holderName = holder.name();
-        if (holderName.equals("Ljava/lang/Object;")) {
-            if (fullName.equals("getClass()Ljava/lang/Class;")) {
-                ValueNode obj = (ValueNode) parameters.get(0);
-                if (obj.stamp().nonNull() && obj.stamp().exactType() != null) {
-                    StructuredGraph graph = new StructuredGraph();
-                    ValueNode result = ConstantNode.forObject(obj.stamp().exactType().toJava(), this, graph);
-                    ReturnNode ret = graph.add(new ReturnNode(result));
-                    graph.start().setNext(ret);
-                    return graph;
-                }
-                StructuredGraph graph = new StructuredGraph();
-                LocalNode receiver = graph.unique(new LocalNode(CiKind.Object, 0));
-                SafeReadNode klassOop = safeReadHub(graph, receiver, StructuredGraph.INVALID_GRAPH_ID);
-                FloatingReadNode result = graph.unique(new FloatingReadNode(klassOop, null, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.classMirrorOffset, graph), StampFactory.objectNonNull()));
-                ReturnNode ret = graph.add(new ReturnNode(result));
-                graph.start().setNext(klassOop);
-                klassOop.setNext(ret);
-                return graph;
-            }
-        } else if (holderName.equals("Ljava/lang/Class;")) {
-            if (fullName.equals("getModifiers()I")) {
-                StructuredGraph graph = new StructuredGraph();
-                LocalNode receiver = graph.unique(new LocalNode(CiKind.Object, 0));
-                SafeReadNode klassOop = safeRead(graph, CiKind.Object, receiver, config.klassOopOffset, StampFactory.objectNonNull(), StructuredGraph.INVALID_GRAPH_ID);
-                graph.start().setNext(klassOop);
-                // TODO(thomaswue): Care about primitive classes! Crashes for primitive classes at the moment (klassOop == null)
-                FloatingReadNode result = graph.unique(new FloatingReadNode(klassOop, null, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Int, config.klassModifierFlagsOffset, graph), StampFactory.forKind(CiKind.Int)));
-                ReturnNode ret = graph.add(new ReturnNode(result));
-                klassOop.setNext(ret);
-                return graph;
-            }
-        } else if (holderName.equals("Ljava/lang/Thread;")) {
-            if (fullName.equals("currentThread()Ljava/lang/Thread;")) {
-                StructuredGraph graph = new StructuredGraph();
-                ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset))));
-                graph.start().setNext(ret);
-                return graph;
-            }
-        }
-        return null;
-    }
-
-    private SafeReadNode safeReadHub(Graph graph, ValueNode value, long leafGraphId) {
-        return safeRead(graph, CiKind.Object, value, config.hubOffset, StampFactory.objectNonNull(), leafGraphId);
-    }
-
-    private SafeReadNode safeReadArrayLength(Graph graph, ValueNode value, Stamp stamp, long leafGraphId) {
-        return safeRead(graph, CiKind.Int, value, config.arrayLengthOffset, stamp, leafGraphId);
-    }
-
-    private static SafeReadNode safeRead(Graph graph, CiKind kind, ValueNode value, int offset, Stamp stamp, long leafGraphId) {
-        return graph.add(new SafeReadNode(value, LocationNode.create(LocationNode.FINAL_LOCATION, kind, offset, graph), stamp, leafGraphId));
-    }
-
-    public RiResolvedType getType(Class<?> clazz) {
-        return (RiResolvedType) compiler.getCompilerToVM().getType(clazz);
-    }
-
-    public Object asCallTarget(Object target) {
-        return target;
-    }
-
-    public long getMaxCallTargetOffset(CiRuntimeCall rtcall) {
-        return compiler.getCompilerToVM().getMaxCallTargetOffset(rtcall);
-    }
-
-    public RiResolvedMethod getRiMethod(Method reflectionMethod) {
-        return (RiResolvedMethod) compiler.getCompilerToVM().getRiMethod(reflectionMethod);
-    }
-
-    @Override
-    public void installMethod(RiResolvedMethod method, CiTargetMethod code, RiCodeInfo info) {
-        compiler.getCompilerToVM().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), true, (HotSpotCodeInfo) info);
-    }
-
-    @Override
-    public RiCompiledMethod addMethod(RiResolvedMethod method, CiTargetMethod code) {
-        return compiler.getCompilerToVM().installMethod(new HotSpotTargetMethod(compiler, (HotSpotMethodResolved) method, code), false, null);
-    }
-
-    @Override
-    public RiRegisterConfig getGlobalStubRegisterConfig() {
-        return globalStubRegConfig;
-    }
-
-    @Override
-    public CiTargetMethod compile(RiResolvedMethod method, StructuredGraph graph) {
-        final PhasePlan plan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
-        plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-        return compiler.getCompiler().compileMethod(method, graph, -1, compiler.getCache(), plan, OptimisticOptimizations.ALL);
-    }
-
-    @Override
-    public int encodeDeoptActionAndReason(RiDeoptAction action, RiDeoptReason reason) {
-        final int actionShift = 0;
-        final int reasonShift = 3;
-
-        int actionValue = convertDeoptAction(action);
-        int reasonValue = convertDeoptReason(reason);
-        return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift)));
-    }
-
-    @Override
-    public int convertDeoptAction(RiDeoptAction 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();
-        }
-    }
-
-    @Override
-    public int convertDeoptReason(RiDeoptReason 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.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotSignature.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-import com.oracle.graal.java.*;
-
-/**
- * Represents a method signature.
- */
-public class HotSpotSignature extends CompilerObject implements RiSignature {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = -2890917956072366116L;
-    private final List<String> arguments = new ArrayList<>();
-    private final String returnType;
-    private final String originalString;
-    private RiType[] argumentTypes;
-    private RiType returnTypeCache;
-
-    public HotSpotSignature(Compiler compiler, String signature) {
-        super(compiler);
-        assert signature.length() > 0;
-        this.originalString = signature;
-
-        if (signature.charAt(0) == '(') {
-            int cur = 1;
-            while (cur < signature.length() && signature.charAt(cur) != ')') {
-                int nextCur = parseSignature(signature, cur);
-                arguments.add(signature.substring(cur, nextCur));
-                cur = nextCur;
-            }
-
-            cur++;
-            int nextCur = parseSignature(signature, cur);
-            returnType = signature.substring(cur, nextCur);
-            assert nextCur == signature.length();
-        } else {
-            returnType = null;
-        }
-    }
-
-    private static int parseSignature(String signature, int start) {
-        int cur = start;
-        char first;
-        do {
-            first = signature.charAt(cur++);
-        } while (first == '[');
-
-        switch (first) {
-            case 'L':
-                while (signature.charAt(cur) != ';') {
-                    cur++;
-                }
-                cur++;
-                break;
-            case 'V':
-            case 'I':
-            case 'B':
-            case 'C':
-            case 'D':
-            case 'F':
-            case 'J':
-            case 'S':
-            case 'Z':
-                break;
-            default:
-                assert false;
-        }
-        return cur;
-    }
-
-    @Override
-    public int argumentCount(boolean withReceiver) {
-        return arguments.size() + (withReceiver ? 1 : 0);
-    }
-
-    @Override
-    public CiKind argumentKindAt(int index, boolean architecture) {
-        return CiKind.fromTypeString(arguments.get(index));
-    }
-
-    @Override
-    public int argumentSlots(boolean withReceiver) {
-        int argSlots = 0;
-        for (int i = 0; i < argumentCount(false); i++) {
-            argSlots += FrameStateBuilder.stackSlots(argumentKindAt(i, false));
-        }
-        return argSlots + (withReceiver ? 1 : 0);
-    }
-
-    @Override
-    public RiType argumentTypeAt(int index, RiResolvedType accessingClass) {
-        if (argumentTypes == null) {
-            argumentTypes = new RiType[arguments.size()];
-        }
-        RiType type = argumentTypes[index];
-        if (type == null || !(type instanceof RiResolvedType)) {
-            type = compiler.lookupType(arguments.get(index), (HotSpotTypeResolved) accessingClass, true);
-            argumentTypes[index] = type;
-        }
-        return type;
-    }
-
-    @Override
-    public String asString() {
-        return originalString;
-    }
-
-    @Override
-    public CiKind returnKind(boolean architecture) {
-        return CiKind.fromTypeString(returnType);
-    }
-
-    @Override
-    public RiType returnType(RiType accessingClass) {
-        if (returnTypeCache == null) {
-            returnTypeCache = compiler.lookupType(returnType, (HotSpotTypeResolved) accessingClass, false);
-        }
-        return returnTypeCache;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotSignature<" + originalString + ">";
-    }
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotType.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-
-/**
- * Common interface for all HotSpot RiType-implementations.
- */
-public abstract class HotSpotType extends CompilerObject implements RiType {
-    /**
-     * 
-     */
-    private static final long serialVersionUID = -4252886265301910771L;
-    protected String name;
-
-    protected HotSpotType(Compiler compiler) {
-        super(compiler);
-    }
-
-    @Override
-    public final String name() {
-        return name;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypePrimitive.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.Compiler;
-
-/**
- * Implementation of RiType for primitive HotSpot types.
- */
-public final class HotSpotTypePrimitive extends HotSpotType implements RiResolvedType {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = -6208552348908071473L;
-    private CiKind kind;
-
-
-    public HotSpotTypePrimitive(Compiler compiler, CiKind kind) {
-        super(compiler);
-        this.kind = kind;
-        this.name = String.valueOf(Character.toUpperCase(kind.typeChar));
-    }
-
-    @Override
-    public int accessFlags() {
-        assert kind != null && kind.toJavaClass() != null;
-        return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
-    }
-
-    @Override
-    public RiResolvedType arrayOf() {
-        return (RiResolvedType) compiler.getCompilerToVM().getPrimitiveArrayType(kind);
-    }
-
-    @Override
-    public RiResolvedType componentType() {
-        return null;
-    }
-
-    @Override
-    public RiResolvedType exactType() {
-        return this;
-    }
-
-    @Override
-    public RiResolvedType superType() {
-        return null;
-    }
-
-    @Override
-    public RiResolvedType leastCommonAncestor(RiResolvedType otherType) {
-        return null;
-    }
-
-    @Override
-    public CiConstant getEncoding(Representation r) {
-        throw GraalInternalError.unimplemented("HotSpotTypePrimitive.getEncoding");
-    }
-
-    @Override
-    public CiKind getRepresentationKind(Representation r) {
-        return kind;
-    }
-
-    @Override
-    public boolean hasFinalizableSubclass() {
-        return false;
-    }
-
-    @Override
-    public boolean hasFinalizer() {
-        return false;
-    }
-
-    @Override
-    public boolean hasSubclass() {
-        return false;
-    }
-
-    @Override
-    public boolean isArrayClass() {
-        return false;
-    }
-
-    @Override
-    public boolean isInitialized() {
-        return true;
-    }
-
-    @Override
-    public boolean isInstance(CiConstant obj) {
-        return false;
-    }
-
-    @Override
-    public boolean isInstanceClass() {
-        return false;
-    }
-
-    @Override
-    public boolean isInterface() {
-        return false;
-    }
-
-    @Override
-    public boolean isSubtypeOf(RiResolvedType other) {
-        return false;
-    }
-
-    @Override
-    public CiKind kind(boolean architecture) {
-        return kind;
-    }
-
-    @Override
-    public RiResolvedMethod resolveMethodImpl(RiResolvedMethod method) {
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotTypePrimitive<" + kind + ">";
-    }
-
-    @Override
-    public RiResolvedType uniqueConcreteSubtype() {
-        return this;
-    }
-
-    @Override
-    public RiResolvedMethod uniqueConcreteMethod(RiResolvedMethod method) {
-        return null;
-    }
-
-    @Override
-    public RiResolvedField[] declaredFields() {
-        return null;
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        return toJava().getAnnotation(annotationClass);
-    }
-
-    @Override
-    public Class< ? > toJava() {
-        return kind.toJavaClass();
-    }
-
-    @Override
-    public RiResolvedType resolve(RiResolvedType accessingClass) {
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolved.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.server.*;
-
-public interface HotSpotTypeResolved extends RiResolvedType, Remote {
-
-    String toString();
-
-    RiConstantPool constantPool();
-
-    int instanceSize();
-
-    RiField createRiField(String name, RiType type, int offset, int flags);
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-
-/**
- * Implementation of RiType for resolved non-primitive HotSpot classes.
- */
-public final class HotSpotTypeResolvedImpl extends HotSpotType implements HotSpotTypeResolved {
-
-    private static final long serialVersionUID = 3481514353553840471L;
-
-    private Class javaMirror;
-    private String simpleName;
-    private int accessFlags;
-    private boolean hasFinalizer;
-    private boolean hasSubclass;
-    private boolean hasFinalizableSubclass;
-    private boolean isArrayClass;
-    private boolean isInstanceClass;
-    private boolean isInterface;
-    private int instanceSize;
-    private HashMap<Long, RiResolvedField> fieldCache;
-    private RiResolvedType superType;
-    private boolean superTypeSet;
-    private RiResolvedField[] fields;
-    private RiConstantPool constantPool;
-    private boolean isInitialized;
-    private RiResolvedType arrayOfType;
-
-    private HotSpotTypeResolvedImpl() {
-        super(null);
-    }
-
-    @Override
-    public int accessFlags() {
-        return accessFlags;
-    }
-
-    @Override
-    public RiResolvedType arrayOf() {
-        if (arrayOfType == null) {
-           arrayOfType = (RiResolvedType) compiler.getCompilerToVM().RiType_arrayOf(this);
-        }
-        return arrayOfType;
-    }
-
-    @Override
-    public RiResolvedType componentType() {
-        assert isArrayClass();
-        return (RiResolvedType) compiler.getCompilerToVM().RiType_componentType(this);
-    }
-
-    @Override
-    public RiResolvedType uniqueConcreteSubtype() {
-        if (isArrayClass()) {
-            return Modifier.isFinal(componentType().accessFlags()) ? this : null;
-        } else {
-            return (RiResolvedType) compiler.getCompilerToVM().RiType_uniqueConcreteSubtype(this);
-        }
-    }
-
-    @Override
-    public RiResolvedType superType() {
-        if (!superTypeSet) {
-            superType = (RiResolvedType) compiler.getCompilerToVM().RiType_superType(this);
-            superTypeSet = true;
-        }
-        return superType;
-    }
-
-    @Override
-    public RiResolvedType leastCommonAncestor(RiResolvedType otherType) {
-        if (otherType instanceof HotSpotTypePrimitive) {
-            return null;
-        } else {
-            return (RiResolvedType) compiler.getCompilerToVM().RiType_leastCommonAncestor(this, (HotSpotTypeResolved) otherType);
-        }
-    }
-
-    @Override
-    public RiResolvedType exactType() {
-        if (Modifier.isFinal(accessFlags)) {
-            return this;
-        }
-        return null;
-    }
-
-    @Override
-    public CiConstant getEncoding(Representation r) {
-        switch (r) {
-            case JavaClass:
-                return CiConstant.forObject(javaMirror);
-            case ObjectHub:
-                return CiConstant.forObject(this);
-            case StaticFields:
-                return CiConstant.forObject(javaMirror);
-            case TypeInfo:
-                return CiConstant.forObject(this);
-            default:
-                return null;
-        }
-    }
-
-    @Override
-    public CiKind getRepresentationKind(Representation r) {
-        return CiKind.Object;
-    }
-
-    @Override
-    public boolean hasFinalizableSubclass() {
-        return hasFinalizableSubclass;
-    }
-
-    @Override
-    public boolean hasFinalizer() {
-        return hasFinalizer;
-    }
-
-    @Override
-    public boolean hasSubclass() {
-        return hasSubclass;
-    }
-
-    @Override
-    public boolean isArrayClass() {
-        return isArrayClass;
-    }
-
-    @Override
-    public boolean isInitialized() {
-        if (!isInitialized) {
-            isInitialized = compiler.getCompilerToVM().RiType_isInitialized(this);
-        }
-        return isInitialized;
-    }
-
-    @Override
-    public boolean isInstance(CiConstant obj) {
-        return javaMirror.isInstance(obj);
-    }
-
-    @Override
-    public boolean isInstanceClass() {
-        return isInstanceClass;
-    }
-
-    @Override
-    public boolean isInterface() {
-        return isInterface;
-    }
-
-    @Override
-    public boolean isSubtypeOf(RiResolvedType other) {
-        if (other instanceof HotSpotTypeResolved) {
-            return compiler.getCompilerToVM().RiType_isSubtypeOf(this, other);
-        }
-        // No resolved type is a subtype of an unresolved type.
-        return false;
-    }
-
-    @Override
-    public CiKind kind(boolean architecture) {
-        return CiKind.Object;
-    }
-
-    @Override
-    public RiResolvedMethod resolveMethodImpl(RiResolvedMethod method) {
-        assert method instanceof HotSpotMethod;
-        return (RiResolvedMethod) compiler.getCompilerToVM().RiType_resolveMethodImpl(this, method.name(), method.signature().asString());
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotType<" + simpleName + ", resolved>";
-    }
-
-    @Override
-    public RiConstantPool constantPool() {
-        if (constantPool == null) {
-            constantPool = new HotSpotConstantPool(compiler, this);
-        }
-        return constantPool;
-    }
-
-    @Override
-    public int instanceSize() {
-        return instanceSize;
-    }
-
-    @Override
-    public synchronized RiResolvedField createRiField(String fieldName, RiType type, int offset, int flags) {
-        RiResolvedField result = null;
-
-        long id = offset + ((long) flags << 32);
-
-        // (thomaswue) Must cache the fields, because the local load elimination only works if the objects from two field lookups are equal.
-        if (fieldCache == null) {
-            fieldCache = new HashMap<>(8);
-        } else {
-            result = fieldCache.get(id);
-        }
-
-        if (result == null) {
-            result = new HotSpotField(compiler, this, fieldName, type, offset, flags);
-            fieldCache.put(id, result);
-        } else {
-            assert result.name().equals(fieldName);
-            assert result.accessFlags() == flags;
-        }
-
-        return result;
-    }
-
-    @Override
-    public RiResolvedMethod uniqueConcreteMethod(RiResolvedMethod method) {
-        return ((HotSpotMethodResolved) method).uniqueConcreteMethod();
-    }
-
-    @Override
-    public RiResolvedField[] declaredFields() {
-        if (fields == null) {
-            fields = compiler.getCompilerToVM().RiType_fields(this);
-        }
-        return fields;
-    }
-
-    @Override
-    public Class< ? > toJava() {
-        return javaMirror;
-    }
-
-    @Override
-    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
-        return toJava().getAnnotation(annotationClass);
-    }
-
-    @Override
-    public RiResolvedType resolve(RiResolvedType accessingClass) {
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeUnresolved.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.hotspot.Compiler;
-
-/**
- * Implementation of RiType for unresolved HotSpot classes.
- */
-public class HotSpotTypeUnresolved extends HotSpotType {
-
-    private static final long serialVersionUID = -2320936267633521314L;
-    public final String simpleName;
-    public final int dimensions;
-
-    /**
-     * Creates a new unresolved type for a specified type descriptor.
-     */
-    public HotSpotTypeUnresolved(Compiler compiler, String name) {
-        super(compiler);
-        assert name.length() > 0 : "name cannot be empty";
-
-        int dims = 0;
-        int startIndex = 0;
-        while (name.charAt(startIndex) == '[') {
-            startIndex++;
-            dims++;
-        }
-
-        // Decode name if necessary.
-        if (name.charAt(name.length() - 1) == ';') {
-            assert name.charAt(startIndex) == 'L';
-            this.simpleName = name.substring(startIndex + 1, name.length() - 1);
-            this.name = name;
-        } else {
-            this.simpleName = name;
-            this.name = getFullName(name, dims);
-        }
-
-        this.dimensions = dims;
-    }
-
-    public HotSpotTypeUnresolved(Compiler compiler, String name, int dimensions) {
-        super(compiler);
-        assert dimensions >= 0;
-        this.simpleName = name;
-        this.dimensions = dimensions;
-        this.name = getFullName(name, dimensions);
-    }
-
-    private static String getFullName(String name, int dimensions) {
-        StringBuilder str = new StringBuilder(name.length() + dimensions + 2);
-        for (int i = 0; i < dimensions; i++) {
-            str.append('[');
-        }
-        str.append('L').append(name).append(';');
-        return str.toString();
-    }
-
-    @Override
-    public RiType componentType() {
-        assert dimensions > 0 : "no array class" + name();
-        return new HotSpotTypeUnresolved(compiler, simpleName, dimensions - 1);
-    }
-
-    @Override
-    public RiType arrayOf() {
-        return new HotSpotTypeUnresolved(compiler, simpleName, dimensions + 1);
-    }
-
-    @Override
-    public CiKind kind(boolean architecture) {
-        return CiKind.Object;
-    }
-
-    @Override
-    public int hashCode() {
-        return simpleName.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        return o == this;
-    }
-
-    @Override
-    public String toString() {
-        return "HotSpotType<" + simpleName + ", unresolved>";
-    }
-
-    @Override
-    public CiKind getRepresentationKind(RiType.Representation r) {
-        return CiKind.Object;
-    }
-
-    @Override
-    public RiResolvedType resolve(RiResolvedType accessingClass) {
-        return (RiResolvedType) compiler.lookupType(name, (HotSpotTypeResolved) accessingClass, true);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1096 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-import static com.oracle.graal.hotspot.ri.TemplateFlag.*;
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.CiAddress.Scale;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.*;
-import com.oracle.max.cri.xir.CiXirAssembler.XirConstant;
-import com.oracle.max.cri.xir.CiXirAssembler.XirLabel;
-import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
-import com.oracle.max.cri.xir.CiXirAssembler.XirOperand;
-import com.oracle.max.cri.xir.CiXirAssembler.XirParameter;
-
-public class HotSpotXirGenerator implements RiXirGenerator {
-
-    // this needs to correspond to graal_CodeInstaller.hpp
-    // @formatter:off
-    public static final Integer MARK_VERIFIED_ENTRY            = 0x0001;
-    public static final Integer MARK_UNVERIFIED_ENTRY          = 0x0002;
-    public static final Integer MARK_OSR_ENTRY                 = 0x0003;
-    public static final Integer MARK_UNWIND_ENTRY              = 0x0004;
-    public static final Integer MARK_EXCEPTION_HANDLER_ENTRY   = 0x0005;
-    public static final Integer MARK_DEOPT_HANDLER_ENTRY       = 0x0006;
-
-    public static final Integer MARK_STATIC_CALL_STUB          = 0x1000;
-
-    public static final Integer MARK_INVOKEINTERFACE           = 0x2001;
-    public static final Integer MARK_INVOKESTATIC              = 0x2002;
-    public static final Integer MARK_INVOKESPECIAL             = 0x2003;
-    public static final Integer MARK_INVOKEVIRTUAL             = 0x2004;
-
-    public static final Integer MARK_IMPLICIT_NULL             = 0x3000;
-    public static final Integer MARK_POLL_NEAR                 = 0x3001;
-    public static final Integer MARK_POLL_RETURN_NEAR          = 0x3002;
-    public static final Integer MARK_POLL_FAR                  = 0x3003;
-    public static final Integer MARK_POLL_RETURN_FAR           = 0x3004;
-
-    // @formatter:on
-
-    private final HotSpotVMConfig config;
-    private final CiTarget target;
-    private final RiRegisterConfig registerConfig;
-    private final Compiler compiler;
-
-
-    private CiXirAssembler globalAsm;
-
-    public HotSpotXirGenerator(HotSpotVMConfig config, CiTarget target, RiRegisterConfig registerConfig, Compiler compiler) {
-        this.config = config;
-        this.target = target;
-        this.registerConfig = registerConfig;
-        this.compiler = compiler;
-    }
-
-    private XirConstant wordConst(CiXirAssembler asm, long value) {
-        if (target.wordKind == CiKind.Long) {
-            return asm.createConstant(CiConstant.forLong(value));
-        } else {
-            assert target.wordKind == CiKind.Int;
-            return asm.createConstant(CiConstant.forInt((int) value));
-        }
-    }
-
-    private XirArgument wordArg(long value) {
-        if (target.wordKind == CiKind.Long) {
-            return XirArgument.forLong(value);
-        } else {
-            assert target.wordKind == CiKind.Int;
-            return XirArgument.forInt((int) value);
-        }
-    }
-
-    private SimpleTemplates invokeInterfaceTemplates = new SimpleTemplates(NULL_CHECK) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart();
-            XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
-            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
-            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
-            XirOperand tempO = asm.createRegister("tempO", CiKind.Object, AMD64.rax);
-
-            if (is(NULL_CHECK, flags)) {
-                asm.mark(MARK_IMPLICIT_NULL);
-                asm.pload(target.wordKind, temp, receiver, true);
-            }
-            asm.mark(MARK_INVOKEINTERFACE);
-            asm.mov(tempO, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
-
-            return asm.finishTemplate(addr, "invokeinterface");
-        }
-    };
-
-    private SimpleTemplates invokeVirtualTemplates = new SimpleTemplates(NULL_CHECK) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart();
-            XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
-            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
-            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
-            XirOperand tempO = asm.createRegister("tempO", CiKind.Object, AMD64.rax);
-
-            if (is(NULL_CHECK, flags)) {
-                asm.mark(MARK_IMPLICIT_NULL);
-                asm.pload(target.wordKind, temp, receiver, true);
-            }
-            asm.mark(MARK_INVOKEVIRTUAL);
-            asm.mov(tempO, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ)));
-
-            return asm.finishTemplate(addr, "invokevirtual");
-        }
-    };
-
-    private IndexTemplates inlinedInvokeVirtualTemplates = new IndexTemplates(NULL_CHECK) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, int vtableEntryOffset) {
-            asm.restart();
-            XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
-            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
-            XirOperand method = asm.createRegisterTemp("method", CiKind.Object, AMD64.rbx);
-
-            // load class from receiver
-            if (is(NULL_CHECK, flags)) {
-                asm.mark(MARK_IMPLICIT_NULL);
-            }
-            asm.pload(target.wordKind, temp, receiver, asm.i(config.hubOffset), true);
-            // load vtable entry
-            asm.pload(target.wordKind, method, temp, asm.i(vtableEntryOffset), false);
-            // load entry point from methodOop
-            asm.mark(MARK_IMPLICIT_NULL);
-            asm.pload(target.wordKind, temp, method, asm.i(config.methodCompiledEntryOffset), true);
-            asm.mark(MARK_INVOKEVIRTUAL);
-
-            return asm.finishTemplate(temp, "invokevirtual");
-        }
-    };
-
-    private SimpleTemplates invokeSpecialTemplates = new SimpleTemplates(NULL_CHECK) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart();
-            XirParameter receiver = asm.createInputParameter("receiver", CiKind.Object);
-            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
-            XirOperand temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.rax);
-            XirLabel stub = asm.createOutOfLineLabel("call stub");
-
-            if (is(NULL_CHECK, flags)) {
-                asm.mark(MARK_IMPLICIT_NULL);
-                asm.pload(target.wordKind, temp, receiver, true);
-            }
-            asm.mark(MARK_INVOKESPECIAL);
-
-            // -- out of line -------------------------------------------------------
-            asm.bindOutOfLine(stub);
-            XirOperand method = asm.createRegisterTemp("method", target.wordKind, AMD64.rbx);
-            asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
-            asm.mov(method, wordConst(asm, 0));
-            XirLabel dummy = asm.createOutOfLineLabel("dummy");
-            asm.jmp(dummy);
-            asm.bindOutOfLine(dummy);
-
-            return asm.finishTemplate(addr, "invokespecial");
-        }
-    };
-
-    private SimpleTemplates invokeStaticTemplates = new SimpleTemplates() {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart();
-            XirParameter addr = asm.createConstantInputParameter("addr", target.wordKind);
-
-            XirLabel stub = asm.createOutOfLineLabel("call stub");
-            asm.mark(MARK_INVOKESTATIC);
-
-            // -- out of line -------------------------------------------------------
-            asm.bindOutOfLine(stub);
-            XirOperand method = asm.createRegisterTemp("method", target.wordKind, AMD64.rbx);
-            asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE);
-            asm.mov(method, wordConst(asm, 0));
-            XirLabel dummy = asm.createOutOfLineLabel("dummy");
-            asm.jmp(dummy);
-            asm.bindOutOfLine(dummy);
-
-            return asm.finishTemplate(addr, "invokestatic");
-        }
-    };
-
-    private SimpleTemplates monitorEnterTemplates = new SimpleTemplates(NULL_CHECK) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart(CiKind.Void);
-            XirParameter object = asm.createInputParameter("object", CiKind.Object);
-            XirParameter lock = asm.createInputParameter("lock", target.wordKind);
-
-            if (is(NULL_CHECK, flags)) {
-                asm.mark(MARK_IMPLICIT_NULL);
-                asm.pload(target.wordKind, asm.createTemp("temp", target.wordKind), object, true);
-            }
-
-
-            // (thomaswue) It is important to use for this runtime call the debug info AFTER the monitor enter. Otherwise the monitor object
-            // is not correctly garbage collected.
-            final boolean useInfoAfter = true;
-
-            if (config.useFastLocking) {
-                useRegisters(asm, AMD64.rax, AMD64.rbx);
-                useRegisters(asm, getGeneralParameterRegister(0));
-                useRegisters(asm, getGeneralParameterRegister(1));
-                asm.callRuntime(config.fastMonitorEnterStub, null, useInfoAfter, object, lock);
-            } else {
-                asm.reserveOutgoingStack(target.wordSize * 2);
-                XirOperand rsp = asm.createRegister("rsp", target.wordKind, asRegister(AMD64.RSP));
-                asm.pstore(CiKind.Object, rsp, asm.i(target.wordSize), object, false);
-                asm.pstore(target.wordKind, rsp, asm.i(0), lock, false);
-                asm.callRuntime(config.monitorEnterStub, null, useInfoAfter);
-            }
-
-            return asm.finishTemplate("monitorEnter");
-        }
-    };
-
-    private CiRegister getGeneralParameterRegister(int index) {
-        return registerConfig.getCallingConventionRegisters(CiCallingConvention.Type.RuntimeCall, RegisterFlag.CPU)[index];
-    }
-
-    private SimpleTemplates monitorExitTemplates = new SimpleTemplates(NULL_CHECK) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            asm.restart(CiKind.Void);
-            XirParameter object = asm.createInputParameter("object", CiKind.Object);
-            XirParameter lock = asm.createInputParameter("lock", target.wordKind);
-
-            if (config.useFastLocking) {
-                useRegisters(asm, AMD64.rax, AMD64.rbx);
-                useRegisters(asm, getGeneralParameterRegister(0));
-                useRegisters(asm, getGeneralParameterRegister(1));
-                asm.callRuntime(config.fastMonitorExitStub, null, object, lock);
-            } else {
-                asm.reserveOutgoingStack(target.wordSize);
-                asm.pstore(target.wordKind, asm.createRegister("rsp", target.wordKind, asRegister(AMD64.RSP)), asm.i(0), lock, false);
-                asm.callRuntime(config.monitorExitStub, null);
-            }
-
-            return asm.finishTemplate("monitorExit");
-        }
-    };
-
-    private final IndexTemplates newInstanceTemplates = new IndexTemplates() {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, int size) {
-            XirOperand result = asm.restart(target.wordKind);
-            XirOperand type = asm.createInputParameter("type", CiKind.Object);
-
-            XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx);
-            XirOperand temp1o = asm.createRegister("temp1o", CiKind.Object, AMD64.rcx);
-            XirOperand temp2 = asm.createRegisterTemp("temp2", target.wordKind, AMD64.rbx);
-            XirOperand temp2i = asm.createRegister("temp2i", CiKind.Int, AMD64.rbx);
-            useRegisters(asm, AMD64.rsi);
-            XirLabel tlabFull = asm.createOutOfLineLabel("tlab full");
-            XirLabel resume = asm.createInlineLabel("resume");
-
-            // check if the class is already initialized
-            asm.pload(CiKind.Int, temp2i, type, asm.i(config.klassStateOffset), false);
-            asm.jneq(tlabFull, temp2i, asm.i(config.klassStateFullyInitialized));
-
-            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
-            asm.pload(target.wordKind, result, thread, asm.i(config.threadTlabTopOffset), false);
-            asm.add(temp1, result, wordConst(asm, size));
-            asm.pload(target.wordKind, temp2, thread, asm.i(config.threadTlabEndOffset), false);
-
-            asm.jgt(tlabFull, temp1, temp2);
-            asm.pstore(target.wordKind, thread, asm.i(config.threadTlabTopOffset), temp1, false);
-
-            asm.bindInline(resume);
-
-            asm.pload(target.wordKind, temp1, type, asm.i(config.instanceHeaderPrototypeOffset), false);
-            asm.pstore(target.wordKind, result, temp1, false);
-            asm.mov(temp1o, type); // need a temporary register since Intel cannot store 64-bit constants to memory
-            asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), temp1o, false);
-
-            if (size > 2 * target.wordSize) {
-                asm.mov(temp1, wordConst(asm, 0));
-                for (int offset = 2 * target.wordSize; offset < size; offset += target.wordSize) {
-                    asm.pstore(target.wordKind, result, asm.i(offset), temp1, false);
-                }
-            }
-
-            // -- out of line -------------------------------------------------------
-            asm.bindOutOfLine(tlabFull);
-            XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx);
-            asm.mov(arg, type);
-            useRegisters(asm, AMD64.rax);
-            asm.callRuntime(config.newInstanceStub, result);
-            asm.jmp(resume);
-
-            return asm.finishTemplate("new instance");
-        }
-    };
-
-    private SimpleTemplates newObjectArrayTemplates = new SimpleTemplates() {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags) {
-            emitNewTypeArray(asm, CiKind.Object, config.useFastNewObjectArray, config.newObjectArrayStub);
-            return asm.finishTemplate("newObjectArray");
-        }
-    };
-
-    private void emitNewTypeArray(CiXirAssembler asm, CiKind kind, boolean useFast, long slowPathStub) {
-        XirOperand result = asm.restart(target.wordKind);
-
-        XirParameter lengthParam = asm.createInputParameter("length", CiKind.Int, true);
-
-        XirOperand length = asm.createRegisterTemp("length", CiKind.Int, AMD64.rbx);
-        XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rdx);
-
-        // Registers rsi, rcx, rdi, and rax are needed by the runtime call.
-        // Hub needs to be on rdx, length on rbx.
-        XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx);
-        XirOperand temp1o = asm.createRegister("temp1o", CiKind.Object, AMD64.rcx);
-        XirOperand temp2 = asm.createRegisterTemp("temp2", target.wordKind, AMD64.rax);
-        XirOperand temp3 = asm.createRegisterTemp("temp3", target.wordKind, AMD64.rdi);
-        XirOperand size = asm.createRegisterTemp("size", CiKind.Int, AMD64.rsi);
-
-        asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object));
-        asm.mov(length, lengthParam);
-
-        if (useFast) {
-
-            XirLabel slowPath = asm.createOutOfLineLabel("slowPath");
-
-            XirLabel done = asm.createInlineLabel("done");
-
-            // Check for negative array size.
-            // TODO: Also check for upper bound
-            asm.jlt(slowPath, length, asm.i(0));
-
-            final int aligning = target.wordSize;
-            final int arrayLengthOffset = target.wordSize * 2;
-            final int arrayElementOffset = config.getArrayOffset(kind);
-
-            // Calculate aligned size
-            asm.mov(size, length);
-            int scale = CiUtil.log2(target.sizeInBytes(kind));
-            if (scale != 0) {
-                asm.shl(size, size, asm.i(scale));
-            }
-            asm.add(size, size, asm.i(arrayElementOffset + aligning - 1));
-            long mask = 0xFFFFFFFFL;
-            mask <<= CiUtil.log2(aligning);
-            asm.and(size, size, asm.i((int) mask));
-
-            // Try tlab allocation
-            XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15);
-            asm.pload(target.wordKind, result, thread, asm.i(config.threadTlabTopOffset), false);
-            asm.add(temp1, result, size);
-            asm.pload(target.wordKind, temp2, thread, asm.i(config.threadTlabEndOffset), false);
-            asm.jgt(slowPath, temp1, temp2);
-            asm.pstore(target.wordKind, thread, asm.i(config.threadTlabTopOffset), temp1, false);
-
-            // Now the new object is in result, store mark word and klass
-            asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false);
-            asm.pstore(target.wordKind, result, temp1, false);
-            asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory
-            asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), temp1o, false);
-
-            // Store array length
-            asm.pstore(CiKind.Int, result, asm.i(arrayLengthOffset), length, false);
-
-            // Initialize with 0
-            XirLabel top = asm.createInlineLabel("top");
-            asm.sub(size, size, asm.i(arrayElementOffset));
-            asm.shr(size, size, asm.i(Scale.Times8.log2));
-            asm.jeq(done, size, asm.i(0));
-            asm.xor(temp3, temp3, temp3);
-            asm.bindInline(top);
-            asm.pstore(target.wordKind, result, size, temp3, arrayElementOffset - target.wordSize, Scale.Times8, false);
-            asm.decAndJumpNotZero(top, size);
-
-            asm.bindInline(done);
-
-            // Slow path
-            asm.bindOutOfLine(slowPath);
-            asm.callRuntime(slowPathStub, result);
-            asm.jmp(done);
-        } else {
-            asm.callRuntime(slowPathStub, result);
-        }
-    }
-
-    private KindTemplates newTypeArrayTemplates = new KindTemplates() {
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
-            emitNewTypeArray(asm, kind, config.useFastNewTypeArray, config.newTypeArrayStub);
-            return asm.finishTemplate("newTypeArray<" + kind.toString() + ">");
-        }
-    };
-
-    private final IndexTemplates multiNewArrayTemplate = new IndexTemplates() {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, int dimensions) {
-            XirOperand result = asm.restart(CiKind.Object);
-
-            XirOperand hub = asm.createRegisterTemp("hub", CiKind.Object, AMD64.rax);
-            XirOperand rank = asm.createRegisterTemp("rank", CiKind.Int, AMD64.rbx);
-            XirOperand sizes = asm.createRegisterTemp("sizes", CiKind.Long, AMD64.rcx);
-            XirOperand thread = asm.createRegisterTemp("thread", CiKind.Long, AMD64.r15);
-            asm.add(sizes, thread, asm.l(config.threadMultiNewArrayStorage));
-            for (int i = 0; i < dimensions; i++) {
-                XirParameter length = asm.createInputParameter("length" + i, CiKind.Int, true);
-                asm.pstore(CiKind.Int, sizes, asm.i(i * target.sizeInBytes(CiKind.Int)), length, false);
-            }
-
-            asm.mov(hub, asm.createConstantInputParameter("hub", CiKind.Object));
-
-            asm.mov(rank, asm.i(dimensions));
-            // not necessary because we already have a temp in rax:  useRegisters(asm, AMD64.rax);
-            asm.callRuntime(config.newMultiArrayStub, result);
-            return asm.finishTemplate("multiNewArray" + dimensions);
-        }
-    };
-
-    private IndexTemplates checkCastTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
-            asm.restart(CiKind.Void);
-            XirParameter object = asm.createInputParameter("object", CiKind.Object);
-            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object);
-
-            XirOperand objHub = asm.createTemp("objHub", CiKind.Object);
-
-            XirLabel end = asm.createInlineLabel("end");
-            XirLabel slowPath = asm.createOutOfLineLabel("slow path");
-
-            if (is(NULL_CHECK, flags)) {
-                // null can be cast to anything
-                asm.jeq(end, object, asm.o(null));
-            }
-
-            asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false);
-            if (hintCount == 0) {
-                assert !is(EXACT_HINTS, flags);
-                checkSubtype(asm, objHub, objHub, hub);
-                asm.jeq(slowPath, objHub, asm.o(null));
-                asm.bindInline(end);
-
-                // -- out of line -------------------------------------------------------
-                asm.bindOutOfLine(slowPath);
-            } else {
-                XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
-                // if we get an exact match: succeed immediately
-                for (int i = 0; i < hintCount; i++) {
-                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object);
-                    asm.mov(scratchObject, hintHub);
-                    if (i < hintCount - 1) {
-                        asm.jeq(end, objHub, scratchObject);
-                    } else {
-                        asm.jneq(slowPath, objHub, scratchObject);
-                    }
-                }
-                asm.bindInline(end);
-
-                // -- out of line -------------------------------------------------------
-                asm.bindOutOfLine(slowPath);
-                if (!is(EXACT_HINTS, flags)) {
-                    checkSubtype(asm, objHub, objHub, hub);
-                    asm.jneq(end, objHub, asm.o(null));
-                }
-            }
-
-            RiDeoptReason deoptReason = is(EXACT_HINTS, flags) ? RiDeoptReason.OptimizedTypeCheckViolated : RiDeoptReason.ClassCastException;
-            XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10);
-            asm.mov(scratch, wordConst(asm, compiler.getRuntime().encodeDeoptActionAndReason(RiDeoptAction.InvalidateReprofile, deoptReason)));
-            asm.callRuntime(CiRuntimeCall.Deoptimize, null);
-            asm.shouldNotReachHere();
-
-            return asm.finishTemplate("checkcast");
-        }
-    };
-
-    private IndexTemplates instanceOfTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
-            asm.restart(CiKind.Void);
-            XirParameter object = asm.createInputParameter("object", CiKind.Object);
-            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object);
-
-            XirOperand objHub = asm.createTemp("objHub", CiKind.Object);
-
-            XirLabel trueSucc = asm.createInlineLabel(XirLabel.TrueSuccessor);
-            XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor);
-
-            if (is(NULL_CHECK, flags)) {
-                // null isn't "instanceof" anything
-                asm.jeq(falseSucc, object, asm.o(null));
-            }
-
-            asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false);
-            if (hintCount == 0) {
-                assert !is(EXACT_HINTS, flags);
-                checkSubtype(asm, objHub, objHub, hub);
-                asm.jeq(falseSucc, objHub, asm.o(null));
-                asm.jmp(trueSucc);
-            } else {
-                XirLabel slowPath = null;
-                XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
-
-                // if we get an exact match: succeed immediately
-                for (int i = 0; i < hintCount; i++) {
-                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object);
-                    asm.mov(scratchObject, hintHub);
-                    if (i < hintCount - 1) {
-                        asm.jeq(trueSucc, objHub, scratchObject);
-                    } else {
-                        if (is(EXACT_HINTS, flags)) {
-                            asm.jneq(falseSucc, objHub, scratchObject);
-                            asm.jmp(trueSucc);
-                        } else {
-                            slowPath = asm.createOutOfLineLabel("slow path");
-                            asm.jneq(slowPath, objHub, scratchObject);
-                            asm.jmp(trueSucc);
-                        }
-                    }
-                }
-
-                // -- out of line -------------------------------------------------------
-                if (slowPath != null) {
-                    asm.bindOutOfLine(slowPath);
-                    checkSubtype(asm, objHub, objHub, hub);
-                    asm.jeq(falseSucc, objHub, asm.o(null));
-                    asm.jmp(trueSucc);
-                }
-            }
-
-            return asm.finishTemplate("instanceof");
-        }
-    };
-
-    private IndexTemplates materializeInstanceOfTemplates = new IndexTemplates(NULL_CHECK, EXACT_HINTS) {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, int hintCount) {
-            XirOperand result = asm.restart(CiKind.Int);
-            XirParameter object = asm.createInputParameter("object", CiKind.Object);
-            final XirOperand hub = is(EXACT_HINTS, flags) ? null : asm.createConstantInputParameter("hub", CiKind.Object);
-            XirOperand trueValue = asm.createInputParameter("trueValue", CiKind.Int);
-            XirOperand falseValue = asm.createInputParameter("falseValue", CiKind.Int);
-
-            XirOperand objHub = asm.createTemp("objHub", CiKind.Object);
-
-            XirLabel end = asm.createInlineLabel("end");
-            XirLabel falseSucc = asm.createInlineLabel("ko");
-
-            if (is(NULL_CHECK, flags)) {
-                // null isn't "instanceof" anything
-                asm.jeq(falseSucc, object, asm.o(null));
-            }
-
-            asm.pload(CiKind.Object, objHub, object, asm.i(config.hubOffset), false);
-            asm.mov(result, trueValue);
-
-            if (hintCount == 0) {
-                assert !is(EXACT_HINTS, flags);
-                checkSubtype(asm, objHub, objHub, hub);
-                asm.jneq(end, objHub, asm.o(null));
-                asm.bindInline(falseSucc);
-                asm.mov(result, falseValue);
-                asm.bindInline(end);
-            } else {
-                XirLabel slowPath = null;
-                XirOperand scratchObject = asm.createRegisterTemp("scratch", CiKind.Object, AMD64.r10);
-
-                // if we get an exact match: succeed immediately
-                for (int i = 0; i < hintCount; i++) {
-                    XirParameter hintHub = asm.createConstantInputParameter("hintHub" + i, CiKind.Object);
-                    asm.mov(scratchObject, hintHub);
-                    if (i < hintCount - 1) {
-                        asm.jeq(end, objHub, scratchObject);
-                    } else {
-                        if (is(EXACT_HINTS, flags)) {
-                            asm.jeq(end, objHub, scratchObject);
-                        } else {
-                            slowPath = asm.createOutOfLineLabel("slow path");
-                            asm.jeq(end, objHub, scratchObject);
-                            asm.jmp(slowPath);
-                        }
-                    }
-                }
-                asm.bindInline(falseSucc);
-                asm.mov(result, falseValue);
-                asm.bindInline(end);
-
-                // -- out of line -------------------------------------------------------
-                if (slowPath != null) {
-                    asm.bindOutOfLine(slowPath);
-                    checkSubtype(asm, objHub, objHub, hub);
-                    asm.jeq(falseSucc, objHub, asm.o(null));
-                    asm.jmp(end);
-                }
-            }
-
-            return asm.finishTemplate("instanceof");
-        }
-    };
-
-    private KindTemplates arrayCopyTemplates = new KindTemplates() {
-
-        @Override
-        protected XirTemplate create(CiXirAssembler asm, long flags, CiKind kind) {
-            asm.restart(CiKind.Void);
-            XirParameter src = asm.createInputParameter("src", CiKind.Object);
-            XirParameter srcPos = asm.createInputParameter("srcPos", CiKind.Int, true);
-            XirParameter dest = asm.createInputParameter("dest", CiKind.Object);
-            XirParameter destPos = asm.createInputParameter("destPos", CiKind.Int, true);
-            XirParameter length = asm.createInputParameter("length", CiKind.Int, true);
-
-            XirOperand tempSrc = asm.createTemp("tempSrc", target.wordKind);
-            XirOperand tempDest = asm.createTemp("tempDest", target.wordKind);
-            XirOperand lengthOperand = asm.createRegisterTemp("lengthOperand", CiKind.Int, AMD64.rax);
-
-            XirOperand compHub = null;
-            XirOperand valueHub = null;
-            XirOperand temp = null;
-            XirLabel store = null;
-            XirLabel slowStoreCheck = null;
-
-            if (is(STORE_CHECK, flags) && kind == CiKind.Object) {
-                valueHub = asm.createRegisterTemp("valueHub", target.wordKind, AMD64.rdi);
-                compHub = asm.createRegisterTemp("compHub", target.wordKind, AMD64.rsi);
-                temp = asm.createRegisterTemp("temp", target.wordKind, AMD64.r10);
-            }
-
-            // Calculate the factor for the repeat move instruction.
-            int elementSize = target.sizeInBytes(kind);
-            int factor;
-            boolean wordSize;
-            if (elementSize >= target.wordSize) {
-                assert elementSize % target.wordSize == 0;
-                wordSize = true;
-                factor = elementSize / target.wordSize;
-            } else {
-                factor = elementSize;
-                wordSize = false;
-            }
-
-            // Adjust the length if the factor is not 1.
-            if (factor != 1) {
-                asm.shl(lengthOperand, length, asm.i(CiUtil.log2(factor)));
-            } else {
-                asm.mov(lengthOperand, length);
-            }
-
-            // Set the start and the end pointer.
-            asm.lea(tempSrc, src, srcPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
-            asm.lea(tempDest, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
-
-            XirLabel reverse = null;
-            XirLabel normal = null;
-
-            if (is(STORE_CHECK, flags)) {
-                reverse = asm.createInlineLabel("reverse");
-                asm.jneq(reverse, src, dest);
-            }
-
-            if (!is(STORE_CHECK, flags) && !is(INPUTS_DIFFERENT, flags) && !is(INPUTS_SAME, flags)) {
-                normal = asm.createInlineLabel("normal");
-                asm.jneq(normal, src, dest);
-            }
-
-            if (!is(INPUTS_DIFFERENT, flags)) {
-                if (reverse == null) {
-                    reverse = asm.createInlineLabel("reverse");
-                }
-                asm.jlt(reverse, srcPos, destPos);
-            }
-
-            if (!is(STORE_CHECK, flags) && !is(INPUTS_DIFFERENT, flags) && !is(INPUTS_SAME, flags)) {
-                asm.bindInline(normal);
-            }
-
-            // Everything set up => repeat mov.
-            if (wordSize) {
-                asm.repmov(tempSrc, tempDest, lengthOperand);
-            } else {
-                asm.repmovb(tempSrc, tempDest, lengthOperand);
-            }
-
-            if (!is(INPUTS_DIFFERENT, flags) || is(STORE_CHECK, flags)) {
-
-                XirLabel end = asm.createInlineLabel("end");
-                asm.jmp(end);
-
-                // Implement reverse copy, because srcPos < destPos and src == dest.
-                asm.bindInline(reverse);
-
-                if (is(STORE_CHECK, flags)) {
-                    asm.pload(CiKind.Object, compHub, dest, asm.i(config.hubOffset), false);
-                    asm.pload(CiKind.Object, compHub, compHub, asm.i(config.arrayClassElementOffset), false);
-                }
-
-                CiKind copyKind = wordSize ? CiKind.Object : CiKind.Byte;
-                XirOperand tempValue = asm.createTemp("tempValue", copyKind);
-                XirLabel start = asm.createInlineLabel("start");
-                asm.bindInline(start);
-                asm.sub(lengthOperand, lengthOperand, asm.i(1));
-                asm.jlt(end, lengthOperand, asm.i(0));
-
-                Scale scale = wordSize ? Scale.fromInt(target.wordSize) : Scale.Times1;
-                asm.pload(copyKind, tempValue, tempSrc, lengthOperand, 0, scale, false);
-
-                if (is(STORE_CHECK, flags)) {
-                    slowStoreCheck = asm.createOutOfLineLabel("slowStoreCheck");
-                    store = asm.createInlineLabel("store");
-                    asm.jeq(store, tempValue, asm.o(null)); // first check if value is null
-                    asm.pload(CiKind.Object, valueHub, tempValue, asm.i(config.hubOffset), false);
-                    asm.jneq(slowStoreCheck, compHub, valueHub); // then check component hub matches value hub
-                    asm.bindInline(store);
-                }
-
-                asm.pstore(copyKind, tempDest, lengthOperand, tempValue, 0, scale, false);
-
-                asm.jmp(start);
-                asm.bindInline(end);
-            }
-
-            if (kind == CiKind.Object) {
-                // Do write barriers
-                asm.lea(tempDest, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
-                asm.shr(tempDest, tempDest, asm.i(config.cardtableShift));
-                asm.pstore(CiKind.Boolean, wordConst(asm, config.cardtableStartAddress), tempDest, asm.b(false), false);
-
-                XirOperand tempDestEnd = tempSrc; // Reuse src temp
-                asm.lea(tempDestEnd, dest, destPos, config.getArrayOffset(kind), Scale.fromInt(elementSize));
-                asm.add(tempDestEnd, tempDestEnd, length);
-                asm.shr(tempDestEnd, tempDestEnd, asm.i(config.cardtableShift));
-
-                // Jump to out-of-line write barrier loop if the array is big.
-                XirLabel writeBarrierLoop = asm.createOutOfLineLabel("writeBarrierLoop");
-                asm.jneq(writeBarrierLoop, tempDest, tempSrc);
-                XirLabel back = asm.createInlineLabel("back");
-                asm.bindInline(back);
-
-                asm.bindOutOfLine(writeBarrierLoop);
-                asm.pstore(CiKind.Boolean, wordConst(asm, config.cardtableStartAddress), tempDestEnd, asm.b(false), false);
-                asm.sub(tempDestEnd, tempDestEnd, asm.i(1));
-                asm.jneq(writeBarrierLoop, tempDestEnd, tempDest);
-                asm.jmp(back);
-            }
-
-            if (is(STORE_CHECK, flags)) {
-                assert kind == CiKind.Object;
-                useRegisters(asm, AMD64.rax);
-                asm.bindOutOfLine(slowStoreCheck);
-                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, compiler.getRuntime().encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.ClassCastException)));
-                asm.callRuntime(CiRuntimeCall.Deoptimize, null);
-                asm.jmp(store);
-            }
-
-            return asm.finishTemplate("arraycopy<" + kind + ">");
-        }
-    };
-
-    private SimpleTemplates typeCheckTemplates = new SimpleTemplates(NULL_CHECK) {
-       @Override
-       protected XirTemplate create(CiXirAssembler asm, long flags) {
-           asm.restart(CiKind.Void);
-           XirParameter objHub = asm.createInputParameter("objectHub", CiKind.Object);
-           XirOperand hub = asm.createConstantInputParameter("hub", CiKind.Object);
-           XirLabel falseSucc = asm.createInlineLabel(XirLabel.FalseSuccessor);
-
-           XirOperand checkHub = asm.createTemp("checkHub", CiKind.Object);
-
-           if (is(NULL_CHECK, flags)) {
-               asm.mark(MARK_IMPLICIT_NULL);
-           }
-
-           asm.mov(checkHub, hub);
-           // if we get an exact match: continue.
-           asm.jneq(falseSucc, objHub, checkHub);
-
-           return asm.finishTemplate("typeCheck");
-       }
-    };
-
-    @Override
-    public XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, RiMethod method) {
-        return new XirSnippet(invokeInterfaceTemplates.get(site), receiver, wordArg(0));
-    }
-
-    @Override
-    public XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, RiMethod method, boolean megamorph) {
-        int vtableEntryOffset = 0;
-
-        if (GraalOptions.InlineVTableStubs && (GraalOptions.AlwaysInlineVTableStubs || megamorph)) {
-            HotSpotMethodResolved hsMethod = (HotSpotMethodResolved) method;
-            if (!hsMethod.holder().isInterface()) {
-                vtableEntryOffset = hsMethod.vtableEntryOffset();
-            }
-        }
-        if (vtableEntryOffset > 0) {
-            return new XirSnippet(inlinedInvokeVirtualTemplates.get(site, vtableEntryOffset), receiver);
-        } else {
-            return new XirSnippet(invokeVirtualTemplates.get(site), receiver, wordArg(0));
-        }
-    }
-
-    @Override
-    public XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, RiMethod method) {
-        return new XirSnippet(invokeSpecialTemplates.get(site), receiver, wordArg(0));
-    }
-
-    @Override
-    public XirSnippet genInvokeStatic(XirSite site, RiMethod method) {
-        return new XirSnippet(invokeStaticTemplates.get(site), wordArg(0));
-    }
-
-    @Override
-    public XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress) {
-        return new XirSnippet(monitorEnterTemplates.get(site), receiver, lockAddress);
-    }
-
-    @Override
-    public XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress) {
-        return new XirSnippet(monitorExitTemplates.get(site), receiver, lockAddress);
-    }
-
-    @Override
-    public XirSnippet genNewInstance(XirSite site, RiType type) {
-        int instanceSize = ((HotSpotTypeResolved) type).instanceSize();
-        return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(type));
-    }
-
-    @Override
-    public XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType) {
-        if (elementKind == CiKind.Object) {
-            assert arrayType instanceof RiResolvedType;
-            return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(arrayType));
-        } else {
-            assert arrayType == null;
-            RiType primitiveArrayType = compiler.getCompilerToVM().getPrimitiveArrayType(elementKind);
-            return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(primitiveArrayType));
-        }
-    }
-
-    @Override
-    public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) {
-        XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1);
-        params[lengths.length] = XirArgument.forObject(type);
-        return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length), params);
-    }
-
-    @Override
-    public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact) {
-        if (hints == null || hints.length == 0) {
-            return new XirSnippet(checkCastTemplates.get(site, 0), receiver, hub);
-        } else {
-            XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 1 : 2)];
-            int i = 0;
-            params[i++] = receiver;
-            if (!hintsExact) {
-                params[i++] = hub;
-            }
-            for (RiResolvedType hint : hints) {
-                params[i++] = XirArgument.forObject(hint);
-            }
-            XirTemplate template = hintsExact ? checkCastTemplates.get(site, hints.length, EXACT_HINTS) : checkCastTemplates.get(site, hints.length);
-            return new XirSnippet(template, params);
-        }
-    }
-
-    @Override
-    public XirSnippet genInstanceOf(XirSite site, XirArgument object, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact) {
-        if (hints == null || hints.length == 0) {
-            return new XirSnippet(instanceOfTemplates.get(site, 0), object, hub);
-        } else {
-            XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 1 : 2)];
-            int i = 0;
-            params[i++] = object;
-            if (!hintsExact) {
-                params[i++] = hub;
-            }
-            for (RiResolvedType hint : hints) {
-                params[i++] = XirArgument.forObject(hint);
-            }
-            XirTemplate template = hintsExact ? instanceOfTemplates.get(site, hints.length, EXACT_HINTS) : instanceOfTemplates.get(site, hints.length);
-            return new XirSnippet(template, params);
-        }
-    }
-
-    @Override
-    public XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument object, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, RiResolvedType[] hints, boolean hintsExact) {
-        if (hints == null || hints.length == 0) {
-            return new XirSnippet(materializeInstanceOfTemplates.get(site, 0), object, hub, trueValue, falseValue);
-        } else {
-            XirArgument[] params = new XirArgument[hints.length + (hintsExact ? 3 : 4)];
-            int i = 0;
-            params[i++] = object;
-            if (!hintsExact) {
-                params[i++] = hub;
-            }
-            params[i++] = trueValue;
-            params[i++] = falseValue;
-            for (RiResolvedType hint : hints) {
-                params[i++] = XirArgument.forObject(hint);
-            }
-            XirTemplate template = hintsExact ? materializeInstanceOfTemplates.get(site, hints.length, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hints.length);
-            return new XirSnippet(template, params);
-        }
-    }
-
-    @Override
-    public XirSnippet genArrayCopy(XirSite site, XirArgument src, XirArgument srcPos, XirArgument dest, XirArgument destPos, XirArgument length, RiType elementType, boolean inputsSame, boolean inputsDifferent) {
-        if (elementType == null) {
-            return null;
-        }
-        assert !inputsDifferent || !inputsSame;
-        XirTemplate template = null;
-        if (inputsDifferent) {
-            template = arrayCopyTemplates.get(site, elementType.kind(true), INPUTS_DIFFERENT);
-        } else if (inputsSame) {
-            template = arrayCopyTemplates.get(site, elementType.kind(true), INPUTS_SAME);
-        } else {
-            template = arrayCopyTemplates.get(site, elementType.kind(true));
-        }
-        return new XirSnippet(template, src, srcPos, dest, destPos, length);
-    }
-
-    @Override
-    public XirSnippet genTypeBranch(XirSite site, XirArgument thisHub, XirArgument otherHub, RiType type) {
-        assert type instanceof RiResolvedType;
-        return new XirSnippet(typeCheckTemplates.get(site), thisHub, otherHub);
-    }
-
-    @Override
-    public void initialize(CiXirAssembler asm) {
-        this.globalAsm = asm;
-    }
-
-    private void checkSubtype(CiXirAssembler asm, XirOperand result, XirOperand objHub, XirOperand hub) {
-        asm.push(objHub);
-        asm.push(hub);
-        asm.callRuntime(config.instanceofStub, null);
-        asm.pop(result);
-        asm.pop(result);
-    }
-
-    private static void useRegisters(CiXirAssembler asm, CiRegister... registers) {
-        if (registers != null) {
-            for (CiRegister register : registers) {
-                asm.createRegisterTemp("reg", CiKind.Illegal, register);
-            }
-        }
-    }
-
-    public boolean is(TemplateFlag check, long flags) {
-        return (flags & check.bits()) == check.bits();
-    }
-
-    /**
-     * Base class for all the ondemand template generators. It is not normally subclassed directly, but through one of
-     * its subclasses (SimpleTemplates, KindTemplates, IndexTemplates).
-     */
-    private abstract class Templates {
-
-        private ConcurrentHashMap<Long, XirTemplate> templates = new ConcurrentHashMap<>();
-        private final long mask;
-
-        /**
-         * Each flag passed to this method will cause templates with and without it to be generated.
-         */
-        public Templates(TemplateFlag... flags) {
-            this.mask = getBits((int) INDEX_MASK, null, flags);
-        }
-
-        protected abstract XirTemplate create(CiXirAssembler asm, long flags);
-
-        protected long getBits(int index, XirSite site, TemplateFlag... flags) {
-            long bits = index;
-            if (site != null) {
-                bits |= site.requiresNullCheck() ? NULL_CHECK.bits() : 0;
-                bits |= site.requiresReadBarrier() ? READ_BARRIER.bits() : 0;
-                bits |= site.requiresWriteBarrier() ? WRITE_BARRIER.bits() : 0;
-                bits |= site.requiresArrayStoreCheck() ? STORE_CHECK.bits() : 0;
-                bits |= site.requiresBoundsCheck() ? BOUNDS_CHECK.bits() : 0;
-            }
-            if (flags != null) {
-                for (TemplateFlag flag : flags) {
-                    bits |= flag.bits();
-                }
-            }
-            return bits;
-        }
-
-        protected XirTemplate getInternal(long flags) {
-            long maskedFlags = flags & mask;
-            XirTemplate template = templates.get(maskedFlags);
-            if (template == null) {
-                template = create(HotSpotXirGenerator.this.globalAsm.copy(), maskedFlags);
-                templates.put(maskedFlags, template);
-            }
-            return template;
-        }
-    }
-
-    private abstract class SimpleTemplates extends Templates {
-
-        public SimpleTemplates(TemplateFlag... flags) {
-            super(flags);
-        }
-
-        public XirTemplate get(XirSite site, TemplateFlag... flags) {
-            return getInternal(getBits(0, site, flags));
-        }
-    }
-
-    private abstract class IndexTemplates extends Templates {
-
-        public IndexTemplates(TemplateFlag... flags) {
-            super(flags);
-        }
-
-        @Override
-        protected final XirTemplate create(CiXirAssembler asm, long flags) {
-            return create(asm, flags & FLAGS_MASK, (int) (flags & INDEX_MASK));
-        }
-
-        protected abstract XirTemplate create(CiXirAssembler asm, long flags, int index);
-
-        public XirTemplate get(XirSite site, int size, TemplateFlag... flags) {
-            return getInternal(getBits(size, site, flags));
-        }
-    }
-
-    private abstract class KindTemplates extends Templates {
-
-        public KindTemplates(TemplateFlag... flags) {
-            super(flags);
-        }
-
-        @Override
-        protected final XirTemplate create(CiXirAssembler asm, long flags) {
-            return create(asm, flags & FLAGS_MASK, CiKind.VALUES[(int) (flags & INDEX_MASK)]);
-        }
-
-        protected abstract XirTemplate create(CiXirAssembler asm, long flags, CiKind kind);
-
-        public XirTemplate get(XirSite site, CiKind kind, TemplateFlag... flags) {
-            return getInternal(getBits(kind.ordinal(), site, flags));
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/TemplateFlag.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ri;
-
-enum TemplateFlag {
-    NULL_CHECK, READ_BARRIER, WRITE_BARRIER, STORE_CHECK, BOUNDS_CHECK, GIVEN_LENGTH, INPUTS_DIFFERENT, INPUTS_SAME, STATIC_METHOD, SYNCHRONIZED, EXACT_HINTS;
-
-    private static final long FIRST_FLAG = 0x0000000100000000L;
-    public static final long FLAGS_MASK = 0x0000FFFF00000000L;
-    public static final long INDEX_MASK = 0x00000000FFFFFFFFL;
-
-    public long bits() {
-        assert ((FIRST_FLAG << ordinal()) & FLAGS_MASK) != 0;
-        return FIRST_FLAG << ordinal();
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/server/CompilationServer.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.server;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import javax.net.*;
-
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.Compiler;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.logging.*;
-
-/**
- * Server side of the client/server compilation model. The server listens for connections on the hardcoded port 1199.
- */
-public class CompilationServer implements Runnable {
-
-    public static void main(String[] args) throws Exception {
-        new CompilationServer(false).run();
-    }
-
-    public interface ConnectionObserver {
-
-        void connectionStarted(Compiler compiler);
-
-        void connectionFinished(Compiler compiler);
-    }
-
-    private final boolean multiple;
-    private final ArrayList<ConnectionObserver> observers = new ArrayList<>();
-
-    /**
-     * Creates a new Compilation server. The server is activated by calling {@link #run()} directly or via a new
-     * {@link Thread}.
-     *
-     * @param multiple true if the server should server should serve an infinite amount of consecutive connections,
-     *            false if it should terminate after the first connection ends.
-     */
-    public CompilationServer(boolean multiple) {
-        this.multiple = multiple;
-        HotSpotOptions.setDefaultOptions();
-    }
-
-    public void addConnectionObserver(ConnectionObserver observer) {
-        observers.add(observer);
-    }
-
-    public void removeConnectionObserver(ConnectionObserver observer) {
-        observers.remove(observer);
-    }
-
-    public void run() {
-        final ServerSocket serverSocket;
-        try {
-            serverSocket = ServerSocketFactory.getDefault().createServerSocket(1199);
-        } catch (IOException e) {
-            throw new RuntimeException("Couldn't create compilation server", e);
-        }
-        do {
-            Socket socket = null;
-            try {
-                Logger.log("Compilation server ready, waiting for client to connect...");
-                socket = serverSocket.accept();
-                Logger.log("Connected to " + socket.getRemoteSocketAddress());
-
-                ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream());
-
-                // get the CompilerToVM proxy from the client
-                CompilerToVM toVM = (CompilerToVM) streams.getInvocation().waitForResult(false);
-
-                // return the initialized compiler to the client
-                Compiler compiler = CompilerImpl.initializeServer(toVM);
-                compiler.getCompiler();
-                streams.getInvocation().sendResult(compiler);
-
-                for (ConnectionObserver observer : observers) {
-                    observer.connectionStarted(compiler);
-                }
-
-                streams.getInvocation().waitForResult(true);
-
-                for (ConnectionObserver observer : observers) {
-                    observer.connectionFinished(compiler);
-                }
-            } catch (IOException e) {
-                e.printStackTrace();
-            } catch (ClassNotFoundException e) {
-                throw new RuntimeException(e);
-            } finally {
-                if (socket != null) {
-                    try {
-                        socket.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-        } while (multiple);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/server/InvocationSocket.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.server;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.hotspot.logging.*;
-
-/**
- * A collection of java.lang.reflect proxies that communicate over a socket connection.
- *
- * Calling a method sends the method name and the parameters through the socket. Afterwards this class waits for a
- * result. While waiting for a result three types of objects can arrive through the socket: a method invocation, a
- * method result or an exception. Method invocation can thus be recursive.
- */
-public class InvocationSocket {
-
-    private static final boolean DEBUG = false;
-    private static final boolean COUNT_CALLS = false;
-
-    private static final HashSet<String> cachedMethodNames = new HashSet<>();
-    private static final HashSet<String> forbiddenMethodNames = new HashSet<>();
-
-    static {
-        cachedMethodNames.add("name");
-        cachedMethodNames.add("kind");
-        cachedMethodNames.add("isResolved");
-        cachedMethodNames.add("getCompilerToVM");
-        cachedMethodNames.add("exactType");
-        cachedMethodNames.add("isInitialized");
-        forbiddenMethodNames.add("javaClass");
-    }
-
-    private final ObjectOutputStream output;
-    private final ObjectInputStream input;
-
-    private final Map<String, Integer> counts = new HashMap<>();
-
-    public InvocationSocket(ObjectOutputStream output, ObjectInputStream input) {
-        this.output = output;
-        this.input = input;
-
-        if (COUNT_CALLS) {
-            Runtime.getRuntime().addShutdownHook(new Thread() {
-                @Override
-                public void run() {
-                    SortedMap<Integer, String> sorted = new TreeMap<>();
-                    for (Map.Entry<String, Integer> entry : counts.entrySet()) {
-                        sorted.put(entry.getValue(), entry.getKey());
-                    }
-                    for (Map.Entry<Integer, String> entry : sorted.entrySet()) {
-                        System.out.println(entry.getKey() + ": " + entry.getValue());
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Represents one invocation of a method that is transferred via the socket connection.
-     *
-     */
-    private static class Invocation implements Serializable {
-
-        private static final long serialVersionUID = -799162779226626066L;
-
-        public Object receiver;
-        public String methodName;
-        public Object[] args;
-
-        public Invocation(Object receiver, String methodName, Object[] args) {
-            this.receiver = receiver;
-            this.methodName = methodName;
-            this.args = args;
-        }
-    }
-
-    /**
-     * Represents the result of an invocation that is transferred via the socket connection.
-     *
-     */
-    private static class Result implements Serializable {
-
-        private static final long serialVersionUID = -7496058356272415814L;
-
-        public Object result;
-
-        public Result(Object result) {
-            this.result = result;
-        }
-    }
-
-    private void incCount(String name, Object[] args) {
-        if (COUNT_CALLS) {
-            String nameAndArgCount = name + (args == null ? 0 : args.length);
-            if (counts.get(nameAndArgCount) != null) {
-                counts.put(nameAndArgCount, counts.get(nameAndArgCount) + 1);
-            } else {
-                counts.put(nameAndArgCount, 1);
-            }
-        }
-    }
-
-    /**
-     * Each instance of this class handles remote invocations for one instance of a Remote class. It will forward all
-     * interface methods to the other end of the socket and cache the results of calls to certain methods.
-     *
-     */
-    public class Handler implements InvocationHandler {
-
-        private final Object receiver;
-        private final HashMap<String, Object> cache = new HashMap<>();
-
-        public Handler(Object receiver) {
-            this.receiver = receiver;
-        }
-
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            // only interface methods can be transferred, java.lang.Object methods
-            if (method.getDeclaringClass() == Object.class) {
-                return method.invoke(receiver, args);
-            }
-            String methodName = method.getName();
-            // check if the result of this zero-arg method was cached
-            if (args == null || args.length == 0) {
-                if (cache.containsKey(methodName)) {
-                    return cache.get(methodName);
-                }
-            }
-            if (forbiddenMethodNames.contains(methodName)) {
-                throw new IllegalAccessException(methodName + " not allowed");
-            }
-            Object result = null;
-            try {
-                if (DEBUG) {
-                    Logger.startScope("invoking remote " + methodName);
-                }
-                incCount(methodName, args);
-
-                output.writeObject(new Invocation(receiver, methodName, args));
-                output.flush();
-                result = waitForResult(false);
-
-                // result caching for selected methods
-                if ((args == null || args.length == 0) && cachedMethodNames.contains(methodName)) {
-                    cache.put(methodName, result);
-                }
-                return result;
-            } catch (Throwable t) {
-                t.printStackTrace();
-                throw t;
-            } finally {
-                if (DEBUG) {
-                    Logger.endScope(" = " + result);
-                }
-            }
-        }
-    }
-
-    /**
-     * Waits for the result of a remote method invocation. Invocations that should be executed in this VM might arrive
-     * while waiting for the result, and these invocations will be executed before again waiting fort he result.
-     */
-    @SuppressWarnings("unused")
-    public Object waitForResult(boolean eofExpected) throws IOException, ClassNotFoundException {
-        while (true) {
-            Object in;
-            try {
-                in = input.readObject();
-            } catch (EOFException e) {
-                if (eofExpected) {
-                    return null;
-                }
-                throw e;
-            }
-            if (in instanceof Result) {
-                return ((Result) in).result;
-            } else if (in instanceof RuntimeException) {
-                throw (RuntimeException) in;
-            } else if (in instanceof Throwable) {
-                throw new RuntimeException((Throwable) in);
-            }
-
-            Invocation invoke = (Invocation) in;
-            Method method = null;
-            for (Class<?> clazz = invoke.receiver.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
-                for (Method m : clazz.getDeclaredMethods()) {
-                    if (invoke.methodName.equals(m.getName())) {
-                        method = m;
-                        break;
-                    }
-                }
-            }
-            if (method == null) {
-                Exception e = new UnsupportedOperationException("unknown method " + invoke.methodName);
-                e.printStackTrace();
-                output.writeObject(e);
-                output.flush();
-            } else {
-                Object result = null;
-                try {
-                    if (invoke.args == null) {
-                        if (DEBUG) {
-                            Logger.startScope("invoking local " + invoke.methodName);
-                        }
-                        result = method.invoke(invoke.receiver);
-                    } else {
-                        if (Logger.ENABLED && DEBUG) {
-                            StringBuilder str = new StringBuilder();
-                            str.append("invoking local " + invoke.methodName + "(");
-                            for (int i = 0; i < invoke.args.length; i++) {
-                                str.append(i == 0 ? "" : ", ");
-                                str.append(Logger.pretty(invoke.args[i]));
-                            }
-                            str.append(")");
-                            Logger.startScope(str.toString());
-                        }
-                        result = method.invoke(invoke.receiver, invoke.args);
-                    }
-                    result = new Result(result);
-                } catch (IllegalArgumentException e) {
-                    System.out.println("error while invoking " + invoke.methodName);
-                    e.getCause().printStackTrace();
-                    result = e.getCause();
-                } catch (InvocationTargetException e) {
-                    System.out.println("error while invoking " + invoke.methodName);
-                    e.getCause().printStackTrace();
-                    result = e.getCause();
-                } catch (IllegalAccessException e) {
-                    System.out.println("error while invoking " + invoke.methodName);
-                    e.getCause().printStackTrace();
-                    result = e.getCause();
-                } finally {
-                    if (DEBUG) {
-                        if (result instanceof Result) {
-                            Logger.endScope(" = " + ((Result) result).result);
-                        } else {
-                            Logger.endScope(" = " + result);
-                        }
-                    }
-                }
-                output.writeObject(result);
-                output.flush();
-            }
-        }
-    }
-
-    /**
-     * Sends a result without invoking a method, used by CompilationServer startup code.
-     */
-    public void sendResult(Object obj) throws IOException {
-        output.writeObject(new Result(obj));
-        output.flush();
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/server/Remote.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.server;
-
-
-public interface Remote {
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/server/ReplacingStreams.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.server;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.graal.hotspot.*;
-
-public class ReplacingStreams {
-
-    private IdentityHashMap<Object, Placeholder> objectMap = new IdentityHashMap<>();
-    private ArrayList<Object> objectList = new ArrayList<>();
-
-    private ReplacingOutputStream output;
-    private ReplacingInputStream input;
-
-    private InvocationSocket invocation;
-
-    public ReplacingStreams(OutputStream outputStream, InputStream inputStream) throws IOException {
-        output = new ReplacingOutputStream(new BufferedOutputStream(outputStream));
-        // required, because creating an ObjectOutputStream writes a header, but doesn't flush the stream
-        output.flush();
-        input = new ReplacingInputStream(new BufferedInputStream(inputStream));
-        invocation = new InvocationSocket(output, input);
-
-        addStaticObject(CiValue.IllegalValue);
-        addStaticObject(HotSpotProxy.DUMMY_CONSTANT_OBJ);
-    }
-
-    public void setInvocationSocket(InvocationSocket invocation) {
-        this.invocation = invocation;
-    }
-
-    public ReplacingOutputStream getOutput() {
-        return output;
-    }
-
-    public ReplacingInputStream getInput() {
-        return input;
-    }
-
-    public InvocationSocket getInvocation() {
-        return invocation;
-    }
-
-    private void addStaticObject(Object obj) {
-        int id = objectList.size();
-        objectList.add(obj);
-        objectMap.put(obj, new Placeholder(id));
-    }
-
-    public static class Placeholder implements Serializable {
-
-        /**
-         *
-         */
-        private static final long serialVersionUID = 6071894297788156945L;
-        public final int id;
-
-        public Placeholder(int id) {
-            this.id = id;
-        }
-
-        @Override
-        public String toString() {
-            return "#<" + id + ">";
-        }
-    }
-
-    public static class NewRemoteCallPlaceholder implements Serializable {
-
-        /**
-         *
-         */
-        private static final long serialVersionUID = 3084101671389500206L;
-        public final Class<?>[] interfaces;
-
-        public NewRemoteCallPlaceholder(Class<?>[] interfaces) {
-            this.interfaces = interfaces;
-        }
-    }
-
-    public static class NewDummyPlaceholder implements Serializable {
-
-        /**
-         *
-         */
-        private static final long serialVersionUID = 2692666726573532288L;
-    }
-
-    /**
-     * Replaces certain cir objects that cannot easily be made Serializable.
-     */
-    public class ReplacingInputStream extends ObjectInputStream {
-
-        public ReplacingInputStream(InputStream in) throws IOException {
-            super(in);
-            enableResolveObject(true);
-        }
-
-        @Override
-        protected Object resolveObject(Object obj) throws IOException {
-            // see ReplacingInputStream.replaceObject for details on when these types of objects are created
-
-            if (obj instanceof Placeholder) {
-                Placeholder placeholder = (Placeholder) obj;
-                Object resolvedObj = objectList.get(placeholder.id);
-                return resolvedObj;
-            }
-
-            if (obj instanceof NewRemoteCallPlaceholder) {
-                NewRemoteCallPlaceholder newPlaceholder = (NewRemoteCallPlaceholder) obj;
-                Placeholder placeholder = new Placeholder(objectList.size());
-                Object resolvedObj = Proxy.newProxyInstance(getClass().getClassLoader(), newPlaceholder.interfaces, invocation.new Handler(placeholder));
-                objectMap.put(resolvedObj, placeholder);
-                objectList.add(resolvedObj);
-                return resolvedObj;
-            }
-
-            if (obj instanceof NewDummyPlaceholder) {
-                Object resolvedObj = new Placeholder(objectList.size());
-                objectMap.put(resolvedObj, (Placeholder) resolvedObj);
-                objectList.add(resolvedObj);
-                return resolvedObj;
-            }
-
-            return obj;
-        }
-    }
-
-    /**
-     * Replaces certain cir objects that cannot easily be made Serializable.
-     */
-    public class ReplacingOutputStream extends ObjectOutputStream {
-
-        public ReplacingOutputStream(OutputStream out) throws IOException {
-            super(out);
-            enableReplaceObject(true);
-        }
-
-        @Override
-        protected Object replaceObject(Object obj) throws IOException {
-            // is the object a known instance?
-            Placeholder placeholder = objectMap.get(obj);
-            if (placeholder != null) {
-                return placeholder;
-            }
-
-            // is the object an instance of a class that will always be executed remotely?
-            if (obj instanceof Remote) {
-                return createRemoteCallPlaceholder(obj);
-            }
-
-            // is the object a constant of object type?
-            if (obj.getClass() == CiConstant.class) {
-                CiConstant constant = (CiConstant) obj;
-                if (constant.kind != CiKind.Object) {
-                    return obj;
-                }
-                Object contents = constant.asObject();
-                if (contents == null) {
-                    return obj;
-                }
-                // don't replace if the object already is a placeholder
-                if (contents instanceof Placeholder || contents instanceof Long) {
-                    return obj;
-                }
-                placeholder = objectMap.get(contents);
-                if (placeholder != null) {
-                    return CiConstant.forObject(placeholder);
-                }
-                if (contents instanceof Remote) {
-                    return CiConstant.forObject(createRemoteCallPlaceholder(contents));
-                }
-                return CiConstant.forObject(createDummyPlaceholder(contents));
-            }
-            return obj;
-        }
-    }
-
-    public static Class<?>[] getAllInterfaces(Class<?> clazz) {
-        HashSet<Class< ? >> interfaces = new HashSet<>();
-        getAllInterfaces(clazz, interfaces);
-        return interfaces.toArray(new Class<?>[interfaces.size()]);
-    }
-
-    private static void getAllInterfaces(Class<?> clazz, HashSet<Class<?>> interfaces) {
-        for (Class< ? > iface : clazz.getInterfaces()) {
-            if (!interfaces.contains(iface)) {
-                interfaces.add(iface);
-                getAllInterfaces(iface, interfaces);
-            }
-        }
-        if (clazz.getSuperclass() != null) {
-            getAllInterfaces(clazz.getSuperclass(), interfaces);
-        }
-    }
-
-    private Object createRemoteCallPlaceholder(Object obj) {
-        // collect all interfaces that this object's class implements (proxies only support interfaces)
-        objectMap.put(obj, new Placeholder(objectList.size()));
-        objectList.add(obj);
-        return new NewRemoteCallPlaceholder(getAllInterfaces(obj.getClass()));
-    }
-
-    public Object createDummyPlaceholder(Object obj) {
-        objectMap.put(obj, new Placeholder(objectList.size()));
-        objectList.add(obj);
-        return new NewDummyPlaceholder();
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/server/package-info.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011, 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.
- */
-/**
- * Implementation of a compilation server socket that delegates incoming requests to Graal.
- */
-package com.oracle.graal.hotspot.server;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/ArrayCopySnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -21,18 +21,50 @@
  * questions.
  */
 package com.oracle.graal.hotspot.snippets;
-import com.oracle.graal.cri.*;
-import com.oracle.graal.graph.Node.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.snippets.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Fold;
 
 
+@SuppressWarnings("unused")
 public class ArrayCopySnippets implements SnippetsInterface{
+    private static final Kind VECTOR_KIND = Kind.Long;
+    private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long);
+
+    //@Snippet
+    public static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, @ConstantParameter("baseKind") Kind baseKind) {
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long nonVectorBytes = byteLength % VECTOR_SIZE;
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
+        if (src == dest && srcPos < destPos) { // bad aliased case
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            long vectorLength = byteLength - nonVectorBytes;
+            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        } else {
+            for (long i = 0; i < nonVectorBytes; i++) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
+        }
+    }
 
     @Snippet
     public static void arraycopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
@@ -42,34 +74,30 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
-
+        Kind baseKind = Kind.Byte;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long nonVectorBytes = byteLength % VECTOR_SIZE;
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            if ((length & 0x01) == 0) {
-                if ((length & 0x02) == 0) {
-                    if ((length & 0x04) == 0) {
-                        copyLongsDown(src, srcPos, dest, destPos, length >> 3);
-                    } else {
-                        copyIntsDown(src, srcPos, dest, destPos, length >> 2);
-                    }
-                } else {
-                    copyShortsDown(src, srcPos, dest, destPos, length >> 1);
-                }
-            } else {
-                copyBytesDown(src, srcPos, dest, destPos, length);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            long vectorLength = byteLength - nonVectorBytes;
+            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            if ((length & 0x01) == 0) {
-                if ((length & 0x02) == 0) {
-                    if ((length & 0x04) == 0) {
-                        copyLongsUp(src, srcPos, dest, destPos, length >> 3);
-                    } else {
-                        copyIntsUp(src, srcPos, dest, destPos, length >> 2);
-                    }
-                } else {
-                    copyShortsUp(src, srcPos, dest, destPos, length >> 1);
-                }
-            } else {
-                copyBytesUp(src, srcPos, dest, destPos, length);
+            for (long i = 0; i < nonVectorBytes; i++) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         }
     }
@@ -82,25 +110,30 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        Kind baseKind = Kind.Char;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long nonVectorBytes = byteLength % VECTOR_SIZE;
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            if ((length & 0x01) == 0) {
-                if ((length & 0x02) == 0) {
-                    copyLongsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
-                } else {
-                    copyIntsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
-                }
-            } else {
-                copyShortsDown(src, srcPos * 2L, dest, destPos * 2L, length);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            long vectorLength = byteLength - nonVectorBytes;
+            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            if ((length & 0x01) == 0) {
-                if ((length & 0x02) == 0) {
-                    copyLongsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
-                } else {
-                    copyIntsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
-                }
-            } else {
-                copyShortsUp(src, srcPos * 2L, dest, destPos * 2L, length);
+            for (long i = 0; i < nonVectorBytes; i++) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         }
     }
@@ -113,25 +146,30 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        Kind baseKind = Kind.Short;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long nonVectorBytes = byteLength % VECTOR_SIZE;
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            if ((length & 0x01) == 0) {
-                if ((length & 0x02) == 0) {
-                    copyLongsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
-                } else {
-                    copyIntsDown(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
-                }
-            } else {
-                copyShortsDown(src, srcPos * 2L, dest, destPos * 2L, length);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            long vectorLength = byteLength - nonVectorBytes;
+            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            if ((length & 0x01) == 0) {
-                if ((length & 0x02) == 0) {
-                    copyLongsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 2);
-                } else {
-                    copyIntsUp(src, srcPos * 2L, dest, destPos * 2L, length >> 1);
-                }
-            } else {
-                copyShortsUp(src, srcPos * 2L, dest, destPos * 2L, length);
+            for (long i = 0; i < nonVectorBytes; i++) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         }
     }
@@ -144,17 +182,30 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        Kind baseKind = Kind.Int;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long nonVectorBytes = byteLength % VECTOR_SIZE;
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            if ((length & 0x01) == 0) {
-                copyLongsDown(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
-            } else {
-                copyIntsDown(src, srcPos * 4L, dest, destPos * 4L, length);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            long vectorLength = byteLength - nonVectorBytes;
+            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            if ((length & 0x01) == 0) {
-                copyLongsUp(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
-            } else {
-                copyIntsUp(src, srcPos * 4L, dest, destPos * 4L, length);
+            for (long i = 0; i < nonVectorBytes; i++) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         }
     }
@@ -167,17 +218,30 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        Kind baseKind = Kind.Float;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long nonVectorBytes = byteLength % VECTOR_SIZE;
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            if ((length & 0x01) == 0) {
-                copyLongsDown(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
-            } else {
-                copyIntsDown(src, srcPos * 4L, dest, destPos * 4L, length);
+            for (long i = byteLength - 1; i > byteLength - 1 - nonVectorBytes; i--) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            long vectorLength = byteLength - nonVectorBytes;
+            for (long i = vectorLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
-            if ((length & 0x01) == 0) {
-                copyLongsUp(src, srcPos * 4L, dest, destPos * 4L, length >> 1);
-            } else {
-                copyIntsUp(src, srcPos * 4L, dest, destPos * 4L, length);
+            for (long i = 0; i < nonVectorBytes; i++) {
+                Byte a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Byte);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.byteValue(), Kind.Byte);
+            }
+            for (long i = nonVectorBytes; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
             }
         }
     }
@@ -190,10 +254,21 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        Kind baseKind = Kind.Long;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            copyLongsDown(src, srcPos * 8L, dest, destPos * 8L, length);
+            for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
         } else {
-            copyLongsUp(src, srcPos * 8L, dest, destPos * 8L, length);
+            for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
         }
     }
 
@@ -205,10 +280,21 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        Kind baseKind = Kind.Double;
+        int header = arrayBaseOffset(baseKind);
+        long byteLength = length * arrayIndexScale(baseKind);
+        long srcOffset = srcPos * arrayIndexScale(baseKind);
+        long destOffset = destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            copyLongsDown(src, srcPos * 8L, dest, destPos * 8L, length);
+            for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
         } else {
-            copyLongsUp(src, srcPos * 8L, dest, destPos * 8L, length);
+            for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
+                Long a = UnsafeLoadNode.load(src, header, i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), VECTOR_KIND);
+            }
         }
     }
 
@@ -221,18 +307,19 @@
         if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > src.length || destPos + length > dest.length) {
             throw new IndexOutOfBoundsException();
         }
+        final int scale = arrayIndexScale(Kind.Object);
         if (src == dest && srcPos < destPos) { // bad aliased case
-            copyObjectsDown(src, srcPos * 8L, dest, destPos * 8L, length);
+            copyObjectsDown(src, srcPos * scale, dest, destPos * scale, length);
         } else {
-            copyObjectsUp(src, srcPos * 8L, dest, destPos * 8L, length);
+            copyObjectsUp(src, srcPos * scale, dest, destPos * scale, length);
         }
         if (length > 0) {
-            int header = arrayHeaderSizeFor(CiKind.Object);
+            int header = arrayBaseOffset(Kind.Object);
             int cardShift = cardTableShift();
             long cardStart = cardTableStart();
             long dstAddr = GetObjectAddressNode.get(dest);
-            long start = (dstAddr + header + destPos * 8L) >>> cardShift;
-            long end = (dstAddr + header + (destPos + length - 1) * 8L) >>> cardShift;
+            long start = (dstAddr + header + destPos * scale) >>> cardShift;
+            long end = (dstAddr + header + (destPos + length - 1) * scale) >>> cardShift;
             long count = end - start + 1;
             while (count-- > 0) {
                 DirectStoreNode.store((start + cardStart) + count, false);
@@ -240,208 +327,56 @@
         }
     }
 
-    @Snippet
-    public static void copyBytesDown(Object src, int srcPos, Object dest, int destPos, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Byte);
-        for (long i = length - 1; i >= 0; i--) {
-            Byte a = UnsafeLoadNode.load(src, header, i + srcPos, CiKind.Byte);
-            UnsafeStoreNode.store(dest, header, i + destPos, a.byteValue(), CiKind.Byte);
-        }
-    }
-
-    @Snippet
-    public static void copyShortsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Short);
-        for (long i = (length - 1) * 2; i >= 0; i -= 2) {
-            Character a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Short);
-            UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), CiKind.Short);
-        }
-    }
-
-    @Snippet
-    public static void copyIntsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Int);
-        for (long i = (length - 1) * 4; i >= 0; i -= 4) {
-            Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Int);
-            UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), CiKind.Int);
-        }
-    }
-
-    @Snippet
-    public static void copyLongsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Long);
-        for (long i = (length - 1) * 8; i >= 0; i -= 8) {
-            Long a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Long);
-            UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), CiKind.Long);
-        }
-    }
-
     // Does NOT perform store checks
     @Snippet
     public static void copyObjectsDown(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Object);
-        for (long i = (length - 1) * wordSize(); i >= 0; i -= wordSize()) {
-            Object a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Object);
+        int header = arrayBaseOffset(Kind.Object);
+        final int scale = arrayIndexScale(Kind.Object);
+        for (long i = (length - 1) * scale; i >= 0; i -= scale) {
+            Object a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Object);
             DirectObjectStoreNode.store(dest, header, i + destOffset, a);
         }
     }
-    /**
-     * Copies {@code length} bytes from {@code src} starting at {@code srcPos} to {@code dest} starting at {@code destPos}.
-     * @param src source object
-     * @param srcPos source offset
-     * @param dest destination object
-     * @param destPos destination offset
-     * @param length number of bytes to copy
-     */
-    @Snippet
-    public static void copyBytesUp(Object src, int srcPos, Object dest, int destPos, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Byte);
-        for (long i = 0; i < length; i++) {
-            Byte a = UnsafeLoadNode.load(src, header, i + srcPos, CiKind.Byte);
-            UnsafeStoreNode.store(dest, header, i + destPos, a.byteValue(), CiKind.Byte);
-        }
-    }
-
-    /**
-     * Copies {@code length} shorts from {@code src} starting at offset {@code srcOffset} (in bytes) to {@code dest} starting at offset {@code destOffset} (in bytes).
-     * @param src
-     * @param srcOffset (in bytes)
-     * @param dest
-     * @param destOffset (in bytes)
-     * @param length  (in shorts)
-     */
-    @Snippet
-    public static void copyShortsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Short);
-        for (long i = 0; i < length * 2L; i += 2) {
-            Character a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Short);
-            UnsafeStoreNode.store(dest, header, i + destOffset, a.charValue(), CiKind.Short);
-        }
-    }
-
-    @Snippet
-    public static void copyIntsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Int);
-        for (long i = 0; i < length * 4L; i += 4) {
-            Integer a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Int);
-            UnsafeStoreNode.store(dest, header, i + destOffset, a.intValue(), CiKind.Int);
-        }
-    }
-
-    @Snippet
-    public static void copyLongsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Long);
-        for (long i = 0; i < length * 8L; i += 8) {
-            Long a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Long);
-            UnsafeStoreNode.store(dest, header, i + destOffset, a.longValue(), CiKind.Long);
-        }
-    }
 
     // Does NOT perform store checks
     @Snippet
     public static void copyObjectsUp(Object src, long srcOffset, Object dest, long destOffset, int length)  {
-        int header = arrayHeaderSizeFor(CiKind.Object);
-        for (long i = 0; i < length * wordSize(); i += wordSize()) {
-            Object a = UnsafeLoadNode.load(src, header, i + srcOffset, CiKind.Object);
+        int header = arrayBaseOffset(Kind.Object);
+        final int scale = arrayIndexScale(Kind.Object);
+        for (long i = 0; i < length * scale; i += scale) {
+            Object a = UnsafeLoadNode.load(src, header, i + srcOffset, Kind.Object);
             DirectObjectStoreNode.store(dest, header, i + destOffset, a);
         }
     }
-    private static class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable {
-        @Input private ValueNode object;
-
-        public GetObjectAddressNode(ValueNode obj) {
-            super(StampFactory.forKind(CiKind.Long));
-            this.object = obj;
-        }
-
-        @SuppressWarnings("unused")
-        @NodeIntrinsic
-        public static long get(Object array) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void generate(LIRGeneratorTool gen) {
-            CiValue obj = gen.newVariable(gen.target().wordKind);
-            gen.emitMove(gen.operand(object), obj);
-            gen.setResult(this, obj);
-        }
-    }
-    private static class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
-        @Input private ValueNode address;
-        @Input private ValueNode value;
-
-        public DirectStoreNode(ValueNode address, ValueNode value) {
-            super(StampFactory.illegal());
-            this.address = address;
-            this.value = value;
-        }
-
-        @SuppressWarnings("unused")
-        @NodeIntrinsic
-        public static void store(long address, long value) {
-            throw new UnsupportedOperationException();
-        }
-
-        @SuppressWarnings("unused")
-        @NodeIntrinsic
-        public static void store(long address, boolean value) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void generate(LIRGeneratorTool gen) {
-            CiValue v = gen.operand(value);
-            gen.emitStore(new CiAddress(v.kind, gen.operand(address)), v, false);
-        }
-    }
-
-    private static class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable {
-        @Input private ValueNode object;
-        @Input private ValueNode value;
-        @Input private ValueNode offset;
-        private final int displacement;
-
-        public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value) {
-            super(StampFactory.illegal());
-            this.object = object;
-            this.value = value;
-            this.offset = offset;
-            this.displacement = displacement;
-        }
-
-        @SuppressWarnings("unused")
-        @NodeIntrinsic
-        public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void lower(CiLoweringTool tool) {
-            StructuredGraph graph = (StructuredGraph) this.graph();
-            IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, false);
-            WriteNode write = graph.add(new WriteNode(object, value, location));
-            graph.replaceFixedWithFixed(this, write);
-        }
-    }
 
     @Fold
-    private static int wordSize() {
-        return CompilerImpl.getInstance().getTarget().wordSize;
+    static int arrayBaseOffset(Kind elementKind) {
+        return elementKind.arrayBaseOffset();
     }
 
     @Fold
-    private static int arrayHeaderSizeFor(CiKind elementKind) {
-        return CompilerImpl.getInstance().getConfig().getArrayOffset(elementKind);
+    static int arrayIndexScale(Kind elementKind) {
+        return elementKind.arrayIndexScale();
+    }
+
+    static {
+        assert arrayIndexScale(Kind.Byte) == 1;
+        assert arrayIndexScale(Kind.Boolean) == 1;
+        assert arrayIndexScale(Kind.Char) == 2;
+        assert arrayIndexScale(Kind.Short) == 2;
+        assert arrayIndexScale(Kind.Int) == 4;
+        assert arrayIndexScale(Kind.Long) == 8;
+        assert arrayIndexScale(Kind.Float) == 4;
+        assert arrayIndexScale(Kind.Double) == 8;
     }
 
     @Fold
     private static int cardTableShift() {
-        return CompilerImpl.getInstance().getConfig().cardtableShift;
+        return HotSpotGraalRuntime.getInstance().getConfig().cardtableShift;
     }
 
     @Fold
     private static long cardTableStart() {
-        return CompilerImpl.getInstance().getConfig().cardtableStartAddress;
+        return HotSpotGraalRuntime.getInstance().getConfig().cardtableStartAddress;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CheckCastSnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.snippets;
+import static com.oracle.graal.hotspot.snippets.ArrayCopySnippets.*;
+import static com.oracle.graal.hotspot.snippets.CheckCastSnippets.Counter.*;
+import static com.oracle.graal.snippets.Snippet.Multiple.*;
+import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
+
+import java.io.*;
+import java.util.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Fold;
+import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.SnippetTemplate.Arguments;
+import com.oracle.graal.snippets.SnippetTemplate.Cache;
+import com.oracle.graal.snippets.SnippetTemplate.Key;
+import com.oracle.graal.snippets.nodes.*;
+import com.oracle.max.criutils.*;
+
+/**
+ * Snippets used for implementing the type test of a checkcast instruction.
+ *
+ * The test first checks against the profiled types (if any) and then implements the
+ * checks described in the paper <a href="http://dl.acm.org/citation.cfm?id=583821">
+ * Fast subtype checking in the HotSpot JVM</a> by Cliff Click and John Rose.
+ */
+public class CheckCastSnippets implements SnippetsInterface {
+
+    /**
+     * Type test used when the type being tested against is a final type.
+     */
+    @Snippet
+    public static Object checkcastExact(@Parameter("object") Object object, @Parameter("exactHub") Object exactHub, @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            isNull.inc();
+            return object;
+        }
+        Object objectHub = UnsafeLoadNode.loadObject(object, 0, hubOffset(), true);
+        if (objectHub != exactHub) {
+            exactMiss.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException);
+        }
+        exactHit.inc();
+        return object;
+    }
+
+    /**
+     * Type test used when the type being tested against is a restricted primary type.
+     *
+     * This test ignores use of hints altogether as the display-based type check only
+     * involves one extra load where the second load should hit the same cache line as the
+     * first.
+     */
+    @Snippet
+    public static Object checkcastPrimary(@Parameter("hub") Object hub, @Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("superCheckOffset") int superCheckOffset) {
+        if (checkNull && object == null) {
+            isNull.inc();
+            return object;
+        }
+        Object objectHub = UnsafeLoadNode.loadObject(object, 0, hubOffset(), true);
+        if (UnsafeLoadNode.loadObject(objectHub, 0, superCheckOffset, true) != hub) {
+            displayMiss.inc();
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException);
+        }
+        displayHit.inc();
+        return object;
+    }
+
+    /**
+     * Type test used when the type being tested against is a restricted secondary type.
+     */
+    @Snippet
+    public static Object checkcastSecondary(@Parameter("hub") Object hub, @Parameter("object") Object object, @Parameter(value = "hints", multiple = true) Object[] hints, @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            isNull.inc();
+            return object;
+        }
+        Object objectHub = UnsafeLoadNode.loadObject(object, 0, hubOffset(), true);
+        // if we get an exact match: succeed immediately
+        ExplodeLoopNode.explodeLoop();
+        for (int i = 0; i < hints.length; i++) {
+            Object hintHub = hints[i];
+            if (hintHub == objectHub) {
+                hintsHit.inc();
+                return object;
+            }
+        }
+        if (!checkSecondarySubType(hub, objectHub)) {
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException);
+        }
+        return object;
+    }
+
+    /**
+     * Type test used when the type being tested against is not known at compile time (e.g. the type test
+     * in an object array store check).
+     */
+    @Snippet
+    public static Object checkcastUnknown(@Parameter("hub") Object hub, @Parameter("object") Object object, @Parameter(value = "hints", multiple = true) Object[] hints, @ConstantParameter("checkNull") boolean checkNull) {
+        if (checkNull && object == null) {
+            isNull.inc();
+            return object;
+        }
+        Object objectHub = UnsafeLoadNode.loadObject(object, 0, hubOffset(), true);
+        // if we get an exact match: succeed immediately
+        ExplodeLoopNode.explodeLoop();
+        for (int i = 0; i < hints.length; i++) {
+            Object hintHub = hints[i];
+            if (hintHub == objectHub) {
+                hintsHit.inc();
+                return object;
+            }
+        }
+        if (!checkUnknownSubType(hub, objectHub)) {
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ClassCastException);
+        }
+        return object;
+    }
+
+    //This is used instead of a Java array read to avoid the array bounds check.
+    static Object loadNonNullObjectElement(Object array, int index) {
+        return UnsafeLoadNode.loadObject(array, arrayBaseOffset(Kind.Object), index * arrayIndexScale(Kind.Object), true);
+    }
+
+    static boolean checkSecondarySubType(Object t, Object s) {
+        // if (S.cache == T) return true
+        if (UnsafeLoadNode.loadObject(s, 0, secondarySuperCacheOffset(), true) == t) {
+            cacheHit.inc();
+            return true;
+        }
+
+        // if (T == S) return true
+        if (s == t) {
+            T_equals_S.inc();
+            return true;
+        }
+
+        // if (S.scan_s_s_array(T)) { S.cache = T; return true; }
+        Object[] secondarySupers = UnsafeCastNode.cast(UnsafeLoadNode.loadObject(s, 0, secondarySupersOffset(), true), Object[].class);
+
+        for (int i = 0; i < secondarySupers.length; i++) {
+            if (t == loadNonNullObjectElement(secondarySupers, i)) {
+                DirectObjectStoreNode.store(s, secondarySuperCacheOffset(), 0, t);
+                secondariesHit.inc();
+                return true;
+            }
+        }
+        secondariesMiss.inc();
+        return false;
+    }
+
+    static boolean checkUnknownSubType(Object t, Object s) {
+        // int off = T.offset
+        int superCheckOffset = UnsafeLoadNode.load(t, 0, superCheckOffsetOffset(), Kind.Int);
+        boolean primary = superCheckOffset != secondarySuperCacheOffset();
+
+        // if (T = S[off]) return true
+        if (UnsafeLoadNode.loadObject(s, 0, superCheckOffset, true) == t) {
+            if (primary) {
+                cacheHit.inc();
+            } else {
+                displayHit.inc();
+            }
+            return true;
+        }
+
+        // if (off != &cache) return false
+        if (primary) {
+            displayMiss.inc();
+            return false;
+        }
+
+        // if (T == S) return true
+        if (s == t) {
+            T_equals_S.inc();
+            return true;
+        }
+
+        // if (S.scan_s_s_array(T)) { S.cache = T; return true; }
+        Object[] secondarySupers = UnsafeCastNode.cast(UnsafeLoadNode.loadObject(s, 0, secondarySupersOffset(), true), Object[].class);
+        for (int i = 0; i < secondarySupers.length; i++) {
+            if (t == loadNonNullObjectElement(secondarySupers, i)) {
+                DirectObjectStoreNode.store(s, secondarySuperCacheOffset(), 0, t);
+                secondariesHit.inc();
+                return true;
+            }
+        }
+
+        secondariesMiss.inc();
+        return false;
+    }
+
+    /**
+     * Counters for the various code paths through a checkcast.
+     */
+    public enum Counter {
+        hintsHit("hit a hint type"),
+        exactHit("exact type test succeeded"),
+        exactMiss("exact type test failed"),
+        isNull("object tested was null"),
+        cacheHit("secondary type cache hit"),
+        secondariesHit("secondaries scan succeeded"),
+        secondariesMiss("secondaries scan failed"),
+        displayHit("primary type test succeeded"),
+        displayMiss("primary type test failed"),
+        T_equals_S("object type was equal to secondary type");
+
+        final String description;
+        final int index;
+        long count;
+
+        private Counter(String desc) {
+            this.description = desc;
+            this.index = ordinal();
+        }
+
+        @Fold
+        static int countOffset() {
+            try {
+                return (int) Unsafe.getUnsafe().objectFieldOffset(Counter.class.getDeclaredField("count"));
+            } catch (Exception e) {
+                throw new GraalInternalError(e);
+            }
+        }
+
+        /**
+         * Increments this counter if counters are enabled. The body of this method has been carefully crafted
+         * such that it contains no safepoints and no calls, neither of which are permissible in a snippet.
+         * Also, increments are not guaranteed to be atomic which is acceptable for a counter.
+         */
+        void inc() {
+            if (ENABLED) {
+                DirectObjectStoreNode.store(this, countOffset(), 0, count + 1);
+            }
+        }
+
+        static final Counter[] VALUES = values();
+        static final boolean ENABLED = GraalOptions.CheckcastCounters;
+    }
+
+    @Fold
+    private static int superCheckOffsetOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().superCheckOffsetOffset;
+    }
+
+    @Fold
+    private static int secondarySuperCacheOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().secondarySuperCacheOffset;
+    }
+
+    @Fold
+    private static int secondarySupersOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().secondarySupersOffset;
+    }
+
+    @Fold
+    private static int hubOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().hubOffset;
+    }
+
+    public static void printCounter(PrintStream out, Counter c, long total) {
+        double percent = total == 0D ? 0D : ((double) (c.count * 100)) / total;
+        out.println(String.format("%16s: %5.2f%%%10d  // %s", c.name(), percent, c.count, c.description));
+    }
+
+    public static void printCounters(PrintStream out) {
+        if (!Counter.ENABLED) {
+            return;
+        }
+        Counter[] counters = Counter.values();
+        Arrays.sort(counters, new Comparator<Counter>() {
+            @Override
+            public int compare(Counter o1, Counter o2) {
+                if (o1.count > o2.count) {
+                    return -1;
+                } else if (o2.count > o1.count) {
+                    return 1;
+                }
+                return 0;
+            }
+
+        });
+
+        long total = 0;
+        for (Counter c : counters) {
+            total += c.count;
+        }
+
+        out.println();
+        out.println("** Checkcast counters **");
+        for (Counter c : counters) {
+            printCounter(out, c, total);
+        }
+    }
+
+    public static class Templates {
+
+        private final Cache cache;
+        private final ResolvedJavaMethod exact;
+        private final ResolvedJavaMethod primary;
+        private final ResolvedJavaMethod secondary;
+        private final ResolvedJavaMethod unknown;
+        private final CodeCacheProvider runtime;
+
+        public Templates(CodeCacheProvider runtime) {
+            this.runtime = runtime;
+            this.cache = new Cache(runtime);
+            try {
+                exact = runtime.getResolvedJavaMethod(CheckCastSnippets.class.getDeclaredMethod("checkcastExact", Object.class, Object.class, boolean.class));
+                primary = runtime.getResolvedJavaMethod(CheckCastSnippets.class.getDeclaredMethod("checkcastPrimary", Object.class, Object.class, boolean.class, int.class));
+                secondary = runtime.getResolvedJavaMethod(CheckCastSnippets.class.getDeclaredMethod("checkcastSecondary", Object.class, Object.class, Object[].class, boolean.class));
+                unknown = runtime.getResolvedJavaMethod(CheckCastSnippets.class.getDeclaredMethod("checkcastUnknown", Object.class, Object.class, Object[].class, boolean.class));
+            } catch (NoSuchMethodException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+
+        /**
+         * Lowers a checkcast node.
+         */
+        public void lower(CheckCastNode checkcast, CiLoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) checkcast.graph();
+            ValueNode hub = checkcast.targetClassInstruction();
+            ValueNode object = checkcast.object();
+            TypeCheckHints hintInfo = new TypeCheckHints(checkcast.targetClass(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints);
+            final HotSpotResolvedJavaType target = (HotSpotResolvedJavaType) checkcast.targetClass();
+            boolean checkNull = !object.stamp().nonNull();
+            Arguments arguments;
+            Key key;
+
+            if (target == null) {
+                HotSpotKlassOop[] hints = createHints(hintInfo);
+                key = new Key(unknown).add("hints", multiple(Object.class, hints.length)).add("checkNull", checkNull);
+                arguments = arguments("hub", hub).add("object", object).add("hints", hints);
+            } else if (hintInfo.exact) {
+                HotSpotKlassOop[] hints = createHints(hintInfo);
+                assert hints.length == 1;
+                key = new Key(exact).add("checkNull", checkNull);
+                arguments = arguments("object", object).add("exactHub", hints[0]);
+            } else if (target.isPrimaryType()) {
+                key = new Key(primary).add("checkNull", checkNull).add("superCheckOffset", target.superCheckOffset());
+                arguments = arguments("hub", hub).add("object", object);
+            } else {
+                HotSpotKlassOop[] hints = createHints(hintInfo);
+                key = new Key(secondary).add("hints", multiple(Object.class, hints.length)).add("checkNull", checkNull);
+                arguments = arguments("hub", hub).add("object", object).add("hints", hints);
+            }
+
+            SnippetTemplate template = cache.get(key);
+            Debug.log("Lowering checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, arguments);
+            template.instantiate(runtime, checkcast, checkcast, arguments);
+        }
+
+        private static HotSpotKlassOop[] createHints(TypeCheckHints hints) {
+            HotSpotKlassOop[] hintHubs = new HotSpotKlassOop[hints.types.length];
+            for (int i = 0; i < hintHubs.length; i++) {
+                hintHubs[i] = ((HotSpotJavaType) hints.types[i]).klassOop();
+            }
+            return hintHubs;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectObjectStoreNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,68 @@
+/*
+ * 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.hotspot.snippets;
+
+import com.oracle.graal.cri.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * A special purpose store node that differs from {@link UnsafeStoreNode} in that
+ * it is not a {@link StateSplit} and does not include a write barrier.
+ */
+class DirectObjectStoreNode extends FixedWithNextNode implements Lowerable {
+    @Input private ValueNode object;
+    @Input private ValueNode value;
+    @Input private ValueNode offset;
+    private final int displacement;
+
+    public DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value) {
+        super(StampFactory.forVoid());
+        this.object = object;
+        this.value = value;
+        this.offset = offset;
+        this.displacement = displacement;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, Object value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(Object obj, @ConstantNodeParameter int displacement, long offset, long value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void lower(CiLoweringTool tool) {
+        StructuredGraph graph = (StructuredGraph) this.graph();
+        IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, false);
+        WriteNode write = graph.add(new WriteNode(object, value, location));
+        graph.replaceFixedWithFixed(this, write);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/DirectStoreNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,63 @@
+/*
+ * 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.hotspot.snippets;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * A special purpose store node that differs from {@link UnsafeStoreNode} in that
+ * it is not a {@link StateSplit} and takes a computed address instead of an object.
+ */
+class DirectStoreNode extends FixedWithNextNode implements LIRLowerable {
+    @Input private ValueNode address;
+    @Input private ValueNode value;
+
+    public DirectStoreNode(ValueNode address, ValueNode value) {
+        super(StampFactory.forVoid());
+        this.address = address;
+        this.value = value;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(long address, long value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static void store(long address, boolean value) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        Value v = gen.operand(value);
+        gen.emitStore(new Address(v.kind, gen.operand(address)), v, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/GetObjectAddressNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,56 @@
+/*
+ * 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.hotspot.snippets;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * Intrinsification for getting the address of an object.
+ * The code path(s) between a call to {@link #get(Object)} and all uses
+ * of the returned value must be atomic. The only exception to this is
+ * if the usage is not an attempt to dereference the value.
+ */
+class GetObjectAddressNode extends FixedWithNextNode implements LIRLowerable {
+    @Input private ValueNode object;
+
+    public GetObjectAddressNode(ValueNode obj) {
+        super(StampFactory.forKind(Kind.Long));
+        this.object = obj;
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static long get(Object array) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        Value obj = gen.newVariable(gen.target().wordKind);
+        gen.emitMove(gen.operand(object), obj);
+        gen.setResult(this, obj);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,8 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.compiler.util.*;
@@ -36,18 +36,18 @@
 import com.oracle.graal.nodes.java.*;
 
 public class IntrinsifyArrayCopyPhase extends Phase {
-    private final GraalRuntime runtime;
-    private RiResolvedMethod arrayCopy;
-    private RiResolvedMethod byteArrayCopy;
-    private RiResolvedMethod shortArrayCopy;
-    private RiResolvedMethod charArrayCopy;
-    private RiResolvedMethod intArrayCopy;
-    private RiResolvedMethod longArrayCopy;
-    private RiResolvedMethod floatArrayCopy;
-    private RiResolvedMethod doubleArrayCopy;
-    private RiResolvedMethod objectArrayCopy;
+    private final ExtendedRiRuntime runtime;
+    private ResolvedJavaMethod arrayCopy;
+    private ResolvedJavaMethod byteArrayCopy;
+    private ResolvedJavaMethod shortArrayCopy;
+    private ResolvedJavaMethod charArrayCopy;
+    private ResolvedJavaMethod intArrayCopy;
+    private ResolvedJavaMethod longArrayCopy;
+    private ResolvedJavaMethod floatArrayCopy;
+    private ResolvedJavaMethod doubleArrayCopy;
+    private ResolvedJavaMethod objectArrayCopy;
 
-    public IntrinsifyArrayCopyPhase(GraalRuntime runtime) {
+    public IntrinsifyArrayCopyPhase(ExtendedRiRuntime runtime) {
         this.runtime = runtime;
         try {
             byteArrayCopy = getArrayCopySnippet(runtime, byte.class);
@@ -58,7 +58,7 @@
             floatArrayCopy = getArrayCopySnippet(runtime, float.class);
             doubleArrayCopy = getArrayCopySnippet(runtime, double.class);
             objectArrayCopy = getArrayCopySnippet(runtime, Object.class);
-            arrayCopy = runtime.getRiMethod(System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class));
+            arrayCopy = runtime.getResolvedJavaMethod(System.class.getDeclaredMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class));
         } catch (SecurityException e) {
             e.printStackTrace();
         } catch (NoSuchMethodException e) {
@@ -66,48 +66,48 @@
         }
     }
 
-    private static RiResolvedMethod getArrayCopySnippet(RiRuntime runtime, Class<?> componentClass) throws NoSuchMethodException {
+    private static ResolvedJavaMethod getArrayCopySnippet(CodeCacheProvider runtime, Class<?> componentClass) throws NoSuchMethodException {
         Class<?> arrayClass = Array.newInstance(componentClass, 0).getClass();
-        return runtime.getRiMethod(ArrayCopySnippets.class.getDeclaredMethod("arraycopy", arrayClass, int.class, arrayClass, int.class, int.class));
+        return runtime.getResolvedJavaMethod(ArrayCopySnippets.class.getDeclaredMethod("arraycopy", arrayClass, int.class, arrayClass, int.class, int.class));
     }
 
     @Override
     protected void run(StructuredGraph graph) {
         boolean hits = false;
         for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) {
-            RiResolvedMethod targetMethod = methodCallTarget.targetMethod();
-            RiResolvedMethod snippetMethod = null;
+            ResolvedJavaMethod targetMethod = methodCallTarget.targetMethod();
+            ResolvedJavaMethod snippetMethod = null;
             if (targetMethod == arrayCopy) {
                 ValueNode src = methodCallTarget.arguments().get(0);
                 ValueNode dest = methodCallTarget.arguments().get(2);
                 assert src != null && dest != null;
-                RiResolvedType srcDeclaredType = src.declaredType();
-                RiResolvedType destDeclaredType = dest.declaredType();
-                if (srcDeclaredType != null
-                                && srcDeclaredType.isArrayClass()
-                                && destDeclaredType != null
-                                && destDeclaredType.isArrayClass()) {
-                    CiKind componentKind = srcDeclaredType.componentType().kind(false);
-                    if (srcDeclaredType.componentType() == destDeclaredType.componentType()) {
-                        if (componentKind == CiKind.Int) {
+                ResolvedJavaType srcType = src.objectStamp().type();
+                ResolvedJavaType destType = dest.objectStamp().type();
+                if (srcType != null
+                                && srcType.isArrayClass()
+                                && destType != null
+                                && destType.isArrayClass()) {
+                    Kind componentKind = srcType.componentType().kind();
+                    if (srcType.componentType() == destType.componentType()) {
+                        if (componentKind == Kind.Int) {
                             snippetMethod = intArrayCopy;
-                        } else if (componentKind == CiKind.Char) {
+                        } else if (componentKind == Kind.Char) {
                             snippetMethod = charArrayCopy;
-                        } else if (componentKind == CiKind.Long) {
+                        } else if (componentKind == Kind.Long) {
                             snippetMethod = longArrayCopy;
-                        } else if (componentKind == CiKind.Byte) {
+                        } else if (componentKind == Kind.Byte) {
                             snippetMethod = byteArrayCopy;
-                        } else if (componentKind == CiKind.Short) {
+                        } else if (componentKind == Kind.Short) {
                             snippetMethod = shortArrayCopy;
-                        } else if (componentKind == CiKind.Float) {
+                        } else if (componentKind == Kind.Float) {
                             snippetMethod = floatArrayCopy;
-                        } else if (componentKind == CiKind.Double) {
+                        } else if (componentKind == Kind.Double) {
                             snippetMethod = doubleArrayCopy;
-                        } else if (componentKind == CiKind.Object) {
+                        } else if (componentKind == Kind.Object) {
                             snippetMethod = objectArrayCopy;
                         }
-                    } else if (componentKind == CiKind.Object
-                                    && srcDeclaredType.componentType().isSubtypeOf(destDeclaredType.componentType())) {
+                    } else if (componentKind == Kind.Object
+                                    && srcType.componentType().isSubtypeOf(destType.componentType())) {
                         snippetMethod = objectArrayCopy;
                     }
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,229 @@
+/*
+ * 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.hotspot.snippets;
+
+import static com.oracle.graal.hotspot.nodes.CastFromHub.*;
+import static com.oracle.graal.hotspot.nodes.RegisterNode.*;
+import static com.oracle.graal.hotspot.snippets.DirectObjectStoreNode.*;
+import static com.oracle.graal.nodes.extended.UnsafeLoadNode.*;
+import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*;
+import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*;
+import static com.oracle.max.asm.target.amd64.AMD64.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.snippets.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Fold;
+import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.SnippetTemplate.Arguments;
+import com.oracle.graal.snippets.SnippetTemplate.Cache;
+import com.oracle.graal.snippets.SnippetTemplate.Key;
+
+/**
+ * Snippets used for implementing NEW.
+ */
+public class NewInstanceSnippets implements SnippetsInterface {
+
+    @Snippet
+    public static Word allocate(@ConstantParameter("size") int size) {
+        Word thread = asWord(register(r15, wordKind()));
+        Word top = loadWord(thread, threadTlabTopOffset());
+        Word end = loadWord(thread, threadTlabEndOffset());
+        Word newTop = top.plus(size);
+        if (newTop.belowOrEqual(end)) {
+            store(thread, 0, threadTlabTopOffset(), newTop);
+            return top;
+        }
+        return Word.zero();
+    }
+
+    @Snippet
+    public static Object initialize(
+                    @Parameter("memory") Word memory,
+                    @Parameter("hub") Object hub,
+                    @Parameter("prototypeHeader") Word headerPrototype,
+                    @ConstantParameter("size") int size) {
+
+        if (memory == Word.zero()) {
+            return NewInstanceStubCall.call(hub);
+        }
+        formatObject(hub, size, memory, headerPrototype);
+        Object instance = memory.toObject();
+        return castFromHub(verifyOop(instance), hub);
+    }
+
+    private static Object verifyOop(Object object) {
+        if (verifyOops()) {
+            VerifyOopStubCall.call(object);
+        }
+        return object;
+    }
+
+    private static Word asWord(Object object) {
+        return Word.fromObject(object);
+    }
+
+    private static Word loadWord(Word address, int offset) {
+        Object value = loadObject(address, 0, offset, true);
+        return asWord(value);
+    }
+
+    /**
+     * Maximum size of an object whose body is initialized by a sequence of
+     * zero-stores to its fields. Larger objects have their bodies initialized
+     * in a loop.
+     */
+    private static final int MAX_UNROLLED_OBJECT_INITIALIZATION_SIZE = 10 * wordSize();
+
+    /**
+     * Formats some allocated memory with an object header zeroes out the rest.
+     */
+    private static void formatObject(Object hub, int size, Word memory, Word headerPrototype) {
+        store(memory, 0, 0, headerPrototype);
+        store(memory, 0, hubOffset(), hub);
+        if (size <= MAX_UNROLLED_OBJECT_INITIALIZATION_SIZE) {
+            explodeLoop();
+            for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
+                store(memory, 0, offset, 0);
+            }
+        } else {
+            for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) {
+                store(memory, 0, offset, 0);
+            }
+        }
+    }
+
+    @Fold
+    private static boolean verifyOops() {
+        return HotSpotGraalRuntime.getInstance().getConfig().verifyOops;
+    }
+
+    @Fold
+    private static int threadTlabTopOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset;
+    }
+
+    @Fold
+    private static int threadTlabEndOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset;
+    }
+
+    @Fold
+    private static Kind wordKind() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordKind;
+    }
+
+    @Fold
+    private static int wordSize() {
+        return HotSpotGraalRuntime.getInstance().getTarget().wordSize;
+    }
+
+    @Fold
+    private static int hubOffset() {
+        return HotSpotGraalRuntime.getInstance().getConfig().hubOffset;
+    }
+
+    public static class Templates {
+
+        private final Cache cache;
+        private final ResolvedJavaMethod allocate;
+        private final ResolvedJavaMethod initialize;
+        private final CodeCacheProvider runtime;
+        private final boolean useTLAB;
+
+        public Templates(CodeCacheProvider runtime, boolean useTLAB) {
+            this.runtime = runtime;
+            this.cache = new Cache(runtime);
+            this.useTLAB = useTLAB;
+            try {
+                allocate = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("allocate", int.class));
+                initialize = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("initialize", Word.class, Object.class, Word.class, int.class));
+            } catch (NoSuchMethodException e) {
+                throw new GraalInternalError(e);
+            }
+        }
+
+        /**
+         * Lowers a {@link NewInstanceNode}.
+         */
+        @SuppressWarnings("unused")
+        public void lower(NewInstanceNode newInstanceNode, CiLoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) newInstanceNode.graph();
+            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass();
+            HotSpotKlassOop hub = type.klassOop();
+            int size = type.instanceSize();
+            assert (size % wordSize()) == 0;
+            assert size >= 0;
+
+            ValueNode memory;
+            if (!useTLAB) {
+                memory = ConstantNode.forObject(null, runtime, graph);
+            } else {
+                TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(size, wordKind()));
+                graph.addBeforeFixed(newInstanceNode, tlabAllocateNode);
+                memory = tlabAllocateNode;
+            }
+            InitializeNode initializeNode = graph.add(new InitializeNode(memory, type));
+            graph.replaceFixedWithFixed(newInstanceNode, initializeNode);
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(TLABAllocateNode tlabAllocateNode, CiLoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph();
+            int size = tlabAllocateNode.size();
+            assert (size % wordSize()) == 0;
+            assert size >= 0;
+            Key key = new Key(allocate).add("size", size);
+            Arguments arguments = new Arguments();
+            SnippetTemplate template = cache.get(key);
+            Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments);
+            template.instantiate(runtime, tlabAllocateNode, tlabAllocateNode, arguments);
+        }
+
+        @SuppressWarnings("unused")
+        public void lower(InitializeNode initializeNode, CiLoweringTool tool) {
+            StructuredGraph graph = (StructuredGraph) initializeNode.graph();
+            HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type();
+            HotSpotKlassOop hub = type.klassOop();
+            int size = type.instanceSize();
+            assert (size % wordSize()) == 0;
+            assert size >= 0;
+            Key key = new Key(initialize).add("size", size);
+            ValueNode memory = initializeNode.memory();
+            //assert memory instanceof AllocateNode || memory instanceof ConstantNode : memory;
+            Arguments arguments = arguments("memory", memory).add("hub", hub).add("prototypeHeader", type.prototypeHeader());
+            SnippetTemplate template = cache.get(key);
+            Debug.log("Lowering initialize in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments);
+            template.instantiate(runtime, initializeNode, initializeNode, arguments);
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/SystemSnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.snippets;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.snippets.*;
 
@@ -33,11 +33,11 @@
 public class SystemSnippets implements SnippetsInterface {
 
     public static long currentTimeMillis() {
-        return RuntimeCallNode.performCall(CiRuntimeCall.JavaTimeMillis);
+        return RuntimeCallNode.callLong(RuntimeCall.JavaTimeMillis);
     }
 
     public static long nanoTime() {
-        return RuntimeCallNode.performCall(CiRuntimeCall.JavaTimeNanos);
+        return RuntimeCallNode.callLong(RuntimeCall.JavaTimeNanos);
     }
 
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsafeSnippets.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/UnsafeSnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.hotspot.snippets;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.util.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.snippets.*;
@@ -47,7 +47,7 @@
     }
 
     public Object getObject(Object o, long offset) {
-        return UnsafeLoadNode.load(o, 0, offset, CiKind.Object);
+        return UnsafeLoadNode.load(o, 0, offset, Kind.Object);
     }
 
     public Object getObjectVolatile(Object o, long offset) {
@@ -58,7 +58,7 @@
     }
 
     public void putObject(Object o, long offset, Object x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Object);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Object);
     }
 
     public void putObjectVolatile(Object o, long offset, Object x) {
@@ -68,7 +68,7 @@
     }
 
     public int getInt(Object o, long offset) {
-        Integer value = UnsafeLoadNode.load(o, 0, offset, CiKind.Int);
+        Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int);
         return value;
     }
 
@@ -80,7 +80,7 @@
     }
 
     public void putInt(Object o, long offset, int x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Int);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Int);
     }
 
     public void putIntVolatile(Object o, long offset, int x) {
@@ -91,7 +91,7 @@
 
     public boolean getBoolean(Object o, long offset) {
         @JavacBug(id = 6995200)
-        Boolean result = UnsafeLoadNode.load(o, 0, offset, CiKind.Boolean);
+        Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean);
         return result;
     }
 
@@ -103,7 +103,7 @@
     }
 
     public void putBoolean(Object o, long offset, boolean x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Boolean);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Boolean);
     }
 
     public void putBooleanVolatile(Object o, long offset, boolean x) {
@@ -114,7 +114,7 @@
 
     public byte getByte(Object o, long offset) {
         @JavacBug(id = 6995200)
-        Byte result = UnsafeLoadNode.load(o, 0, offset, CiKind.Byte);
+        Byte result = UnsafeLoadNode.load(o, 0, offset, Kind.Byte);
         return result;
     }
 
@@ -126,7 +126,7 @@
     }
 
     public void putByte(Object o, long offset, byte x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Byte);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Byte);
     }
 
     public void putByteVolatile(Object o, long offset, byte x) {
@@ -137,7 +137,7 @@
 
     public short getShort(Object o, long offset) {
         @JavacBug(id = 6995200)
-        Short result = UnsafeLoadNode.load(o, 0, offset, CiKind.Short);
+        Short result = UnsafeLoadNode.load(o, 0, offset, Kind.Short);
         return result;
     }
 
@@ -149,7 +149,7 @@
     }
 
     public void putShort(Object o, long offset, short x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Short);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Short);
     }
 
     public void putShortVolatile(Object o, long offset, short x) {
@@ -160,7 +160,7 @@
 
     public char getChar(Object o, long offset) {
         @JavacBug(id = 6995200)
-        Character result = UnsafeLoadNode.load(o, 0, offset, CiKind.Char);
+        Character result = UnsafeLoadNode.load(o, 0, offset, Kind.Char);
         return result;
     }
 
@@ -172,7 +172,7 @@
     }
 
     public void putChar(Object o, long offset, char x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Char);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Char);
     }
 
     public void putCharVolatile(Object o, long offset, char x) {
@@ -183,7 +183,7 @@
 
     public long getLong(Object o, long offset) {
         @JavacBug(id = 6995200)
-        Long result = UnsafeLoadNode.load(o, 0, offset, CiKind.Long);
+        Long result = UnsafeLoadNode.load(o, 0, offset, Kind.Long);
         return result;
     }
 
@@ -195,7 +195,7 @@
     }
 
     public void putLong(Object o, long offset, long x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Long);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Long);
     }
 
     public void putLongVolatile(Object o, long offset, long x) {
@@ -206,7 +206,7 @@
 
     public float getFloat(Object o, long offset) {
         @JavacBug(id = 6995200)
-        Float result = UnsafeLoadNode.load(o, 0, offset, CiKind.Float);
+        Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float);
         return result;
     }
 
@@ -218,7 +218,7 @@
     }
 
     public void putFloat(Object o, long offset, float x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Float);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Float);
     }
 
     public void putFloatVolatile(Object o, long offset, float x) {
@@ -229,7 +229,7 @@
 
     public double getDouble(Object o, long offset) {
         @JavacBug(id = 6995200)
-        Double result = UnsafeLoadNode.load(o, 0, offset, CiKind.Double);
+        Double result = UnsafeLoadNode.load(o, 0, offset, Kind.Double);
         return result;
     }
 
@@ -241,7 +241,7 @@
     }
 
     public void putDouble(Object o, long offset, double x) {
-        UnsafeStoreNode.store(o, 0, offset, x, CiKind.Double);
+        UnsafeStoreNode.store(o, 0, offset, x, Kind.Double);
     }
 
     public void putDoubleVolatile(Object o, long offset, double x) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64NewInstanceStubCallOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,71 @@
+/*
+ * 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.hotspot.target;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+
+/**
+ * LIR instruction for calling HotSpot's {@code new_instance} stub. This stub is declared in c1_Runtime1.hpp
+ * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp.
+ */
+public class AMD64NewInstanceStubCallOp extends AMD64LIRInstruction {
+    public AMD64NewInstanceStubCallOp(Value result, Value hub, LIRDebugInfo info) {
+        super("NEW_INSTANCE", new Value[] {result}, info, new Value[] {hub}, NO_OPERANDS, new Value[]{AMD64.rax.asValue(Kind.Object)});
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        Value result = output(0);
+        Value hub = input(0);
+
+        // rdx: (in) hub
+        // rax: (out) result
+        assert asRegister(hub) == AMD64.rdx;
+        AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().newInstanceStub, info);
+        if (asRegister(result) != AMD64.rax) {
+            masm.movq(asRegister(result), AMD64.rax);
+        }
+    }
+
+    @Override
+    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+        if (mode == OperandMode.Input) {
+            return EnumSet.of(OperandFlag.Register);
+        } else if (mode == OperandMode.Output) {
+            return EnumSet.of(OperandFlag.Register);
+        } else if (mode == OperandMode.Temp) {
+            return EnumSet.of(OperandFlag.Register);
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64VerifyOopStubCallOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,67 @@
+/*
+ * 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.hotspot.target;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+
+/**
+ * A call to HotSpot's object pointer verification stub.
+ */
+public class AMD64VerifyOopStubCallOp extends AMD64LIRInstruction {
+    public AMD64VerifyOopStubCallOp(Value object, LIRDebugInfo info) {
+        super("VERIFY_OOP", LIRInstruction.NO_OPERANDS, info, new Value[] {object}, NO_OPERANDS, NO_OPERANDS);
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+        Register object = asRegister(input(0));
+        // r13: (in) object
+        if (object != AMD64.r13) {
+            masm.push(AMD64.r13);
+            masm.movq(AMD64.r13, object);
+        }
+        AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().verifyOopStub, info);
+        if (object != AMD64.r13) {
+            masm.pop(AMD64.r13);
+        }
+    }
+
+    @Override
+    protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+        if (mode == OperandMode.Input) {
+            return EnumSet.of(OperandFlag.Register);
+        }
+        throw GraalInternalError.shouldNotReachHere();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64SafepointOp.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64SafepointOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,18 +22,18 @@
  */
 package com.oracle.graal.hotspot.target.amd64;
 
-import static com.oracle.graal.hotspot.ri.HotSpotXirGenerator.*;
+import static com.oracle.graal.hotspot.meta.HotSpotXirGenerator.*;
 import static com.oracle.max.asm.target.amd64.AMD64.*;
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
 
 /**
  * Emits a safepoint poll.
@@ -49,17 +49,17 @@
 
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) {
-        CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
+        Register scratch = tasm.frameMap.registerConfig.getScratchRegister();
         int pos = asm.codeBuffer.position();
         if (config.isPollingPageFar) {
             asm.movq(scratch, config.safepointPollingAddress);
             tasm.recordMark(MARK_POLL_FAR);
             tasm.recordSafepoint(pos, info);
-            asm.movq(scratch, new CiAddress(tasm.target.wordKind, scratch.asValue()));
+            asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue()));
         } else {
             tasm.recordMark(MARK_POLL_NEAR);
             tasm.recordSafepoint(pos, info);
-            asm.movq(scratch, new CiAddress(tasm.target.wordKind, rip.asValue()));
+            asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue()));
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64TailcallOp.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64TailcallOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.hotspot.target.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
@@ -38,7 +38,7 @@
  */
 public class AMD64TailcallOp extends AMD64LIRInstruction {
 
-    public AMD64TailcallOp(List<CiValue> parameters, CiValue target, CiValue[] callingConvention) {
+    public AMD64TailcallOp(List<Value> parameters, Value target, Value[] callingConvention) {
         super("TAILCALL", LIRInstruction.NO_OPERANDS, null, toArray(parameters, target), LIRInstruction.NO_OPERANDS, callingConvention.clone());
         assert inputs.length == temps.length + 1;
 
@@ -48,8 +48,8 @@
         }
     }
 
-    private static CiValue[] toArray(List<CiValue> parameters, CiValue target) {
-        CiValue[] result = new CiValue[parameters.size() + 1];
+    private static Value[] toArray(List<Value> parameters, Value target) {
+        Value[] result = new Value[parameters.size() + 1];
         parameters.toArray(result);
         result[parameters.size()] = target;
         return result;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,20 +22,23 @@
  */
 package com.oracle.graal.hotspot.target.amd64;
 
-import static com.oracle.graal.hotspot.ri.HotSpotXirGenerator.*;
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.hotspot.meta.HotSpotXirGenerator.*;
 import static com.oracle.max.asm.target.amd64.AMD64.*;
-import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 
 import java.lang.reflect.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.compiler.target.amd64.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.ri.*;
+import com.oracle.graal.hotspot.counters.*;
+import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
@@ -44,19 +47,17 @@
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 
 public class HotSpotAMD64Backend extends Backend {
 
-    public HotSpotAMD64Backend(RiRuntime runtime, CiTarget target) {
+    public HotSpotAMD64Backend(CodeCacheProvider runtime, TargetDescription target) {
         super(runtime, target);
     }
 
     @Override
-    public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
-        return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir) {
+    public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir, RiXirGenerator xir, Assumptions assumptions) {
+        return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir, assumptions) {
 
             @Override
             public void visitSafepointNode(SafepointNode i) {
@@ -67,14 +68,20 @@
             @Override
             public void visitExceptionObject(ExceptionObjectNode x) {
                 HotSpotVMConfig config = ((HotSpotRuntime) runtime).config;
-                CiRegisterValue thread = r15.asValue();
-                CiAddress exceptionAddress = new CiAddress(CiKind.Object, thread, config.threadExceptionOopOffset);
-                CiAddress pcAddress = new CiAddress(CiKind.Long, thread, config.threadExceptionPcOffset);
-                CiValue exception = emitLoad(exceptionAddress, false);
-                emitStore(exceptionAddress, CiConstant.NULL_OBJECT, false);
-                emitStore(pcAddress, CiConstant.LONG_0, false);
+                RegisterValue thread = r15.asValue();
+                Address exceptionAddress = new Address(Kind.Object, thread, config.threadExceptionOopOffset);
+                Address pcAddress = new Address(Kind.Long, thread, config.threadExceptionPcOffset);
+                Value exception = emitLoad(exceptionAddress, false);
+                emitStore(exceptionAddress, Constant.NULL_OBJECT, false);
+                emitStore(pcAddress, Constant.LONG_0, false);
                 setResult(x, exception);
             }
+
+            @Override
+            protected void emitPrologue() {
+                super.emitPrologue();
+                MethodEntryCounters.emitCounter(this, method);
+            }
         };
     }
 
@@ -98,10 +105,10 @@
             if (GraalOptions.ZapStackOnMethodEntry) {
                 final int intSize = 4;
                 for (int i = 0; i < frameSize / intSize; ++i) {
-                    asm.movl(new CiAddress(CiKind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1);
+                    asm.movl(new Address(Kind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1);
                 }
             }
-            CiCalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout();
+            CalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout();
             if (csl != null && csl.size != 0) {
                 int frameToCSA = frameMap.offsetToCalleeSaveArea();
                 assert frameToCSA >= 0;
@@ -113,8 +120,8 @@
         public void leave(TargetMethodAssembler tasm) {
             int frameSize = tasm.frameMap.frameSize();
             AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
-            CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
-            RiRegisterConfig regConfig = tasm.frameMap.registerConfig;
+            CalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
+            RegisterConfig regConfig = tasm.frameMap.registerConfig;
 
             if (csl != null && csl.size != 0) {
                 tasm.targetMethod.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position());
@@ -133,14 +140,14 @@
                 // so deoptimization cannot be performed here. The HotSpot runtime
                 // detects this case - see the definition of frame::should_be_deoptimized()
 
-                CiRegister scratch = regConfig.getScratchRegister();
+                Register scratch = regConfig.getScratchRegister();
                 if (config.isPollingPageFar) {
                     asm.movq(scratch, config.safepointPollingAddress);
                     tasm.recordMark(MARK_POLL_RETURN_FAR);
-                    asm.movq(scratch, new CiAddress(tasm.target.wordKind, scratch.asValue()));
+                    asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue()));
                 } else {
                     tasm.recordMark(MARK_POLL_RETURN_NEAR);
-                    asm.movq(scratch, new CiAddress(tasm.target.wordKind, rip.asValue()));
+                    asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue()));
                 }
             }
         }
@@ -168,10 +175,10 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, RiResolvedMethod method, LIR lir) {
+    public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir) {
         AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
         FrameMap frameMap = tasm.frameMap;
-        RiRegisterConfig regConfig = frameMap.registerConfig;
+        RegisterConfig regConfig = frameMap.registerConfig;
         HotSpotVMConfig config = ((HotSpotRuntime) runtime).config;
         Label unverifiedStub = new Label();
 
@@ -181,10 +188,10 @@
         boolean isStatic = Modifier.isStatic(method.accessFlags());
         if (!isStatic) {
             tasm.recordMark(MARK_UNVERIFIED_ENTRY);
-            CiCallingConvention cc = regConfig.getCallingConvention(JavaCallee, new CiKind[] {CiKind.Object}, target, false);
-            CiRegister inlineCacheKlass = rax; // see definition of IC_Klass in c1_LIRAssembler_x86.cpp
-            CiRegister receiver = asRegister(cc.locations[0]);
-            CiAddress src = new CiAddress(target.wordKind, receiver.asValue(), config.hubOffset);
+            CallingConvention cc = regConfig.getCallingConvention(JavaCallee, new Kind[] {Kind.Object}, target, false);
+            Register inlineCacheKlass = rax; // see definition of IC_Klass in c1_LIRAssembler_x86.cpp
+            Register receiver = asRegister(cc.locations[0]);
+            Address src = new Address(target.wordKind, receiver.asValue(), config.hubOffset);
 
             asm.cmpq(inlineCacheKlass, src);
             asm.jcc(ConditionFlag.notEqual, unverifiedStub);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,1658 @@
+/*
+ * 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.interpreter;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.interpreter.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.bytecode.*;
+
+/**
+ *
+ * <h1>Implementation notes</h1>
+ * <li>Native methods are invoked using standard java reflection.</li>
+ *
+ * <h1>Features:</h1>
+ *
+ *
+ * <h1>Limitations:</h1>
+ *
+ * <li>The interpreter is not able to recognize a native method that calls a java method.
+ *  In that case the java method will be interpreted directly on the vm interpreter.</li>
+ */
+@SuppressWarnings("static-method")
+public final class BytecodeInterpreter implements Interpreter {
+
+    private static final String OPTION_MAX_STACK_SIZE = "maxStackSize";
+    private static final boolean TRACE = false;
+    private static final boolean TRACE_BYTE_CODE = false;
+
+    private static final int DEFAULT_MAX_STACK_SIZE = 200;
+
+    private static final int NEXT = -1;
+    private static final int BRANCH = -2;
+    private static final int RETURN = -3;
+    private static final int CALL = -4;
+
+    private InterpreterFrame callFrame;
+
+    //TODO try to remove this reference
+    private ExceptionHandler catchAllExceptionHandler;
+
+    private final Map<ResolvedJavaMethod, InterpreterCallable> methodDelegates = new HashMap<>();
+
+    private int maxStackFrames = DEFAULT_MAX_STACK_SIZE;
+    private int stackFrameDepth;
+
+    private final ResolvedJavaMethod rootMethod;
+    private final VMAdapter vm;
+
+    public BytecodeInterpreter() {
+        this(VMAdapter.getInstance());
+    }
+
+    public BytecodeInterpreter(VMAdapter accessor) {
+        if (accessor == null) {
+            throw new NullPointerException();
+        }
+        this.vm = accessor;
+        this.rootMethod = resolveRootMethod();
+        registerDelegates();
+    }
+
+    @Override
+    public void setOption(String name, String value) {
+        if (name != null && name.equals(OPTION_MAX_STACK_SIZE)) {
+            this.maxStackFrames = Integer.parseInt(value);
+        }
+    }
+
+
+    private void registerDelegates() {
+       addDelegate(findMethod(Throwable.class, "fillInStackTrace"), new InterpreterCallable() {
+        @Override
+        public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object base, Object[] arguments) throws Throwable {
+            setBackTrace(caller, (Throwable) base, createStackTraceElements(caller));
+            return null;
+        }
+       });
+       addDelegate(findMethod(Throwable.class, "getStackTraceDepth"), new InterpreterCallable() {
+           @Override
+           public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object base, Object[] arguments) throws Throwable {
+               StackTraceElement[] elements = getBackTrace(caller, (Throwable) base);
+               if (elements != null) {
+                   return elements.length;
+               }
+               return 0;
+           }
+       });
+       addDelegate(findMethod(Throwable.class, "getStackTraceElement", int.class), new InterpreterCallable() {
+           @Override
+           public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object base, Object[] arguments) throws Throwable {
+               StackTraceElement[] elements = getBackTrace(caller, (Throwable) base);
+               if (elements != null) {
+                   Integer index = (Integer) arguments[0];
+                   if (index != null) {
+                       return elements[index];
+                   }
+               }
+               return null;
+           }
+       });
+    }
+
+    public void setMaxStackFrames(int maxStackSize) {
+        this.maxStackFrames = maxStackSize;
+    }
+
+    public int getMaxStackFrames() {
+        return maxStackFrames;
+    }
+
+    public void addDelegate(Method method, InterpreterCallable callable) {
+        ResolvedJavaMethod resolvedMethod = vm.getRuntime().getResolvedJavaMethod(method);
+        if (methodDelegates.containsKey(resolvedMethod)) {
+            throw new IllegalArgumentException("Delegate for method " + method + " already added.");
+        }
+        methodDelegates.put(resolvedMethod, callable);
+    }
+
+    public void removeDelegate(Method method) {
+        methodDelegates.remove(vm.getRuntime().getResolvedJavaMethod(method));
+    }
+
+    @Override
+    public Object execute(ResolvedJavaMethod method, Object... boxedArguments) {
+        Signature signature = method.signature();
+        assert boxedArguments != null;
+        assert signature.argumentCount(false) == boxedArguments.length;
+
+        if (!Modifier.isStatic(method.accessFlags())) {
+            throw new UnsupportedOperationException("The interpreter can currently only be started with static methods.");
+        }
+
+        InterpreterFrame rootFrame = new InterpreterFrame(rootMethod, signature.argumentSlots(true));
+        rootFrame.pushObject(this);
+        rootFrame.pushObject(method);
+        rootFrame.pushObject(boxedArguments);
+
+        for (int i = 0; i < boxedArguments.length; i++) {
+            pushAsObject(rootFrame, signature.argumentKindAt(i), boxedArguments[i]);
+        }
+
+        InterpreterFrame frame = rootFrame.create(method, false);
+
+        try {
+            executeRoot(rootFrame, frame);
+        } catch (Throwable e) {
+            // clear backtrace for compatibilty and store it in stacktrace
+            StackTraceElement[] backtrace = getBackTrace(rootFrame, e);
+            setBackTrace(rootFrame, e, null);
+            setStackTrace(rootFrame, e, backtrace);
+            throw new InterpreterException(e);
+        }
+
+        return popAsObject(rootFrame, signature.returnKind());
+    }
+
+    public Object execute(Method javaMethod, Object... boxedArguments) throws InterpreterException {
+        return execute(vm.getRuntime().getResolvedJavaMethod(javaMethod), boxedArguments);
+    }
+
+    private void executeRoot(InterpreterFrame root, InterpreterFrame frame) throws Throwable {
+        //TODO reflection redirection
+        stackFrameDepth = 0;
+
+        InterpreterFrame prevFrame = frame;
+        InterpreterFrame currentFrame = frame;
+        BytecodeStream bs = new BytecodeStream(currentFrame.getMethod().code());
+        if (TRACE) {
+            traceCall(frame, "Call");
+        }
+        while (currentFrame != root) {
+            if (prevFrame != currentFrame) {
+                bs = new BytecodeStream(currentFrame.getMethod().code());
+            }
+            bs.setBCI(currentFrame.getBCI());
+
+            prevFrame = currentFrame;
+            currentFrame = loop(root, prevFrame, bs);
+        }
+        assert callFrame == null;
+    }
+
+    private InterpreterFrame loop(InterpreterFrame root, final InterpreterFrame frame, final BytecodeStream bs) throws Throwable {
+        try {
+            while (true) {
+                int result = executeInstruction(frame, bs);
+                switch (result) {
+                    case NEXT :
+                        bs.next();
+                        break;
+                    case RETURN :
+                        return popFrame(frame);
+                    case CALL:
+                        return allocateFrame(frame, bs);
+                    case BRANCH :
+                        bs.setBCI(bs.readBranchDest());
+                        break;
+                    default :
+                        // the outcome depends on stack values
+                        assert result >= 0 : "negative branch target";
+                        bs.setBCI(result);
+                        break;
+                }
+            }
+        } catch (Throwable t) {
+            if (TRACE) {
+                traceOp("Exception " + t.toString());
+            }
+            updateStackTrace(frame, t);
+
+            // frame bci needs to be in sync when handling exceptions
+            frame.setBCI(bs.currentBCI());
+
+            InterpreterFrame handlerFrame = handleThrowable(root, frame, t);
+            if (handlerFrame == null) {
+                // matched root we just throw it again.
+                throw t;
+            } else {
+                if (TRACE) {
+                    traceOp("Handler found " + handlerFrame.getMethod() + ":" + handlerFrame.getBCI());
+                }
+                // update bci from frame
+                bs.setBCI(handlerFrame.getBCI());
+
+                // continue execution on the found frame
+                return handlerFrame;
+            }
+        } finally {
+            // TODO may be not necessary.
+            frame.setBCI(bs.currentBCI());
+        }
+    }
+
+    private int executeInstruction(InterpreterFrame frame, BytecodeStream bs) throws Throwable {
+        if (TRACE_BYTE_CODE) {
+            traceOp(bs.currentBCI() + ": " + Bytecodes.baseNameOf(bs.currentBC()));
+        }
+        switch(bs.currentBC()) {
+            case Bytecodes.NOP            : break;
+            case Bytecodes.ACONST_NULL    :
+                frame.pushObject(null);
+                break;
+            case Bytecodes.ICONST_M1      :
+                frame.pushInt(-1);
+                break;
+            case Bytecodes.ICONST_0       :
+                frame.pushInt(0);
+                break;
+            case Bytecodes.ICONST_1       :
+                frame.pushInt(1);
+                break;
+            case Bytecodes.ICONST_2       :
+                frame.pushInt(2);
+                break;
+            case Bytecodes.ICONST_3       :
+                frame.pushInt(3);
+                break;
+            case Bytecodes.ICONST_4       :
+                frame.pushInt(4);
+                break;
+            case Bytecodes.ICONST_5       :
+                frame.pushInt(5);
+                break;
+            case Bytecodes.LCONST_0       :
+                frame.pushLong(0L);
+                break;
+            case Bytecodes.LCONST_1       :
+                frame.pushLong(1L);
+                break;
+            case Bytecodes.FCONST_0       :
+                frame.pushFloat(0.0F);
+                break;
+            case Bytecodes.FCONST_1       :
+                frame.pushFloat(1.0F);
+                break;
+            case Bytecodes.FCONST_2       :
+                frame.pushFloat(2.0F);
+                break;
+            case Bytecodes.DCONST_0       :
+                frame.pushDouble(0.0D);
+                break;
+            case Bytecodes.DCONST_1       :
+                frame.pushDouble(1.0D);
+                break;
+            case Bytecodes.BIPUSH         :
+                frame.pushInt(bs.readByte());
+                break;
+            case Bytecodes.SIPUSH         :
+                frame.pushInt(bs.readShort());
+                break;
+            case Bytecodes.LDC            :
+            case Bytecodes.LDC_W          :
+            case Bytecodes.LDC2_W         :
+                pushCPConstant(frame, bs.readCPI());
+                break;
+            case Bytecodes.ILOAD          :
+                frame.pushInt(frame.getInt(frame.resolveLocalIndex(bs.readLocalIndex())));
+                break;
+            case Bytecodes.LLOAD          :
+                frame.pushLong(frame.getLong(frame.resolveLocalIndex(bs.readLocalIndex())));
+                break;
+            case Bytecodes.FLOAD          :
+                frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(bs.readLocalIndex())));
+                break;
+            case Bytecodes.DLOAD          :
+                frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(bs.readLocalIndex())));
+                break;
+            case Bytecodes.ALOAD          :
+                frame.pushObject(frame.getObject(frame.resolveLocalIndex(bs.readLocalIndex())));
+                break;
+            case Bytecodes.ILOAD_0:
+                frame.pushInt(frame.getInt(frame.resolveLocalIndex(0)));
+                break;
+            case Bytecodes.ILOAD_1:
+                frame.pushInt(frame.getInt(frame.resolveLocalIndex(1)));
+                break;
+            case Bytecodes.ILOAD_2:
+                frame.pushInt(frame.getInt(frame.resolveLocalIndex(2)));
+                break;
+            case Bytecodes.ILOAD_3:
+                frame.pushInt(frame.getInt(frame.resolveLocalIndex(3)));
+                break;
+            case Bytecodes.LLOAD_0        :
+                frame.pushLong(frame.getLong(frame.resolveLocalIndex(0)));
+                break;
+            case Bytecodes.LLOAD_1        :
+                frame.pushLong(frame.getLong(frame.resolveLocalIndex(1)));
+                break;
+            case Bytecodes.LLOAD_2        :
+                frame.pushLong(frame.getLong(frame.resolveLocalIndex(2)));
+                break;
+            case Bytecodes.LLOAD_3        :
+                frame.pushLong(frame.getLong(frame.resolveLocalIndex(3)));
+                break;
+            case Bytecodes.FLOAD_0        :
+                frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(0)));
+                break;
+            case Bytecodes.FLOAD_1        :
+                frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(1)));
+                break;
+            case Bytecodes.FLOAD_2        :
+                frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(2)));
+                break;
+            case Bytecodes.FLOAD_3        :
+                frame.pushFloat(frame.getFloat(frame.resolveLocalIndex(3)));
+                break;
+            case Bytecodes.DLOAD_0        :
+                frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(0)));
+                break;
+            case Bytecodes.DLOAD_1        :
+                frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(1)));
+                break;
+            case Bytecodes.DLOAD_2        :
+                frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(2)));
+                break;
+            case Bytecodes.DLOAD_3        :
+                frame.pushDouble(frame.getDouble(frame.resolveLocalIndex(3)));
+                break;
+            case Bytecodes.ALOAD_0        :
+                frame.pushObject(frame.getObject(frame.resolveLocalIndex(0)));
+                break;
+            case Bytecodes.ALOAD_1        :
+                frame.pushObject(frame.getObject(frame.resolveLocalIndex(1)));
+                break;
+            case Bytecodes.ALOAD_2        :
+                frame.pushObject(frame.getObject(frame.resolveLocalIndex(2)));
+                break;
+            case Bytecodes.ALOAD_3        :
+                frame.pushObject(frame.getObject(frame.resolveLocalIndex(3)));
+                break;
+            case Bytecodes.IALOAD         :
+                frame.pushInt(vm.getArrayInt(frame.popInt(), frame.popObject()));
+                break;
+            case Bytecodes.LALOAD         :
+                frame.pushLong(vm.getArrayLong(frame.popInt(), frame.popObject()));
+                break;
+            case Bytecodes.FALOAD         :
+                frame.pushFloat(vm.getArrayFloat(frame.popInt(), frame.popObject()));
+                break;
+            case Bytecodes.DALOAD         :
+                frame.pushDouble(vm.getArrayDouble(frame.popInt(), frame.popObject()));
+                break;
+            case Bytecodes.AALOAD         :
+                frame.pushObject(vm.getArrayObject(frame.popInt(), frame.popObject()));
+                break;
+            case Bytecodes.BALOAD         :
+                frame.pushInt(vm.getArrayByte(frame.popInt(), frame.popObject()));
+                break;
+            case Bytecodes.CALOAD         :
+                frame.pushInt(vm.getArrayChar(frame.popInt(), frame.popObject()));
+                break;
+             case Bytecodes.SALOAD:
+                frame.pushInt(vm.getArrayShort(frame.popInt(), frame.popObject()));
+                break;
+            case Bytecodes.ISTORE:
+                frame.setInt(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popInt());
+                break;
+            case Bytecodes.LSTORE         :
+                frame.setLong(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popLong());
+                break;
+            case Bytecodes.FSTORE         :
+                frame.setFloat(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popFloat());
+                break;
+            case Bytecodes.DSTORE         :
+                frame.setDouble(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popDouble());
+                break;
+            case Bytecodes.ASTORE         :
+                frame.setObject(frame.resolveLocalIndex(bs.readLocalIndex()), frame.popObject());
+                break;
+            case Bytecodes.ISTORE_0       :
+                frame.setInt(frame.resolveLocalIndex(0), frame.popInt());
+                break;
+            case Bytecodes.ISTORE_1       :
+                frame.setInt(frame.resolveLocalIndex(1), frame.popInt());
+                break;
+            case Bytecodes.ISTORE_2       :
+                frame.setInt(frame.resolveLocalIndex(2), frame.popInt());
+                break;
+            case Bytecodes.ISTORE_3       :
+                frame.setInt(frame.resolveLocalIndex(3), frame.popInt());
+                break;
+            case Bytecodes.LSTORE_0       :
+                frame.setLong(frame.resolveLocalIndex(0), frame.popLong());
+                break;
+            case Bytecodes.LSTORE_1       :
+                frame.setLong(frame.resolveLocalIndex(1), frame.popLong());
+                break;
+            case Bytecodes.LSTORE_2       :
+                frame.setLong(frame.resolveLocalIndex(2), frame.popLong());
+                break;
+            case Bytecodes.LSTORE_3       :
+                frame.setLong(frame.resolveLocalIndex(3), frame.popLong());
+                break;
+            case Bytecodes.FSTORE_0       :
+                frame.setFloat(frame.resolveLocalIndex(0), frame.popFloat());
+                break;
+            case Bytecodes.FSTORE_1       :
+                frame.setFloat(frame.resolveLocalIndex(1), frame.popFloat());
+                break;
+            case Bytecodes.FSTORE_2       :
+                frame.setFloat(frame.resolveLocalIndex(2), frame.popFloat());
+                break;
+            case Bytecodes.FSTORE_3       :
+                frame.setFloat(frame.resolveLocalIndex(3), frame.popFloat());
+                break;
+            case Bytecodes.DSTORE_0       :
+                frame.setDouble(frame.resolveLocalIndex(0), frame.popDouble());
+                break;
+            case Bytecodes.DSTORE_1       :
+                frame.setDouble(frame.resolveLocalIndex(1), frame.popDouble());
+                break;
+            case Bytecodes.DSTORE_2       :
+                frame.setDouble(frame.resolveLocalIndex(2), frame.popDouble());
+                break;
+            case Bytecodes.DSTORE_3       :
+                frame.setDouble(frame.resolveLocalIndex(3), frame.popDouble());
+                break;
+            case Bytecodes.ASTORE_0       :
+                frame.setObject(frame.resolveLocalIndex(0), frame.popObject());
+                break;
+            case Bytecodes.ASTORE_1       :
+                frame.setObject(frame.resolveLocalIndex(1), frame.popObject());
+                break;
+            case Bytecodes.ASTORE_2       :
+                frame.setObject(frame.resolveLocalIndex(2), frame.popObject());
+                break;
+            case Bytecodes.ASTORE_3       :
+                frame.setObject(frame.resolveLocalIndex(3), frame.popObject());
+                break;
+            case Bytecodes.IASTORE        :
+                vm.setArrayInt(frame.popInt(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.LASTORE        :
+                vm.setArrayLong(frame.popLong(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.FASTORE        :
+                vm.setArrayFloat(frame.popFloat(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.DASTORE        :
+                vm.setArrayDouble(frame.popDouble(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.AASTORE        :
+                vm.setArrayObject(frame.popObject(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.BASTORE        :
+                vm.setArrayByte((byte) frame.popInt(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.CASTORE        :
+                vm.setArrayChar((char) frame.popInt(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.SASTORE        :
+                vm.setArrayShort((short) frame.popInt(), frame.popInt(), frame.popObject());
+                break;
+            case Bytecodes.POP            :
+                frame.popVoid(1);
+                break;
+            case Bytecodes.POP2           :
+                frame.popVoid(2);
+                break;
+            case Bytecodes.DUP            :
+                frame.dup(1);
+                break;
+            case Bytecodes.DUP_X1         :
+                frame.dupx1();
+                break;
+            case Bytecodes.DUP_X2         :
+                frame.dupx2();
+                break;
+            case Bytecodes.DUP2           :
+                frame.dup(2);
+                break;
+            case Bytecodes.DUP2_X1        :
+                frame.dup2x1();
+                break;
+            case Bytecodes.DUP2_X2        :
+                frame.dup2x2();
+                break;
+            case Bytecodes.SWAP           :
+                frame.swapSingle();
+                break;
+            case Bytecodes.IADD           :
+                frame.pushInt(frame.popInt() + frame.popInt());
+                break;
+            case Bytecodes.LADD           :
+                frame.pushLong(frame.popLong() + frame.popLong());
+                break;
+            case Bytecodes.FADD           :
+                frame.pushFloat(frame.popFloat() + frame.popFloat());
+                break;
+            case Bytecodes.DADD           :
+                frame.pushDouble(frame.popDouble() + frame.popDouble());
+                break;
+            case Bytecodes.ISUB           :
+                frame.pushInt(-frame.popInt() + frame.popInt());
+                break;
+            case Bytecodes.LSUB           :
+                frame.pushLong(-frame.popLong() + frame.popLong());
+                break;
+            case Bytecodes.FSUB           :
+                frame.pushFloat(-frame.popFloat() + frame.popFloat());
+                break;
+            case Bytecodes.DSUB           :
+                frame.pushDouble(-frame.popDouble() + frame.popDouble());
+                break;
+            case Bytecodes.IMUL           :
+                frame.pushInt(frame.popInt() * frame.popInt());
+                break;
+            case Bytecodes.LMUL           :
+                frame.pushLong(frame.popLong() * frame.popLong());
+                break;
+            case Bytecodes.FMUL           :
+                frame.pushFloat(frame.popFloat() * frame.popFloat());
+                break;
+            case Bytecodes.DMUL           :
+                frame.pushDouble(frame.popDouble() * frame.popDouble());
+                break;
+            case Bytecodes.IDIV           :
+                divInt(frame);
+                break;
+            case Bytecodes.LDIV           :
+                divLong(frame);
+                break;
+            case Bytecodes.FDIV           :
+                divFloat(frame);
+                break;
+            case Bytecodes.DDIV           :
+                divDouble(frame);
+                break;
+            case Bytecodes.IREM           :
+                remInt(frame);
+                break;
+            case Bytecodes.LREM           :
+                remLong(frame);
+                break;
+            case Bytecodes.FREM           :
+                remFloat(frame);
+                break;
+            case Bytecodes.DREM           :
+                remDouble(frame);
+                break;
+            case Bytecodes.INEG           :
+                frame.pushInt(-frame.popInt());
+                break;
+            case Bytecodes.LNEG           :
+                frame.pushLong(-frame.popLong());
+                break;
+            case Bytecodes.FNEG           :
+                frame.pushFloat(-frame.popFloat());
+                break;
+            case Bytecodes.DNEG           :
+                frame.pushDouble(-frame.popDouble());
+                break;
+            case Bytecodes.ISHL           :
+                shiftLeftInt(frame);
+                break;
+            case Bytecodes.LSHL           :
+                shiftLeftLong(frame);
+                break;
+            case Bytecodes.ISHR           :
+                shiftRightSignedInt(frame);
+                break;
+            case Bytecodes.LSHR           :
+                shiftRightSignedLong(frame);
+                break;
+            case Bytecodes.IUSHR          :
+                shiftRightUnsignedInt(frame);
+                break;
+            case Bytecodes.LUSHR          :
+                shiftRightUnsignedLong(frame);
+                break;
+            case Bytecodes.IAND           :
+                frame.pushInt(frame.popInt() & frame.popInt());
+                break;
+            case Bytecodes.LAND           :
+                frame.pushLong(frame.popLong() & frame.popLong());
+                break;
+            case Bytecodes.IOR            :
+                frame.pushInt(frame.popInt() | frame.popInt());
+                break;
+            case Bytecodes.LOR            :
+                frame.pushLong(frame.popLong() | frame.popLong());
+                break;
+            case Bytecodes.IXOR           :
+                frame.pushInt(frame.popInt() ^ frame.popInt());
+                break;
+            case Bytecodes.LXOR           :
+                frame.pushLong(frame.popLong() ^ frame.popLong());
+                break;
+            case Bytecodes.IINC           :
+                iinc(frame, bs);
+                break;
+            case Bytecodes.I2L            :
+                frame.pushLong(frame.popInt());
+                break;
+            case Bytecodes.I2F            :
+                frame.pushFloat(frame.popInt());
+                break;
+            case Bytecodes.I2D            :
+                frame.pushDouble(frame.popInt());
+                break;
+            case Bytecodes.L2I            :
+                frame.pushInt((int) frame.popLong());
+                break;
+            case Bytecodes.L2F            :
+                frame.pushFloat(frame.popLong());
+                break;
+            case Bytecodes.L2D            :
+                frame.pushDouble(frame.popLong());
+                break;
+            case Bytecodes.F2I            :
+                frame.pushInt((int) frame.popFloat());
+                break;
+            case Bytecodes.F2L            :
+                frame.pushLong((long) frame.popFloat());
+                break;
+            case Bytecodes.F2D            :
+                frame.pushDouble(frame.popFloat());
+                break;
+            case Bytecodes.D2I            :
+                frame.pushInt((int) frame.popDouble());
+                break;
+            case Bytecodes.D2L            :
+                frame.pushLong((long) frame.popDouble());
+                break;
+            case Bytecodes.D2F            :
+                frame.pushFloat((float) frame.popDouble());
+                break;
+            case Bytecodes.I2B            :
+                frame.pushInt((byte) frame.popInt());
+                break;
+            case Bytecodes.I2C            :
+                frame.pushInt((char) frame.popInt());
+                break;
+            case Bytecodes.I2S            :
+                frame.pushInt((short) frame.popInt());
+                break;
+            case Bytecodes.LCMP           :
+                compareLong(frame);
+                break;
+            case Bytecodes.FCMPL          :
+                compareFloatLess(frame);
+                break;
+            case Bytecodes.FCMPG          :
+                compareFloatGreater(frame);
+                break;
+            case Bytecodes.DCMPL          :
+                compareDoubleLess(frame);
+                break;
+            case Bytecodes.DCMPG          :
+                compareDoubleGreater(frame);
+                break;
+            case Bytecodes.IFEQ           :
+                if (frame.popInt() == 0) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IFNE           :
+                if (frame.popInt() != 0) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IFLT           :
+                if (frame.popInt() < 0) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IFGE           :
+                if (frame.popInt() >= 0) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IFGT           :
+                if (frame.popInt() > 0) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IFLE           :
+                if (frame.popInt() <= 0) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ICMPEQ      :
+                if (frame.popInt() == frame.popInt()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ICMPNE      :
+                if (frame.popInt() != frame.popInt()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ICMPLT      :
+                if (frame.popInt() > frame.popInt()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ICMPGE      :
+                if (frame.popInt() <= frame.popInt()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ICMPGT      :
+                if (frame.popInt() < frame.popInt()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ICMPLE      :
+                if (frame.popInt() >= frame.popInt()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ACMPEQ      :
+                if (frame.popObject() == frame.popObject()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IF_ACMPNE      :
+                if (frame.popObject() != frame.popObject()) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.GOTO:
+            case Bytecodes.GOTO_W:
+                return BRANCH;
+            case Bytecodes.JSR            :
+            case Bytecodes.JSR_W          :
+                frame.pushInt(bs.currentBCI());
+                return BRANCH;
+            case Bytecodes.RET            :
+                return frame.getInt(frame.resolveLocalIndex(bs.readLocalIndex()));
+            case Bytecodes.TABLESWITCH    :
+                return tableSwitch(frame, bs);
+            case Bytecodes.LOOKUPSWITCH   :
+                return lookupSwitch(frame, bs);
+            case Bytecodes.IRETURN        :
+                frame.getParentFrame().pushInt(frame.popInt());
+                return RETURN;
+            case Bytecodes.LRETURN        :
+                frame.getParentFrame().pushLong(frame.popLong());
+                return RETURN;
+            case Bytecodes.FRETURN        :
+                frame.getParentFrame().pushFloat(frame.popFloat());
+                return RETURN;
+            case Bytecodes.DRETURN        :
+                frame.getParentFrame().pushDouble(frame.popDouble());
+                return RETURN;
+            case Bytecodes.ARETURN        :
+                frame.getParentFrame().pushObject(frame.popObject());
+                return RETURN;
+            case Bytecodes.RETURN         :
+                return RETURN;
+            case Bytecodes.GETSTATIC      :
+                getField(frame, null, bs.currentBC(), bs.readCPI());
+                break;
+            case Bytecodes.PUTSTATIC      :
+                putStatic(frame, bs.readCPI());
+                break;
+            case Bytecodes.GETFIELD:
+                getField(frame, nullCheck(frame.popObject()), bs.currentBC(), bs.readCPI());
+                break;
+            case Bytecodes.PUTFIELD       :
+                putField(frame, bs.readCPI());
+                break;
+            case Bytecodes.INVOKEVIRTUAL  :
+                callFrame = invokeVirtual(frame, bs.readCPI());
+                if (callFrame == null) {
+                    break;
+                }
+                return CALL;
+            case Bytecodes.INVOKESPECIAL  :
+                callFrame = invokeSpecial(frame, bs.readCPI());
+                if (callFrame == null) {
+                    break;
+                }
+                return CALL;
+            case Bytecodes.INVOKESTATIC   :
+                callFrame = invokeStatic(frame, bs.readCPI());
+                if (callFrame == null) {
+                    break;
+                }
+                return CALL;
+            case Bytecodes.INVOKEINTERFACE:
+                callFrame = invokeInterface(frame, bs.readCPI());
+                if (callFrame == null) {
+                    break;
+                }
+                return CALL;
+            case Bytecodes.XXXUNUSEDXXX   :
+                assert false : "unused bytecode used. behaviour unspecfied.";
+                // nop
+                break;
+            case Bytecodes.NEW            :
+                frame.pushObject(allocateInstance(frame, bs.readCPI()));
+                break;
+            case Bytecodes.NEWARRAY       :
+                frame.pushObject(allocateNativeArray(frame, bs.readByte()));
+                break;
+            case Bytecodes.ANEWARRAY      :
+                frame.pushObject(allocateArray(frame, bs.readCPI()));
+                break;
+            case Bytecodes.ARRAYLENGTH    :
+                frame.pushInt(Array.getLength(nullCheck(frame.popObject())));
+                break;
+            case Bytecodes.ATHROW         :
+                throw (Throwable) frame.popObject();
+            case Bytecodes.CHECKCAST      :
+                checkCast(frame, bs.readCPI());
+                break;
+            case Bytecodes.INSTANCEOF     :
+                instanceOf(frame, bs.readCPI());
+                break;
+            case Bytecodes.MONITORENTER   :
+                vm.monitorEnter(frame.popObject());
+                break;
+            case Bytecodes.MONITOREXIT    :
+                vm.monitorExit(frame.popObject());
+                break;
+            case Bytecodes.WIDE           :
+                assert false;
+                break;
+            case Bytecodes.MULTIANEWARRAY :
+                frame.pushObject(allocateMultiArray(frame, bs.readCPI(), bs.readUByte(bs.currentBCI() + 3)));
+                break;
+            case Bytecodes.IFNULL         :
+                if (frame.popObject() == null) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.IFNONNULL      :
+                if (frame.popObject() != null) {
+                    return BRANCH;
+                }
+                break;
+            case Bytecodes.BREAKPOINT     :
+                assert false : "no breakpoints supported at this time.";
+                break; // nop
+        }
+        return NEXT;
+    }
+
+    private InterpreterFrame handleThrowable(InterpreterFrame root, InterpreterFrame frame, Throwable t) {
+        ExceptionHandler handler;
+        InterpreterFrame currentFrame = frame;
+        do {
+            handler = resolveExceptionHandlers(currentFrame, currentFrame.getBCI(), t);
+            if (handler == null) {
+                // no handler found pop frame
+                // and continue searching
+                currentFrame = popFrame(currentFrame);
+            } else {
+                // found a handler -> execute it
+                if (handler.isCatchAll()) {
+                    catchAllExceptionHandler = handler;
+                } else {
+                    catchAllExceptionHandler = null;
+                }
+                currentFrame.setBCI(handler.handlerBCI());
+                currentFrame.popStack();
+                currentFrame.pushObject(t);
+                return currentFrame;
+            }
+        } while (handler == null && currentFrame != root);
+
+        // will throw exception up the interpreter
+        return null;
+    }
+
+    private void updateStackTrace(InterpreterFrame frame, Throwable t) {
+        StackTraceElement[] elements = getBackTrace(frame, t);
+        if (elements != null) {
+            setStackTrace(frame, t, elements);
+            setBackTrace(frame, t, null);
+        } else {
+            setBackTrace(frame, t, createStackTraceElements(frame));
+        }
+    }
+
+
+    private void setStackTrace(InterpreterFrame frame, Throwable t, StackTraceElement[] stackTrace) {
+      vm.setField(stackTrace, t,  findThrowableField(frame, "stackTrace"));
+    }
+
+    private StackTraceElement[] getBackTrace(InterpreterFrame frame, Throwable t) {
+        Object value = vm.getField(t, findThrowableField(frame, "backtrace"));
+        if (value instanceof StackTraceElement[]) {
+            return (StackTraceElement[]) value;
+        }
+        return null;
+    }
+
+    private void setBackTrace(InterpreterFrame frame, Throwable t, StackTraceElement[] backtrace) {
+        vm.setField(backtrace, t, findThrowableField(frame, "backtrace"));
+    }
+
+    private ExceptionHandler resolveExceptionHandlers(InterpreterFrame frame, int bci, Throwable t) {
+        ExceptionHandler[] handlers = frame.getMethod().exceptionHandlers();
+        for (int i = 0; i < handlers.length; i++) {
+            ExceptionHandler handler = handlers[i];
+            if (bci >= handler.startBCI()
+                            && bci <= handler.endBCI()
+                            && (catchAllExceptionHandler == null || !handler.isCatchAll())) {
+                ResolvedJavaType catchType = null;
+                if (!handler.isCatchAll()) {
+                    catchType = resolveType(frame, bci, (char) handler.catchTypeCPI());
+                }
+
+                if (catchType == null
+                                || catchType.toJava().isInstance(t)) {
+                    // the first found exception handler is our exception handler
+                   return handler;
+                }
+            }
+        }
+        return null;
+    }
+
+    private InterpreterFrame allocateFrame(InterpreterFrame frame, BytecodeStream bs) {
+        try {
+            stackFrameDepth++;
+
+            InterpreterFrame nextFrame = this.callFrame;
+
+            assert nextFrame != null;
+            assert nextFrame.getParentFrame() == frame;
+
+            // store bci when leaving method
+            frame.setBCI(bs.currentBCI());
+
+            if (TRACE) {
+                traceCall(nextFrame, "Call");
+            }
+            if (Modifier.isSynchronized(nextFrame.getMethod().accessFlags())) {
+                if (TRACE) {
+                    traceOp("Method monitor enter");
+                }
+                if (Modifier.isStatic(nextFrame.getMethod().accessFlags())) {
+                    vm.monitorEnter(nextFrame.getMethod().holder().toJava());
+                } else {
+                    Object enterObject = nextFrame.getObject(frame.resolveLocalIndex(0));
+                    assert enterObject != null;
+                    vm.monitorEnter(enterObject);
+                }
+            }
+
+            return nextFrame;
+        } finally {
+            // catch all exception handlers are not allowed to call any method anyway.
+            catchAllExceptionHandler = null;
+            callFrame = null;
+            bs.next();
+        }
+    }
+
+    private InterpreterFrame popFrame(InterpreterFrame frame) {
+        catchAllExceptionHandler = null;
+        InterpreterFrame parent = frame.getParentFrame();
+        if (Modifier.isSynchronized(frame.getMethod().accessFlags())) {
+            if (TRACE) {
+                traceOp("Method monitor exit");
+            }
+            if (Modifier.isStatic(frame.getMethod().accessFlags())) {
+                vm.monitorExit(frame.getMethod().holder().toJava());
+            } else {
+                Object exitObject = frame.getObject(frame.resolveLocalIndex(0));
+                if (exitObject != null) {
+                    vm.monitorExit(exitObject);
+                }
+            }
+        }
+        if (TRACE) {
+            traceCall(frame, "Ret");
+        }
+        stackFrameDepth--;
+
+        frame.dispose();
+        return parent;
+    }
+
+    private void traceOp(String opName) {
+        trace(stackFrameDepth + 1, opName);
+    }
+
+    private void traceCall(InterpreterFrame frame, String type) {
+        trace(stackFrameDepth, type + " " +
+                        frame.getMethod() + " - " + frame.getMethod().signature().asString());
+    }
+
+    private void trace(int level, String message) {
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < level; i++) {
+            builder.append("  ");
+        }
+        builder.append(message);
+        System.out.println(builder);
+    }
+
+
+    private void divInt(InterpreterFrame frame) {
+        int dividend = frame.popInt();
+        int divisor = frame.popInt();
+        frame.pushInt(divisor / dividend);
+    }
+
+    private void divLong(InterpreterFrame frame) {
+        long dividend = frame.popLong();
+        long divisor = frame.popLong();
+        frame.pushLong(divisor / dividend);
+    }
+
+    private void divFloat(InterpreterFrame frame) {
+        float dividend = frame.popFloat();
+        float divisor = frame.popFloat();
+        frame.pushFloat(divisor / dividend);
+    }
+
+    private void divDouble(InterpreterFrame frame) {
+        double dividend = frame.popDouble();
+        double divisor = frame.popDouble();
+        frame.pushDouble(divisor / dividend);
+    }
+
+
+    private void remInt(InterpreterFrame frame) {
+        int dividend = frame.popInt();
+        int divisor = frame.popInt();
+        frame.pushInt(divisor % dividend);
+    }
+
+    private void remLong(InterpreterFrame frame) {
+        long dividend = frame.popLong();
+        long divisor = frame.popLong();
+        frame.pushLong(divisor % dividend);
+    }
+
+    private void remFloat(InterpreterFrame frame) {
+        float dividend = frame.popFloat();
+        float divisor = frame.popFloat();
+        frame.pushFloat(divisor % dividend);
+    }
+
+    private void remDouble(InterpreterFrame frame) {
+        double dividend = frame.popDouble();
+        double divisor = frame.popDouble();
+        frame.pushDouble(divisor % dividend);
+    }
+
+    private void shiftLeftInt(InterpreterFrame frame) {
+        int bits = frame.popInt();
+        int value = frame.popInt();
+        frame.pushInt(value << bits);
+    }
+
+    private void shiftLeftLong(InterpreterFrame frame) {
+        int bits = frame.popInt();
+        long value = frame.popLong();
+        frame.pushLong(value << bits);
+    }
+
+    private void shiftRightSignedInt(InterpreterFrame frame) {
+        int bits = frame.popInt();
+        int value = frame.popInt();
+        frame.pushInt(value >> bits);
+    }
+
+    private void shiftRightSignedLong(InterpreterFrame frame) {
+        int bits = frame.popInt();
+        long value = frame.popLong();
+        frame.pushLong(value >> bits);
+    }
+
+    private void shiftRightUnsignedInt(InterpreterFrame frame) {
+        int bits = frame.popInt();
+        int value = frame.popInt();
+        frame.pushInt(value >>> bits);
+    }
+
+    private void shiftRightUnsignedLong(InterpreterFrame frame) {
+        int bits = frame.popInt();
+        long value = frame.popLong();
+        frame.pushLong(value >>> bits);
+    }
+
+    private int lookupSwitch(InterpreterFrame frame, BytecodeStream bs) {
+        return lookupSearch(
+                        new BytecodeLookupSwitch(bs, bs.currentBCI()), frame.popInt());
+    }
+
+    /**
+     * Binary search implementation for the lookup switch.
+     */
+    private int lookupSearch(BytecodeLookupSwitch switchHelper, int key) {
+        int low = 0;
+        int high = switchHelper.numberOfCases() - 1;
+        while (low <= high) {
+            int mid = (low + high) >>> 1;
+            int midVal = switchHelper.keyAt(mid);
+
+            if (midVal < key) {
+                low = mid + 1;
+            } else if (midVal > key) {
+                high = mid - 1;
+            } else {
+                return switchHelper.bci() + switchHelper.offsetAt(mid); // key found
+            }
+        }
+        return switchHelper.defaultTarget();  // key not found.
+    }
+
+    private int tableSwitch(InterpreterFrame frame, BytecodeStream bs) {
+        BytecodeTableSwitch switchHelper = new BytecodeTableSwitch(bs, bs.currentBCI());
+
+        int low = switchHelper.lowKey();
+        int high = switchHelper.highKey();
+
+        assert low <= high;
+
+        int index = frame.popInt();
+        if (index < low || index > high) {
+            return switchHelper.defaultTarget();
+        } else {
+            return switchHelper.targetAt(index - low);
+        }
+    }
+
+    private void checkCast(InterpreterFrame frame, char cpi) {
+        frame.pushObject(resolveType(frame, Bytecodes.CHECKCAST, cpi).toJava().cast(frame.popObject()));
+    }
+
+    private ResolvedJavaType resolveType(InterpreterFrame frame, int opcode, char cpi) {
+        ConstantPool constantPool = frame.getConstantPool();
+        constantPool.loadReferencedType(cpi, opcode);
+        return constantPool.lookupType(cpi, opcode).resolve(frame.getMethod().holder());
+    }
+
+    private ResolvedJavaType resolveType(InterpreterFrame frame, Class<?> javaClass) {
+        return vm.getRuntime().getResolvedJavaType(javaClass).resolve(frame.getMethod().holder());
+    }
+
+    private ResolvedJavaMethod resolveMethod(InterpreterFrame frame, int opcode, char cpi) {
+        ConstantPool constantPool = frame.getConstantPool();
+        constantPool.loadReferencedType(cpi, opcode);
+        return (ResolvedJavaMethod) constantPool.lookupMethod(cpi, opcode);
+    }
+
+    private ResolvedJavaField resolveField(InterpreterFrame frame, int opcode, char cpi) {
+        ConstantPool constantPool = frame.getConstantPool();
+        constantPool.loadReferencedType(cpi, opcode);
+        return (ResolvedJavaField) constantPool.lookupField(cpi, opcode);
+    }
+
+    private void instanceOf(InterpreterFrame frame, char cpi) {
+        frame.pushInt(resolveType(frame, Bytecodes.INSTANCEOF, cpi).
+                        toJava().isInstance(frame.popObject())
+                        ? 1 : 0);
+    }
+
+    private void pushCPConstant(InterpreterFrame frame, char cpi) {
+        ResolvedJavaMethod method = frame.getMethod();
+        Object constant = method.getConstantPool().lookupConstant(cpi);
+
+        if (constant instanceof Constant) {
+            Constant c = ((Constant) constant);
+            switch (c.kind) {
+                case Int :
+                    frame.pushInt(c.asInt());
+                    break;
+                case Float:
+                    frame.pushFloat(c.asFloat());
+                    break;
+                case Object:
+                    frame.pushObject(c.asObject());
+                    break;
+                case Double :
+                    frame.pushDouble(c.asDouble());
+                    break;
+                case Long :
+                    frame.pushLong(c.asLong());
+                    break;
+                default:
+                    assert false : "unspecified case";
+            }
+        } else if (constant instanceof JavaType) {
+            frame.pushObject(((JavaType) constant).resolve(method.holder()).toJava());
+        } else {
+            assert false : "unexpected case";
+        }
+    }
+
+    private void compareLong(InterpreterFrame frame) {
+        long y = frame.popLong();
+        long x = frame.popLong();
+        frame.pushInt((x < y) ? -1 : ((x == y) ? 0 : 1));
+    }
+
+    private void compareDoubleGreater(InterpreterFrame frame) {
+        double y = frame.popDouble();
+        double x = frame.popDouble();
+        frame.pushInt(x < y ? -1 : ((x == y) ? 0 : 1));
+    }
+
+    private void compareDoubleLess(InterpreterFrame frame) {
+        double y = frame.popDouble();
+        double x = frame.popDouble();
+        frame.pushInt(x > y ? 1 : ((x == y) ? 0 : -1));
+    }
+
+    private void compareFloatGreater(InterpreterFrame frame) {
+        float y = frame.popFloat();
+        float x = frame.popFloat();
+        frame.pushInt(x < y ? -1 : ((x == y) ? 0 : 1));
+    }
+
+    private void compareFloatLess(InterpreterFrame frame) {
+        float y = frame.popFloat();
+        float x = frame.popFloat();
+        frame.pushInt(x > y ? 1 : ((x == y) ? 0 : -1));
+    }
+
+    private Object nullCheck(Object value) {
+        if (value == null) {
+            throw new NullPointerException();
+        }
+        return value;
+    }
+    private InterpreterFrame invokeStatic(InterpreterFrame frame, char cpi) throws Throwable {
+        return invoke(frame, resolveMethod(frame, Bytecodes.INVOKESTATIC, cpi), null);
+    }
+
+    private InterpreterFrame invokeInterface(InterpreterFrame frame, char cpi) throws Throwable {
+        return resolveAndInvoke(frame, resolveMethod(frame, Bytecodes.INVOKEINTERFACE, cpi));
+    }
+
+    private InterpreterFrame resolveAndInvoke(InterpreterFrame parent, ResolvedJavaMethod m) throws Throwable {
+        Object receiver = nullCheck(parent.peekReceiver(m));
+
+        ResolvedJavaMethod method = resolveType(parent, receiver.getClass()).resolveMethodImpl(m);
+
+        if (method == null) {
+            throw new AbstractMethodError();
+        }
+
+        return invoke(parent, method, receiver);
+    }
+
+    private InterpreterFrame invokeVirtual(InterpreterFrame frame, char cpi) throws Throwable {
+        ResolvedJavaMethod m = resolveMethod(frame, Bytecodes.INVOKEVIRTUAL, cpi);
+        if (Modifier.isFinal(m.accessFlags())) {
+            return invoke(frame, m, nullCheck(frame.peekReceiver(m)));
+        } else {
+            return resolveAndInvoke(frame, m);
+        }
+    }
+
+    private InterpreterFrame invokeSpecial(InterpreterFrame frame, char cpi) throws Throwable {
+        ResolvedJavaMethod m = resolveMethod(frame, Bytecodes.INVOKESPECIAL, cpi);
+        return invoke(frame, m, nullCheck(frame.peekReceiver(m)));
+    }
+
+    private void invokeReflective(InterpreterFrame frame, ResolvedJavaMethod method, boolean hasReceiver) throws Throwable {
+        Class<?>[] parameterTypes = resolveMethodArguments(method);
+        Object[] parameters = popArgumentsAsObject(frame, method);
+        Class<?> javaClass = method.holder().toJava();
+
+        Object parentObject = null;
+        if (hasReceiver) {
+            parentObject = frame.popObject();
+            nullCheck(parentObject);
+        }
+        Object returnValue = null;
+
+        if (redirect(method)) {
+            if (TRACE) {
+                traceCall(frame, "Delegate " + method);
+            }
+            try {
+                returnValue = methodDelegates.get(method).invoke(frame, method, parentObject, parameters);
+            } catch (Throwable e) {
+                throw e;
+            }
+        } else {
+            if (TRACE) {
+                traceCall(frame, "Reflective " + method);
+            }
+            try {
+                Method javaMethod = javaClass.getDeclaredMethod(method.name(), parameterTypes);
+                javaMethod.setAccessible(true);
+                returnValue = javaMethod.invoke(parentObject, parameters);
+            } catch (InvocationTargetException e) {
+                e.printStackTrace(System.out);
+                throw e.getTargetException();
+            } catch (NoSuchMethodException | SecurityException e) {
+                throw new AbstractMethodError();
+            }
+        }
+
+        pushAsObject(frame, method.signature().returnKind(), returnValue);
+    }
+
+    private Object[] popArgumentsAsObject(InterpreterFrame frame, ResolvedJavaMethod method) {
+        Signature signature = method.signature();
+        int argumentCount = method.signature().argumentCount(false);
+        Object[] parameters = new Object[argumentCount];
+        for (int i = argumentCount - 1; i >= 0; i--) {
+            ResolvedJavaType type = signature.argumentTypeAt(i, method.holder()).resolve(method.holder());
+            parameters[i] =  popAsObject(frame, type.kind());
+        }
+        return parameters;
+    }
+
+    private Class<?>[] resolveMethodArguments(ResolvedJavaMethod method) {
+        Signature signature = method.signature();
+        int argumentCount = signature.argumentCount(false);
+        Class<?>[] parameterTypes = new Class[argumentCount];
+
+        for (int i = 0; i < argumentCount; i++) {
+            JavaType type = signature.argumentTypeAt(i, method.holder());
+            ResolvedJavaType resolvedType = type.resolve(method.holder());
+            parameterTypes[i] = resolvedType.toJava();
+        }
+        return parameterTypes;
+    }
+
+    private InterpreterFrame invoke(InterpreterFrame parent, ResolvedJavaMethod method, Object receiver) throws Throwable {
+        if (stackFrameDepth >= maxStackFrames) {
+            throw new StackOverflowError("Maximum callstack of " + maxStackFrames + " exceeded.");
+        }
+        if (redirect(method)) {
+            invokeReflective(parent, method, receiver != null);
+
+            // returning null results in a jump to the next instruction
+            // since the method is already successfully invoked.
+            return null;
+        } else {
+            if (Modifier.isNative(method.accessFlags())) {
+                invokeReflective(parent, method, receiver != null);
+                return null;
+            } else {
+                return parent.create(method, receiver != null);
+            }
+        }
+    }
+
+    private boolean redirect(ResolvedJavaMethod method) {
+        return methodDelegates.containsKey(method);
+    }
+
+
+    private Object allocateMultiArray(InterpreterFrame frame, char cpi, int dimension) {
+        ResolvedJavaType type = resolveType(frame, Bytecodes.MULTIANEWARRAY, cpi);
+        int[] dimensions = new int[dimension];
+        for (int i = 0; i < dimension; i++) {
+            dimensions[i] = frame.popInt();
+        }
+        return Array.newInstance(type.toJava(), dimensions);
+    }
+
+    private Object allocateArray(InterpreterFrame frame, char cpi) {
+        ResolvedJavaType type = resolveType(frame, Bytecodes.ANEWARRAY, cpi);
+        return Array.newInstance(type.toJava(), frame.popInt());
+    }
+
+    private Object allocateNativeArray(InterpreterFrame frame, byte cpi) {
+        // the constants for the cpi are loosely defined and no real cpi indices.
+        switch (cpi) {
+            case 4 :
+                return new byte[frame.popInt()];
+            case 8 :
+                return new byte[frame.popInt()];
+            case 5 :
+                return new char[frame.popInt()];
+            case 7 :
+                return new double[frame.popInt()];
+            case 6 :
+                return new float[frame.popInt()];
+            case 10 :
+                return new int[frame.popInt()];
+            case 11 :
+                return new long[frame.popInt()];
+            case 9 :
+                return new short[frame.popInt()];
+            default:
+                assert false : "unexpected case";
+                return null;
+        }
+    }
+
+    private Object allocateInstance(InterpreterFrame frame, char cpi) throws InstantiationException {
+        return vm.newObject(resolveType(frame, Bytecodes.NEW, cpi));
+    }
+
+    private void iinc(InterpreterFrame frame, BytecodeStream bs) {
+        int index = frame.resolveLocalIndex(bs.readLocalIndex());
+        frame.setInt(index, frame.getInt(index) + bs.readIncrement());
+    }
+
+    private void putStatic(InterpreterFrame frame, char cpi) {
+        putFieldStatic(frame, resolveField(frame, Bytecodes.PUTSTATIC, cpi));
+    }
+
+    private void putField(InterpreterFrame frame, char cpi) {
+        putFieldVirtual(frame, resolveField(frame, Bytecodes.PUTFIELD, cpi));
+    }
+
+    private void putFieldStatic(InterpreterFrame frame, ResolvedJavaField field) {
+        switch (field.kind()) {
+            case Boolean :
+            case Byte :
+            case Char :
+            case Short :
+            case Int :
+                vm.setFieldInt(frame.popInt(), null, field);
+                break;
+            case Double :
+                vm.setFieldDouble(frame.popDouble(), null, field);
+                break;
+            case Float :
+                vm.setFieldFloat(frame.popFloat(), null, field);
+                break;
+            case Long :
+                vm.setFieldLong(frame.popLong(), null, field);
+                break;
+            case Object :
+                vm.setField(frame.popObject(), null, field);
+                break;
+            default :
+                assert false : "unexpected case";
+        }
+    }
+
+    private void putFieldVirtual(InterpreterFrame frame, ResolvedJavaField field) {
+        switch (field.kind()) {
+            case Boolean :
+            case Byte :
+            case Char :
+            case Short :
+            case Int :
+                vm.setFieldInt(frame.popInt(), nullCheck(frame.popObject()), field);
+                break;
+            case Double :
+                vm.setFieldDouble(frame.popDouble(), nullCheck(frame.popObject()), field);
+                break;
+            case Float :
+                vm.setFieldFloat(frame.popFloat(), nullCheck(frame.popObject()), field);
+                break;
+            case Long :
+                vm.setFieldLong(frame.popLong(), nullCheck(frame.popObject()), field);
+                break;
+            case Object :
+                vm.setField(frame.popObject(), nullCheck(frame.popObject()), field);
+                break;
+            default :
+                assert false : "unexpected case";
+        }
+    }
+
+    private void getField(InterpreterFrame frame, Object base, int opcode, char cpi) {
+        ResolvedJavaField field = resolveField(frame, opcode, cpi);
+        switch (field.kind()) {
+            case Boolean :
+            case Byte :
+            case Char :
+            case Short :
+            case Int :
+                frame.pushInt(vm.getFieldInt(base, field));
+                break;
+            case Double :
+                frame.pushDouble(vm.getFieldDouble(base, field));
+                break;
+            case Float :
+                frame.pushFloat(vm.getFieldFloat(base, field));
+                break;
+            case Long :
+                frame.pushLong(vm.getFieldLong(base, field));
+                break;
+            case Object :
+                frame.pushObject(vm.getField(base, field));
+                break;
+            default :
+                assert false : "unexpected case";
+        }
+    }
+
+
+    private int pushAsObject(InterpreterFrame frame, Kind typeKind, Object value) {
+        switch(typeKind) {
+            case Int :
+                frame.pushInt((int) value);
+                break;
+            case Long :
+                frame.pushLong((long) value);
+                return 2;
+            case Boolean :
+                frame.pushInt(((boolean) value) ? 1 : 0);
+                break;
+            case Byte :
+                frame.pushInt((byte) value);
+                break;
+            case Char :
+                frame.pushInt((char) value);
+                break;
+            case Double :
+                frame.pushDouble((double) value);
+                return 2;
+            case Float :
+                frame.pushFloat((float) value);
+                break;
+            case Short :
+                frame.pushInt((short) value);
+                break;
+            case Object :
+                frame.pushObject(value);
+                break;
+            case Void :
+                return 0;
+            default :
+                assert false : "case not specified";
+        }
+        return 1;
+    }
+
+    private Object popAsObject(InterpreterFrame frame, Kind typeKind) {
+        switch (typeKind) {
+            case Boolean :
+                return frame.popInt() == 1 ? true : false;
+            case Byte :
+                return (byte) frame.popInt();
+            case Char :
+                return (char) frame.popInt();
+            case Double :
+                return frame.popDouble();
+            case Int :
+                return frame.popInt();
+            case Float :
+                return frame.popFloat();
+            case Long :
+                return frame.popLong();
+            case Short :
+                return (short) frame.popInt();
+            case Object :
+                return frame.popObject();
+            case Void :
+                return null;
+            default :
+                assert false : "unexpected case";
+        }
+        return null;
+    }
+
+    private ResolvedJavaMethod resolveRootMethod() {
+        try {
+            return vm.getRuntime().getResolvedJavaMethod(BytecodeInterpreter.class.getDeclaredMethod("execute", Method.class, Object[].class));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static Method findMethod(Class<?> clazz, String name, Class<?> ... parameters) {
+        try {
+            return clazz.getDeclaredMethod(name, parameters);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static StackTraceElement[] createStackTraceElements(InterpreterFrame frame) {
+        InterpreterFrame tmp = frame;
+        List<StackTraceElement> elements = new ArrayList<>();
+        boolean first = false; // filter only first stack elements
+        while (tmp != null) {
+            if (first || !filterStackElement(tmp)) {
+                first = true;
+                elements.add(tmp.getMethod().toStackTraceElement(tmp.getBCI()));
+            }
+            tmp = tmp.getParentFrame();
+        }
+        return elements.toArray(new StackTraceElement[elements.size()]);
+    }
+
+    private static boolean filterStackElement(InterpreterFrame frame) {
+        return Throwable.class.isAssignableFrom(frame.getMethod().holder().toJava());
+    }
+
+    private ResolvedJavaField findThrowableField(InterpreterFrame frame, String name) {
+        ResolvedJavaType throwableType = resolveType(frame, Throwable.class);
+        ResolvedJavaField[] fields = throwableType.declaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            if (fields[i].name().equals(name)) {
+                return fields[i];
+            }
+        }
+        assert false;
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/Frame.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,134 @@
+/*
+ * 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.interpreter;
+
+import java.lang.reflect.*;
+
+import sun.misc.*;
+
+public class Frame {
+
+    public static final Object[] EMPTY_ARRAY = new Object[0];
+    public static final int PARENT_FRAME_SLOT = 0;
+    public static final int MIN_FRAME_SIZE = 1;
+    private static final Unsafe unsafe = getUnsafe();
+
+    protected final Object[] locals;
+    protected final long[] primitiveLocals;
+
+    public Frame(int numLocals, Frame parent) {
+        assert numLocals >= MIN_FRAME_SIZE;
+        this.locals = new Object[numLocals];
+        this.locals[PARENT_FRAME_SLOT] = parent;
+        this.primitiveLocals = new long[numLocals];
+    }
+
+    public Frame(int numLocals) {
+        this(numLocals, null);
+    }
+
+    public Object getObject(int index) {
+        return locals[index];
+    }
+
+    public void setObject(int index, Object value) {
+        locals[index] = value;
+    }
+
+    public float getFloat(int index) {
+        return unsafe.getFloat(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+    }
+
+    public void setFloat(int index, float value) {
+        unsafe.putFloat(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+    }
+
+    public long getLong(int index) {
+        return unsafe.getLong(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+    }
+
+    public void setLong(int index, long value) {
+        unsafe.putLong(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+    }
+
+    public int getInt(int index) {
+        return unsafe.getInt(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+    }
+
+    public void setInt(int index, int value) {
+        unsafe.putInt(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+    }
+
+    public double getDouble(int index) {
+        return unsafe.getDouble(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+    }
+
+    public void setDouble(int index, double value) {
+        unsafe.putDouble(primitiveLocals, (long) index * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+    }
+
+    public static Frame getParentFrame(Frame frame, int level) {
+        assert level >= 0;
+        if (level == 0) {
+            return frame;
+        } else {
+            return getParentFrame((Frame) frame.getObject(PARENT_FRAME_SLOT), level - 1);
+        }
+    }
+
+    public static Frame getTopFrame(Frame frame) {
+        Frame parentFrame = (Frame) frame.getObject(PARENT_FRAME_SLOT);
+        if (parentFrame == null) {
+            return frame;
+        } else {
+            return getTopFrame(parentFrame);
+        }
+    }
+
+    public static Object[] getArguments(Frame frame, int argOffset) {
+        return (Object[]) frame.getObject(argOffset);
+    }
+
+    public int size() {
+        return locals.length;
+    }
+
+    @SuppressWarnings("unused")
+    private boolean indexExists(int index) {
+        return index >= 0 && index < locals.length;
+    }
+
+    private static Unsafe getUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterCallable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -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.interpreter;
+
+import com.oracle.graal.api.meta.*;
+
+
+public interface InterpreterCallable {
+
+    Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object base, Object[] arguments) throws Throwable;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterException.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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.interpreter;
+
+/**
+ * Thrown if executed byte code caused an error in {@link BytecodeInterpreter}. The actual execution exception is
+ * accessible using {@link #getCause()} or {@link #getExecutionThrowable()}.
+ */
+public class InterpreterException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    public InterpreterException(Throwable cause) {
+        super(cause);
+    }
+
+    public Throwable getExecutionThrowable() {
+        return getCause();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/InterpreterFrame.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,351 @@
+/*
+ * 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.interpreter;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+public class InterpreterFrame extends Frame {
+
+    public static final int BASE_LENGTH = 3;
+
+    private static final int METHOD_FRAME_SLOT = 1;
+    private static final int BCI_FRAME_SLOT = 2;
+
+    private static final int DOUBLE = 2;
+    private static final int SINGLE = 1;
+
+    /** Pointer to the top-most stack frame element. */
+    private int tos;
+
+    public InterpreterFrame(ResolvedJavaMethod method, int additionalStackSpace) {
+        this(method, null, additionalStackSpace);
+    }
+
+    private InterpreterFrame(ResolvedJavaMethod method, InterpreterFrame parent, int additionalStackSpace) {
+        super(method.maxLocals() + method.maxStackSize() + BASE_LENGTH + additionalStackSpace, parent);
+        setMethod(method);
+        setBCI(0);
+        this.tos = BASE_LENGTH;
+    }
+
+    public InterpreterFrame create(ResolvedJavaMethod method, boolean hasReceiver) {
+        InterpreterFrame frame = new InterpreterFrame(method, this, 0);
+        int length = method.signature().argumentSlots(hasReceiver);
+
+        frame.pushVoid(method.maxLocals());
+        if (length > 0) {
+            copyArguments(frame, length);
+            popVoid(length);
+        }
+
+        return frame;
+    }
+
+    public int resolveLocalIndex(int index) {
+        return BASE_LENGTH + index;
+    }
+
+    private int stackTos() {
+        return BASE_LENGTH + getMethod().maxLocals();
+    }
+
+    private void copyArguments(InterpreterFrame dest, int length) {
+        System.arraycopy(locals, tosSingle(length - 1), dest.locals,
+                        BASE_LENGTH, length);
+        System.arraycopy(primitiveLocals, tosSingle(length - 1), dest.primitiveLocals,
+                        BASE_LENGTH, length);
+    }
+
+
+    public Object peekReceiver(ResolvedJavaMethod method) {
+        return getObject(tosSingle(method.signature().argumentSlots(false)));
+    }
+
+    public void pushBoth(Object oValue, int intValue) {
+        incrementTos(SINGLE);
+        setObject(tosSingle(0), oValue);
+        setInt(tosSingle(0), intValue);
+    }
+
+    public void pushBoth(Object oValue, long longValue) {
+        incrementTos(SINGLE);
+        setObject(tosSingle(0), oValue);
+        setLong(tosSingle(0), longValue);
+    }
+
+    public void pushObject(Object value) {
+        incrementTos(SINGLE);
+        setObject(tosSingle(0), value);
+    }
+
+    public void pushInt(int value) {
+        incrementTos(SINGLE);
+        setInt(tosSingle(0), value);
+    }
+
+    public void pushDouble(double value) {
+        incrementTos(DOUBLE);
+        setDouble(tosDouble(0), value);
+    }
+
+    public void pushFloat(float value) {
+        incrementTos(SINGLE);
+        setFloat(tosSingle(0), value);
+    }
+
+    public void pushLong(long value) {
+        incrementTos(DOUBLE);
+        setLong(tosDouble(0), value);
+    }
+
+    public int popInt() {
+        int value = getInt(tosSingle(0));
+        decrementTos(SINGLE);
+        return value;
+    }
+
+    public double popDouble() {
+        double value = getDouble(tosDouble(0));
+        decrementTos(DOUBLE);
+        return value;
+    }
+
+    public float popFloat() {
+        float value = getFloat(tosSingle(0));
+        decrementTos(SINGLE);
+        return value;
+    }
+
+    public long popLong() {
+        long value = getLong(tosDouble(0));
+        decrementTos(DOUBLE);
+        return value;
+    }
+
+    public Object popObject() {
+        Object value = getObject(tosSingle(0));
+        decrementTos(SINGLE);
+        return value;
+    }
+
+    public void swapSingle() {
+        int tmpInt = getInt(tosSingle(1));
+        Object tmpObject = getObject(tosSingle(1));
+
+        setInt(tosSingle(1), getInt(tosSingle(0)));
+        setObject(tosSingle(1), getObject(tosSingle(0)));
+
+        setInt(tosSingle(0), tmpInt);
+        setObject(tosSingle(0), tmpObject);
+    }
+
+    public void dupx1() {
+        long tosLong = getLong(tosSingle(0));
+        Object tosObject = getObject(tosSingle(0));
+
+        swapSingle();
+
+        pushBoth(tosObject, tosLong);
+    }
+
+    public void dup2x1() {
+        long tosLong2 = getLong(tosSingle(2));
+        Object tosObject2 = getObject(tosSingle(2));
+        long tosLong1 = getLong(tosSingle(1));
+        Object tosObject1 = getObject(tosSingle(1));
+        long tosLong0 = getLong(tosSingle(0));
+        Object tosObject0 = getObject(tosSingle(0));
+
+        popVoid(3);
+
+        pushBoth(tosObject1, tosLong1);
+        pushBoth(tosObject0, tosLong0);
+
+        pushBoth(tosObject2, tosLong2);
+
+        pushBoth(tosObject1, tosLong1);
+        pushBoth(tosObject0, tosLong0);
+    }
+
+    public void dup2x2() {
+        long tosLong3 = getLong(tosSingle(3));
+        Object tosObject3 = getObject(tosSingle(3));
+        long tosLong2 = getLong(tosSingle(2));
+        Object tosObject2 = getObject(tosSingle(2));
+        long tosLong1 = getLong(tosSingle(1));
+        Object tosObject1 = getObject(tosSingle(1));
+        long tosLong0 = getLong(tosSingle(0));
+        Object tosObject0 = getObject(tosSingle(0));
+
+        popVoid(4);
+
+        pushBoth(tosObject1, tosLong1);
+        pushBoth(tosObject0, tosLong0);
+
+        pushBoth(tosObject3, tosLong3);
+        pushBoth(tosObject2, tosLong2);
+
+        pushBoth(tosObject1, tosLong1);
+        pushBoth(tosObject0, tosLong0);
+    }
+
+    public void dupx2() {
+        long tosLong2 = getLong(tosSingle(2));
+        Object tosObject2 = getObject(tosSingle(2));
+        long tosLong1 = getLong(tosSingle(1));
+        Object tosObject1 = getObject(tosSingle(1));
+        long tosLong0 = getLong(tosSingle(0));
+        Object tosObject0 = getObject(tosSingle(0));
+
+        popVoid(3);
+
+        pushBoth(tosObject0, tosLong0);
+        pushBoth(tosObject2, tosLong2);
+        pushBoth(tosObject1, tosLong1);
+        pushBoth(tosObject0, tosLong0);
+    }
+
+    public void dup(int length) {
+        assert length > 0;
+        for (int i = 0; i < length; i++) {
+            long valueN1 = getLong(tosSingle(length - i - 1));
+            Object valueO1 = getObject(tosSingle(length - i - 1));
+
+            pushVoid(1);
+
+            setLong(tosSingle(0), valueN1);
+            setObject(tosSingle(0), valueO1);
+        }
+    }
+
+    private void incrementTos(int size) {
+        tos += size;
+    }
+
+    private void decrementTos(int size) {
+        tos -= size;
+    }
+
+    private int tosDouble(int offset) {
+        assert offset >= 0;
+        return tos - DOUBLE - (offset * DOUBLE);
+    }
+
+    private int tosSingle(int offset) {
+        assert offset >= 0;
+        return tos - SINGLE - offset;
+    }
+
+    public int getStackTop() {
+        return tos;
+    }
+
+    public void pushVoid(int count) {
+        incrementTos(count * SINGLE);
+    }
+
+    public void popVoid(int count) {
+        decrementTos(count * SINGLE);
+    }
+
+    public ConstantPool getConstantPool() {
+        return getMethod().getConstantPool();
+    }
+
+    private void setMethod(ResolvedJavaMethod method) {
+        setObject(METHOD_FRAME_SLOT, method);
+    }
+
+    public ResolvedJavaMethod getMethod() {
+        return (ResolvedJavaMethod) getObject(METHOD_FRAME_SLOT);
+    }
+
+    public void setBCI(int bci) {
+        setInt(BCI_FRAME_SLOT, bci);
+    }
+
+    public int getBCI() {
+        return getInt(BCI_FRAME_SLOT);
+    }
+
+    public void pushTo(InterpreterFrame childFrame, int argumentSlots) {
+        System.arraycopy(locals, tos - argumentSlots, childFrame.locals,
+                        InterpreterFrame.MIN_FRAME_SIZE, argumentSlots);
+
+        System.arraycopy(primitiveLocals, tos - argumentSlots, childFrame.primitiveLocals,
+                        InterpreterFrame.MIN_FRAME_SIZE, argumentSlots);
+        popVoid(argumentSlots);
+    }
+
+    public InterpreterFrame getParentFrame() {
+        return (InterpreterFrame) getObject(PARENT_FRAME_SLOT);
+    }
+
+    public void dispose() {
+        // Clear out references in locals array.
+        Arrays.fill(locals, null);
+    }
+
+    @Override
+    public String toString() {
+        ResolvedJavaMethod method = getMethod();
+        StringBuilder b = new StringBuilder(getMethod().toStackTraceElement(getBCI()).toString());
+        for (int i = 0; i < tos; i++) {
+            Object object = getObject(tosSingle(i));
+            long primitive = getLong(tosSingle(i));
+
+            String objectString = null;
+            if (object != null) {
+                objectString = object.getClass().getSimpleName() + "@" + Integer.toHexString(object.hashCode());
+            }
+            String primitiveString = "0x" + Long.toHexString(primitive).toUpperCase();
+            String typeString;
+
+            int index = tosSingle(i);
+            if (index == METHOD_FRAME_SLOT) {
+                typeString = "method";
+            } else if (index == BCI_FRAME_SLOT) {
+                typeString = "bci";
+            } else if (index == PARENT_FRAME_SLOT) {
+                typeString = "parent";
+            } else if (index < BASE_LENGTH + method.maxLocals()) {
+                typeString = "var " + (index - BASE_LENGTH);
+            } else {
+                typeString = "local";
+            }
+            b.append(String.format("%n [%d] %7s Primitive: %10s Object: %s", index, typeString, primitiveString, objectString));
+        }
+        if (getParentFrame() != null) {
+            b.append("\n").append(getParentFrame().toString());
+        }
+        return b.toString();
+    }
+
+    public void popStack() {
+        // TODO(chumer): prevent popping local variables.
+        popVoid(tos - stackTos());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/VMAdapter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,313 @@
+/*
+ * 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.interpreter;
+
+import java.lang.reflect.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.meta.*;
+
+
+/**
+ * This class encapsulates all vm specific methods for the {@link BytecodeInterpreter}.
+ */
+public class VMAdapter {
+
+    private static final Unsafe unsafe = loadUnsafe();
+
+    protected VMAdapter() {
+    }
+
+    public MetaAccessProvider getRuntime() {
+        return Graal.getRuntime().getCapability(MetaAccessProvider.class);
+    }
+
+    public void monitorEnter(Object value) {
+        nullCheck(value);
+        unsafe.monitorEnter(value);
+    }
+
+    public void monitorExit(Object value) {
+        nullCheck(value);
+        unsafe.monitorExit(value);
+    }
+
+    public Object newObject(ResolvedJavaType type) throws InstantiationException {
+        return unsafe.allocateInstance(type.toJava());
+    }
+
+    public Object getField(Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            return unsafe.getObjectVolatile(resolveBase(base, field), offset);
+        } else {
+            return unsafe.getObject(resolveBase(base, field), offset);
+        }
+    }
+
+    public int getFieldInt(Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            return unsafe.getIntVolatile(resolveBase(base, field), offset);
+        } else {
+            return unsafe.getInt(resolveBase(base, field), offset);
+        }
+    }
+
+    public long getFieldLong(Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            return unsafe.getLongVolatile(resolveBase(base, field), offset);
+        } else {
+            return unsafe.getLong(resolveBase(base, field), offset);
+        }
+    }
+
+    public double getFieldDouble(Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            return unsafe.getDoubleVolatile(resolveBase(base, field), offset);
+        } else {
+            return unsafe.getDouble(resolveBase(base, field), offset);
+        }
+    }
+
+    public float getFieldFloat(Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            return unsafe.getFloatVolatile(resolveBase(base, field), offset);
+        } else {
+            return unsafe.getFloat(resolveBase(base, field), offset);
+        }
+    }
+
+    public void setField(Object value, Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            unsafe.putObjectVolatile(resolveBase(base, field), offset, value);
+        } else {
+            unsafe.putObject(resolveBase(base, field), offset, value);
+        }
+    }
+
+    public void setFieldInt(int value, Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            unsafe.putIntVolatile(resolveBase(base, field), offset, value);
+        } else {
+            unsafe.putInt(resolveBase(base, field), offset, value);
+        }
+    }
+
+
+    public void setFieldFloat(float value, Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            unsafe.putFloatVolatile(resolveBase(base, field), offset, value);
+        } else {
+            unsafe.putFloat(resolveBase(base, field), offset, value);
+        }
+    }
+
+    public void setFieldDouble(double value, Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            unsafe.putDoubleVolatile(resolveBase(base, field), offset, value);
+        } else {
+            unsafe.putDouble(resolveBase(base, field), offset, value);
+        }
+    }
+
+    public void setFieldLong(long value, Object base, ResolvedJavaField field) {
+        long offset = resolveOffset(field);
+        if (isVolatile(field)) {
+            unsafe.putDoubleVolatile(resolveBase(base, field), offset, value);
+        } else {
+            unsafe.putDouble(resolveBase(base, field), offset, value);
+        }
+    }
+
+    public byte getArrayByte(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getByte(array, Unsafe.ARRAY_BYTE_BASE_OFFSET + Unsafe.ARRAY_BYTE_INDEX_SCALE * index);
+    }
+
+    public char getArrayChar(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getChar(array, Unsafe.ARRAY_CHAR_BASE_OFFSET + Unsafe.ARRAY_CHAR_INDEX_SCALE * index);
+    }
+
+    public short getArrayShort(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getShort(array, Unsafe.ARRAY_SHORT_BASE_OFFSET + Unsafe.ARRAY_SHORT_INDEX_SCALE * index);
+    }
+
+    public int getArrayInt(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getInt(array, Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * index);
+    }
+
+    public long getArrayLong(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getLong(array, Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * index);
+    }
+
+    public double getArrayDouble(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getDouble(array, Unsafe.ARRAY_DOUBLE_BASE_OFFSET + Unsafe.ARRAY_DOUBLE_INDEX_SCALE * index);
+    }
+
+    public float getArrayFloat(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getFloat(array, Unsafe.ARRAY_FLOAT_BASE_OFFSET + Unsafe.ARRAY_FLOAT_INDEX_SCALE * index);
+    }
+
+    public Object getArrayObject(long index, Object array) {
+        checkArray(array, index);
+        return unsafe.getObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * index);
+    }
+
+    public void setArrayByte(byte value, long index, Object array) {
+        checkArray(array, index);
+        if (array instanceof boolean[]) {
+            checkArrayType(array, boolean.class);
+        } else {
+            checkArrayType(array, byte.class);
+        }
+        unsafe.putByte(array, Unsafe.ARRAY_BYTE_BASE_OFFSET + Unsafe.ARRAY_BYTE_INDEX_SCALE * index, value);
+    }
+
+    public void setArrayChar(char value, long index, Object array) {
+        checkArray(array, index);
+        checkArrayType(array, char.class);
+        unsafe.putChar(array, Unsafe.ARRAY_CHAR_BASE_OFFSET + Unsafe.ARRAY_CHAR_INDEX_SCALE * index, value);
+    }
+
+    public void setArrayShort(short value, long index, Object array) {
+        checkArray(array, index);
+        checkArrayType(array, short.class);
+        unsafe.putShort(array, Unsafe.ARRAY_SHORT_BASE_OFFSET + Unsafe.ARRAY_SHORT_INDEX_SCALE * index, value);
+    }
+
+    public void setArrayInt(int value, long index, Object array) {
+        checkArray(array, index);
+        checkArrayType(array, int.class);
+        unsafe.putInt(array, Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * index, value);
+    }
+
+    public void setArrayLong(long value, long index, Object array) {
+        checkArray(array, index);
+        checkArrayType(array, long.class);
+        unsafe.putLong(array, Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * index, value);
+    }
+
+    public void setArrayFloat(float value, long index, Object array) {
+        checkArray(array, index);
+        checkArrayType(array, float.class);
+        unsafe.putFloat(array, Unsafe.ARRAY_FLOAT_BASE_OFFSET + Unsafe.ARRAY_FLOAT_INDEX_SCALE * index, value);
+    }
+
+    public void setArrayDouble(double value, long index, Object array) {
+        checkArray(array, index);
+        checkArrayType(array, double.class);
+        unsafe.putDouble(array, Unsafe.ARRAY_DOUBLE_BASE_OFFSET + Unsafe.ARRAY_DOUBLE_INDEX_SCALE * index, value);
+    }
+
+    public void setArrayObject(Object value, long index, Object array) {
+        checkArray(array, index);
+        checkArrayType(array, value != null ? value.getClass() : null);
+        unsafe.putObject(array, Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * index, value);
+    }
+
+    private static void nullCheck(Object value) {
+        if (value == null) {
+            throw new NullPointerException();
+        }
+    }
+
+    private void checkArrayType(Object array, Class<?> arrayType) {
+        if (arrayType == null) {
+            return;
+        }
+        ResolvedJavaType type = getRuntime().getResolvedJavaType(array.getClass()).componentType();
+        if (!type.toJava().isAssignableFrom(arrayType)) {
+            throw new ArrayStoreException(arrayType.getName());
+        }
+    }
+
+    private void checkArray(Object array, long index) {
+        nullCheck(array);
+        ResolvedJavaType type = getRuntime().getResolvedJavaType(array.getClass());
+        if (!type.isArrayClass()) {
+            throw new ArrayStoreException(array.getClass().getName());
+        }
+        if (index < 0 || index >= arrayLength(array)) {
+            throw new ArrayIndexOutOfBoundsException((int) index);
+        }
+    }
+
+    private static int arrayLength(Object array) {
+        assert array != null;
+        return Array.getLength(array);
+    }
+
+    private static boolean isVolatile(ResolvedJavaField field) {
+        return Modifier.isVolatile(field.accessFlags());
+    }
+
+    private static long resolveOffset(ResolvedJavaField field) {
+        return ((HotSpotResolvedJavaField) field).offset();
+    }
+
+    private static Object resolveBase(Object base, ResolvedJavaField field) {
+        Object accessorBase = base;
+        if (accessorBase == null) {
+            accessorBase = field.holder().toJava();
+        }
+        return accessorBase;
+    }
+
+    private static Unsafe loadUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+
+    private static final VMAdapter instance = new VMAdapter();
+    public static VMAdapter getInstance() {
+        return instance;
+    }
+
+
+}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,17 +22,16 @@
  */
 package com.oracle.graal.java;
 
-import static com.oracle.graal.java.bytecode.Bytecodes.*;
+import static com.oracle.graal.bytecode.Bytecodes.*;
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.bytecode.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.java.bytecode.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 
 /**
  * Builds a mapping between bytecodes and basic blocks and builds a conservative control flow graph (CFG).
@@ -91,10 +90,10 @@
         public Block retSuccessor;
         public boolean endsWithRet = false;
 
-        public BitMap localsLiveIn;
-        public BitMap localsLiveOut;
-        private BitMap localsLiveGen;
-        private BitMap localsLiveKill;
+        public BitSet localsLiveIn;
+        public BitSet localsLiveOut;
+        private BitSet localsLiveGen;
+        private BitSet localsLiveKill;
 
         public Block exceptionDispatchBlock() {
             if (successors.size() > 0 && successors.get(successors.size() - 1) instanceof ExceptionDispatchBlock) {
@@ -139,9 +138,9 @@
     }
 
     public static class ExceptionDispatchBlock extends Block {
-        private HashMap<RiExceptionHandler, ExceptionDispatchBlock> exceptionDispatch = new HashMap<>();
+        private HashMap<ExceptionHandler, ExceptionDispatchBlock> exceptionDispatch = new HashMap<>();
 
-        public RiExceptionHandler handler;
+        public ExceptionHandler handler;
         public int deoptBci;
     }
 
@@ -149,12 +148,12 @@
      * The blocks found in this method, in reverse postorder.
      */
     public final List<Block> blocks;
-    public final RiResolvedMethod method;
+    public final ResolvedJavaMethod method;
     public boolean hasJsrBytecodes;
     public Block startBlock;
 
     private final BytecodeStream stream;
-    private final RiExceptionHandler[] exceptionHandlers;
+    private final ExceptionHandler[] exceptionHandlers;
     private Block[] blockMap;
     public Block[] loopHeaders;
 
@@ -162,7 +161,7 @@
      * Creates a new BlockMap instance from bytecode of the given method .
      * @param method the compiler interface method containing the code
      */
-    public BciBlockMapping(RiResolvedMethod method) {
+    public BciBlockMapping(ResolvedJavaMethod method) {
         this.method = method;
         exceptionHandlers = method.exceptionHandlers();
         stream = new BytecodeStream(method.code());
@@ -233,7 +232,7 @@
 
     private void makeExceptionEntries() {
         // start basic blocks at all exception handler blocks and mark them as exception entries
-        for (RiExceptionHandler h : this.exceptionHandlers) {
+        for (ExceptionHandler h : this.exceptionHandlers) {
             Block xhandler = makeBlock(h.handlerBCI());
             xhandler.isExceptionEntry = true;
         }
@@ -405,16 +404,21 @@
     }
 
     private void addSwitchSuccessors(int predBci, BytecodeSwitch bswitch) {
+        // adds distinct targets to the successor list
+        Collection<Integer> targets = new TreeSet<>();
         for (int i = 0; i < bswitch.numberOfCases(); i++) {
-            addSuccessor(predBci, makeBlock(bswitch.targetAt(i)));
+            targets.add(bswitch.targetAt(i));
         }
-        addSuccessor(predBci, makeBlock(bswitch.defaultTarget()));
+        targets.add(bswitch.defaultTarget());
+        for (int targetBci : targets) {
+            addSuccessor(predBci, makeBlock(targetBci));
+        }
     }
 
     private void addSuccessor(int predBci, Block sux) {
         Block predecessor = blockMap[predBci];
         if (sux.isExceptionEntry) {
-            throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow");
+            throw new BailoutException("Exception handler can be reached by both normal and exceptional control flow");
         }
         predecessor.successors.add(sux);
     }
@@ -475,20 +479,20 @@
     }
 
 
-    private HashMap<RiExceptionHandler, ExceptionDispatchBlock> initialExceptionDispatch = new HashMap<>();
+    private HashMap<ExceptionHandler, ExceptionDispatchBlock> initialExceptionDispatch = new HashMap<>();
 
     private ExceptionDispatchBlock handleExceptions(int bci) {
         ExceptionDispatchBlock lastHandler = null;
 
         for (int i = exceptionHandlers.length - 1; i >= 0; i--) {
-            RiExceptionHandler h = exceptionHandlers[i];
+            ExceptionHandler h = exceptionHandlers[i];
             if (h.startBCI() <= bci && bci < h.endBCI()) {
                 if (h.isCatchAll()) {
                     // Discard all information about succeeding exception handlers, since they can never be reached.
                     lastHandler = null;
                 }
 
-                HashMap<RiExceptionHandler, ExceptionDispatchBlock> exceptionDispatch = lastHandler != null ? lastHandler.exceptionDispatch : initialExceptionDispatch;
+                HashMap<ExceptionHandler, ExceptionDispatchBlock> exceptionDispatch = lastHandler != null ? lastHandler.exceptionDispatch : initialExceptionDispatch;
                 ExceptionDispatchBlock curHandler = exceptionDispatch.get(h);
                 if (curHandler == null) {
                     curHandler = new ExceptionDispatchBlock();
@@ -523,7 +527,7 @@
                 // There is a path from a loop end to the method entry that does not pass the loop header.
                 // Therefore, the loop is non reducible (has more than one entry).
                 // We don't want to compile such methods because the IR only supports structured loops.
-                throw new CiBailout("Non-reducible loop");
+                throw new BailoutException("Non-reducible loop");
             }
         } while (loopChanges);
     }
@@ -535,7 +539,7 @@
             // There is a path from a loop end to the method entry that does not pass the loop header.
             // Therefore, the loop is non reducible (has more than one entry).
             // We don't want to compile such methods because the IR only supports structured loops.
-            throw new CiBailout("Non-reducible loop");
+            throw new BailoutException("Non-reducible loop");
         }
 
         // Convert postorder to the desired reverse postorder.
@@ -616,12 +620,12 @@
             if (block.isExceptionEntry) {
                 // Loops that are implicitly formed by an exception handler lead to all sorts of corner cases.
                 // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
-                throw new CiBailout("Loop formed by an exception handler");
+                throw new BailoutException("Loop formed by an exception handler");
             }
             if (nextLoop >= Long.SIZE) {
                 // This restriction can be removed by using a fall-back to a BitSet in case we have more than 64 loops
                 // Don't compile such methods for now, until we see a concrete case that allows checking for correctness.
-                throw new CiBailout("Too many loops in method");
+                throw new BailoutException("Too many loops in method");
             }
 
             assert block.loops == 0;
@@ -722,15 +726,20 @@
                 Debug.log("  start B%d  [%d, %d]  in: %s  out: %s  gen: %s  kill: %s", block.blockID, block.startBci, block.endBci, block.localsLiveIn, block.localsLiveOut, block.localsLiveGen, block.localsLiveKill);
 
                 boolean blockChanged = (iteration == 0);
-                for (Block sux : block.successors) {
-                    Debug.log("    Successor B%d: %s", sux.blockID, sux.localsLiveIn);
-                    blockChanged = block.localsLiveOut.setUnionWithResult(sux.localsLiveIn) || blockChanged;
+                if (block.successors.size() > 0) {
+                    int oldCardinality = block.localsLiveOut.cardinality();
+                    for (Block sux : block.successors) {
+                        Debug.log("    Successor B%d: %s", sux.blockID, sux.localsLiveIn);
+                        block.localsLiveOut.or(sux.localsLiveIn);
+                    }
+                    blockChanged |= (oldCardinality != block.localsLiveOut.cardinality());
                 }
 
                 if (blockChanged) {
-                    block.localsLiveIn.setFrom(block.localsLiveOut);
-                    block.localsLiveIn.setDifference(block.localsLiveKill);
-                    block.localsLiveIn.setUnion(block.localsLiveGen);
+                    block.localsLiveIn.clear();
+                    block.localsLiveIn.or(block.localsLiveOut);
+                    block.localsLiveIn.xor(block.localsLiveKill);
+                    block.localsLiveIn.or(block.localsLiveGen);
                     Debug.log("  end   B%d  [%d, %d]  in: %s  out: %s  gen: %s  kill: %s", block.blockID, block.startBci, block.endBci, block.localsLiveIn, block.localsLiveOut, block.localsLiveGen, block.localsLiveKill);
                 }
                 changed |= blockChanged;
@@ -740,10 +749,10 @@
     }
 
     private void computeLocalLiveness(Block block) {
-        block.localsLiveIn = new BitMap(method.maxLocals());
-        block.localsLiveOut = new BitMap(method.maxLocals());
-        block.localsLiveGen = new BitMap(method.maxLocals());
-        block.localsLiveKill = new BitMap(method.maxLocals());
+        block.localsLiveIn = new BitSet(method.maxLocals());
+        block.localsLiveOut = new BitSet(method.maxLocals());
+        block.localsLiveGen = new BitSet(method.maxLocals());
+        block.localsLiveKill = new BitSet(method.maxLocals());
 
         if (block.startBci < 0 || block.endBci < 0) {
             return;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,22 +23,21 @@
 package com.oracle.graal.java;
 
 import static com.oracle.graal.graph.iterators.NodePredicates.*;
-import static com.oracle.graal.nodes.ValueUtil.*;
+import static com.oracle.graal.nodes.ValueNodeUtil.*;
 import static java.lang.reflect.Modifier.*;
 
 import java.util.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 
 public class FrameStateBuilder {
-    private final RiResolvedMethod method;
+    private final ResolvedJavaMethod method;
     private final StructuredGraph graph;
 
     private final ValueNode[] locals;
@@ -46,7 +45,7 @@
     private int stackSize;
     private boolean rethrowException;
 
-    public FrameStateBuilder(RiResolvedMethod method, StructuredGraph graph, boolean eagerResolve) {
+    public FrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, boolean eagerResolve) {
         assert graph != null;
         this.method = method;
         this.graph = graph;
@@ -63,19 +62,18 @@
             javaIndex = 1;
             index = 1;
         }
-        RiSignature sig = method.signature();
+        Signature sig = method.signature();
         int max = sig.argumentCount(false);
-        RiResolvedType accessingClass = method.holder();
+        ResolvedJavaType accessingClass = method.holder();
         for (int i = 0; i < max; i++) {
-            RiType type = sig.argumentTypeAt(i, accessingClass);
+            JavaType type = sig.argumentTypeAt(i, accessingClass);
             if (eagerResolve) {
                 type = type.resolve(accessingClass);
             }
-            CiKind kind = type.kind(false).stackKind();
+            Kind kind = type.kind().stackKind();
             Stamp stamp;
-            if (kind == CiKind.Object && type instanceof RiResolvedType) {
-                RiResolvedType resolvedType = (RiResolvedType) type;
-                stamp = StampFactory.declared(resolvedType);
+            if (kind == Kind.Object && type instanceof ResolvedJavaType) {
+                stamp = StampFactory.declared((ResolvedJavaType) type);
             } else {
                 stamp = StampFactory.forKind(kind);
             }
@@ -86,7 +84,7 @@
         }
     }
 
-    private FrameStateBuilder(RiResolvedMethod method, StructuredGraph graph, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException) {
+    private FrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException) {
         assert locals.length == method.maxLocals();
         assert stack.length == Math.max(1, method.maxStackSize());
 
@@ -118,7 +116,7 @@
     }
 
     public FrameState create(int bci) {
-        return graph.add(new FrameState(method, bci, locals, stack, stackSize, rethrowException, false));
+        return graph.add(new FrameState(method, bci, locals, stack, stackSize, rethrowException, false, null));
     }
 
     public FrameStateBuilder copy() {
@@ -134,7 +132,7 @@
         for (int i = 0; i < stackSize(); i++) {
             ValueNode x = stackAt(i);
             ValueNode y = other.stackAt(i);
-            if (x != y && ValueUtil.typeMismatch(x, y)) {
+            if (x != y && ValueNodeUtil.typeMismatch(x, y)) {
                 return false;
             }
         }
@@ -158,7 +156,7 @@
 
         } else if (block.isPhiAtMerge(currentValue)) {
             if (otherValue == null || currentValue.kind() != otherValue.kind()) {
-                deletePhi((PhiNode) currentValue);
+                propagateDelete((PhiNode) currentValue);
                 return null;
             }
             ((PhiNode) currentValue).addInput(otherValue);
@@ -170,7 +168,7 @@
                 return null;
             }
 
-            PhiNode phi = graph.unique(new PhiNode(currentValue.kind(), block, PhiType.Value));
+            PhiNode phi = graph.unique(new PhiNode(currentValue.kind(), block));
             for (int i = 0; i < block.phiPredecessorCount(); i++) {
                 phi.addInput(currentValue);
             }
@@ -183,45 +181,21 @@
         }
     }
 
-    private void deletePhi(PhiNode phi) {
-        if (phi.isDeleted()) {
+    private void propagateDelete(FloatingNode node) {
+        assert node instanceof PhiNode || node instanceof ValueProxyNode;
+        if (node.isDeleted()) {
             return;
         }
         // Collect all phi functions that use this phi so that we can delete them recursively (after we delete ourselfs to avoid circles).
-        List<PhiNode> phiUsages = phi.usages().filter(PhiNode.class).snapshot();
-        List<ValueProxyNode> vpnUsages = phi.usages().filter(ValueProxyNode.class).snapshot();
+        List<FloatingNode> propagateUsages = node.usages().filter(FloatingNode.class).filter(isA(PhiNode.class).or(ValueProxyNode.class)).snapshot();
 
         // Remove the phi function from all FrameStates where it is used and then delete it.
-        assert phi.usages().filter(isNotA(FrameState.class).nor(PhiNode.class).nor(ValueProxyNode.class)).isEmpty() : "phi function that gets deletes must only be used in frame states";
-        phi.replaceAtUsages(null);
-        phi.safeDelete();
-
-        for (PhiNode phiUsage : phiUsages) {
-            deletePhi(phiUsage);
-        }
-        for (ValueProxyNode proxyUsage : vpnUsages) {
-            deleteProxy(proxyUsage);
-        }
-    }
+        assert node.usages().filter(isNotA(FrameState.class).nor(PhiNode.class).nor(ValueProxyNode.class)).isEmpty() : "phi function that gets deletes must only be used in frame states";
+        node.replaceAtUsages(null);
+        node.safeDelete();
 
-    private void deleteProxy(ValueProxyNode proxy) {
-        if (proxy.isDeleted()) {
-            return;
-        }
-        // Collect all phi functions that use this phi so that we can delete them recursively (after we delete ourselfs to avoid circles).
-        List<PhiNode> phiUsages = proxy.usages().filter(PhiNode.class).snapshot();
-        List<ValueProxyNode> vpnUsages = proxy.usages().filter(ValueProxyNode.class).snapshot();
-
-        // Remove the proxy function from all FrameStates where it is used and then delete it.
-        assert proxy.usages().filter(isNotA(FrameState.class).nor(PhiNode.class).nor(ValueProxyNode.class)).isEmpty() : "phi function that gets deletes must only be used in frame states";
-        proxy.replaceAtUsages(null);
-        proxy.safeDelete();
-
-        for (PhiNode phiUsage : phiUsages) {
-            deletePhi(phiUsage);
-        }
-        for (ValueProxyNode proxyUsage : vpnUsages) {
-            deleteProxy(proxyUsage);
+        for (FloatingNode phiUsage : propagateUsages) {
+            propagateDelete(phiUsage);
         }
     }
 
@@ -257,7 +231,7 @@
         }
         assert !block.isPhiAtMerge(value) : "phi function for this block already created";
 
-        PhiNode phi = graph.unique(new PhiNode(value.kind(), block, PhiType.Value));
+        PhiNode phi = graph.unique(new PhiNode(value.kind(), block));
         phi.addInput(value);
         return phi;
     }
@@ -265,17 +239,16 @@
     public void cleanupDeletedPhis() {
         for (int i = 0; i < localsSize(); i++) {
             if (localAt(i) != null && localAt(i).isDeleted()) {
-                assert localAt(i) instanceof PhiNode : "Only phi functions can be deleted during parsing";
+                assert localAt(i) instanceof PhiNode || localAt(i) instanceof ValueProxyNode : "Only phi and value proxies can be deleted during parsing: " + localAt(i);
                 storeLocal(i, null);
             }
         }
     }
 
-    public void clearNonLiveLocals(BitMap liveness) {
+    public void clearNonLiveLocals(BitSet liveness) {
         if (liveness == null) {
             return;
         }
-        assert liveness.size() == locals.length;
         for (int i = 0; i < locals.length; i++) {
             if (!liveness.get(i)) {
                 locals[i] = null;
@@ -344,14 +317,14 @@
     }
 
     /**
-     * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word},
+     * Stores a given local variable at the specified index. If the value is a {@linkplain Kind#isDoubleWord() double word},
      * then the next local variable index is also overwritten.
      *
      * @param i the index at which to store
      * @param x the instruction which produces the value for the local
      */
     public void storeLocal(int i, ValueNode x) {
-        assert x == null || x.kind() != CiKind.Void && x.kind() != CiKind.Illegal : "unexpected value: " + x;
+        assert x == null || x.kind() != Kind.Void && x.kind() != Kind.Illegal : "unexpected value: " + x;
         locals[i] = x;
         if (x != null && isTwoSlot(x.kind())) {
             // if this is a double word, then kill i+1
@@ -376,8 +349,8 @@
      * @param kind the type expected for this instruction
      * @param x the instruction to push onto the stack
      */
-    public void push(CiKind kind, ValueNode x) {
-        assert !x.isDeleted() && x.kind() != CiKind.Void && x.kind() != CiKind.Illegal;
+    public void push(Kind kind, ValueNode x) {
+        assert !x.isDeleted() && x.kind() != Kind.Void && x.kind() != Kind.Illegal;
         xpush(assertKind(kind, x));
         if (isTwoSlot(kind)) {
             xpush(null);
@@ -389,7 +362,7 @@
      * @param x the instruction to push onto the stack
      */
     public void xpush(ValueNode x) {
-        assert x == null || (!x.isDeleted() && x.kind() != CiKind.Void && x.kind() != CiKind.Illegal);
+        assert x == null || (!x.isDeleted() && x.kind() != Kind.Void && x.kind() != Kind.Illegal);
         stack[stackSize++] = x;
     }
 
@@ -444,8 +417,8 @@
         xpush(null);
     }
 
-    public void pushReturn(CiKind kind, ValueNode x) {
-        if (kind != CiKind.Void) {
+    public void pushReturn(Kind kind, ValueNode x) {
+        if (kind != Kind.Void) {
             push(kind.stackKind(), x);
         }
     }
@@ -455,8 +428,8 @@
      * @param kind the expected type
      * @return the instruction on the top of the stack
      */
-    public ValueNode pop(CiKind kind) {
-        assert kind != CiKind.Void;
+    public ValueNode pop(Kind kind) {
+        assert kind != Kind.Void;
         if (isTwoSlot(kind)) {
             xpop();
         }
@@ -568,13 +541,13 @@
         stackSize = 0;
     }
 
-    public static int stackSlots(CiKind kind) {
+    public static int stackSlots(Kind kind) {
         return isTwoSlot(kind) ? 2 : 1;
     }
 
-    public static boolean isTwoSlot(CiKind kind) {
-        assert kind != CiKind.Void && kind != CiKind.Illegal;
-        return kind == CiKind.Long || kind == CiKind.Double;
+    public static boolean isTwoSlot(Kind kind) {
+        assert kind != Kind.Void && kind != Kind.Illegal;
+        return kind == Kind.Long || kind == Kind.Double;
     }
 
     public boolean contains(ValueNode value) {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderConfiguration.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.java;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.phases.*;
-import com.oracle.max.cri.ri.*;
 
 public class GraphBuilderConfiguration {
 
@@ -33,18 +33,18 @@
 
     private final ResolvePolicy resolving;
     private final PhasePlan plan;
-    private RiResolvedType[] skippedExceptionTypes;
+    private ResolvedJavaType[] skippedExceptionTypes;
 
     public GraphBuilderConfiguration(ResolvePolicy resolving, PhasePlan plan) {
         this.resolving = resolving;
         this.plan = plan;
     }
 
-    public void setSkippedExceptionTypes(RiResolvedType[] skippedExceptionTypes) {
+    public void setSkippedExceptionTypes(ResolvedJavaType[] skippedExceptionTypes) {
         this.skippedExceptionTypes = skippedExceptionTypes;
     }
 
-    public RiResolvedType[] getSkippedExceptionTypes() {
+    public ResolvedJavaType[] getSkippedExceptionTypes() {
         return skippedExceptionTypes;
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,17 @@
  */
 package com.oracle.graal.java;
 
-import static com.oracle.graal.java.bytecode.Bytecodes.*;
+import static com.oracle.graal.bytecode.Bytecodes.*;
 import static java.lang.reflect.Modifier.*;
 
 import java.lang.reflect.*;
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
+import com.oracle.graal.api.meta.JavaTypeProfile.*;
+import com.oracle.graal.bytecode.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.compiler.util.*;
@@ -35,7 +40,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.java.BciBlockMapping.Block;
 import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock;
-import com.oracle.graal.java.bytecode.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
@@ -43,9 +47,6 @@
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.Representation;
 import com.oracle.max.criutils.*;
 
 /**
@@ -67,10 +68,10 @@
 
     private StructuredGraph currentGraph;
 
-    private final RiRuntime runtime;
-    private RiConstantPool constantPool;
-    private RiResolvedMethod method;
-    private RiProfilingInfo profilingInfo;
+    private final MetaAccessProvider runtime;
+    private ConstantPool constantPool;
+    private ResolvedJavaMethod method;
+    private ProfilingInfo profilingInfo;
 
     private BytecodeStream stream;           // the bytecode stream
     private final LogStream log;
@@ -97,17 +98,18 @@
      */
     private static class BlockPlaceholderNode extends FixedWithNextNode implements Node.IterableNodeType {
         public BlockPlaceholderNode() {
-            super(StampFactory.illegal());
+            super(StampFactory.forVoid());
         }
     }
 
     private Block[] loopHeaders;
 
-    public GraphBuilderPhase(RiRuntime runtime, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
+    public GraphBuilderPhase(MetaAccessProvider runtime, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
         this.graphBuilderConfig = graphBuilderConfig;
         this.optimisticOpts = optimisticOpts;
         this.runtime = runtime;
         this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
+        assert runtime != null;
     }
 
     @Override
@@ -128,13 +130,13 @@
 
     @Override
     protected String getDetailedName() {
-        return getName() + " " + CiUtil.format("%H.%n(%p):%r", method);
+        return getName() + " " + CodeUtil.format("%H.%n(%p):%r", method);
     }
 
     private BciBlockMapping createBlockMap() {
         BciBlockMapping map = new BciBlockMapping(method);
         map.build();
-        Debug.dump(map, CiUtil.format("After block building %f %R %H.%n(%P)", method));
+        Debug.dump(map, CodeUtil.format("After block building %f %R %H.%n(%P)", method));
 
         return map;
     }
@@ -146,7 +148,8 @@
         }
 
         if (GraalOptions.PrintProfilingInformation) {
-            method.dumpProfile();
+            TTY.println("Profiling info for " + method);
+            TTY.println(CodeUtil.indent(CodeUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), "  "));
         }
 
         // compute the block map, setup exception handlers and get the entrypoint(s)
@@ -163,7 +166,7 @@
         frameState.clearNonLiveLocals(blockMap.startBlock.localsLiveIn);
 
         // finish the start block
-        ((AbstractStateSplit) lastInstr).setStateAfter(frameState.create(0));
+        ((StateSplit) lastInstr).setStateAfter(frameState.create(0));
         if (blockMap.startBlock.isLoopHeader) {
             appendGoto(createTarget(blockMap.startBlock, frameState));
         } else {
@@ -223,23 +226,23 @@
         return stream.currentBCI();
     }
 
-    private void loadLocal(int index, CiKind kind) {
+    private void loadLocal(int index, Kind kind) {
         frameState.push(kind, frameState.loadLocal(index));
     }
 
-    private void storeLocal(CiKind kind, int index) {
+    private void storeLocal(Kind kind, int index) {
         frameState.storeLocal(index, frameState.pop(kind));
     }
 
-    public static boolean covers(RiExceptionHandler handler, int bci) {
+    public static boolean covers(ExceptionHandler handler, int bci) {
         return handler.startBCI() <= bci && bci < handler.endBCI();
     }
 
-    public static boolean isCatchAll(RiExceptionHandler handler) {
+    public static boolean isCatchAll(ExceptionHandler handler) {
         return handler.catchTypeCPI() == 0;
     }
 
-    private BeginNode handleException(ValueNode exceptionObject, int bci) {
+    private DispatchBeginNode handleException(ValueNode exceptionObject, int bci) {
         assert bci == FrameState.BEFORE_BCI || bci == bci() : "invalid bci";
         Debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, profilingInfo.getExceptionSeen(bci));
 
@@ -253,11 +256,11 @@
         FrameStateBuilder dispatchState = frameState.copy();
         dispatchState.clearStack();
 
-        BeginNode dispatchBegin = currentGraph.add(new BeginNode());
+        DispatchBeginNode dispatchBegin = currentGraph.add(new DispatchBeginNode());
         dispatchBegin.setStateAfter(dispatchState.create(bci));
 
         if (exceptionObject == null) {
-            ExceptionObjectNode newExceptionObject = currentGraph.add(new ExceptionObjectNode());
+            ExceptionObjectNode newExceptionObject = currentGraph.add(new ExceptionObjectNode(runtime));
             dispatchState.apush(newExceptionObject);
             dispatchState.setRethrowException(true);
             newExceptionObject.setStateAfter(dispatchState.create(bci));
@@ -278,41 +281,39 @@
     private void genLoadConstant(int cpi, int opcode) {
         Object con = lookupConstant(cpi, opcode);
 
-        if (con instanceof RiType) {
+        if (con instanceof JavaType) {
             // this is a load of class constant which might be unresolved
-            RiType riType = (RiType) con;
-            if (riType instanceof RiResolvedType) {
-                frameState.push(CiKind.Object, append(ConstantNode.forCiConstant(((RiResolvedType) riType).getEncoding(Representation.JavaClass), runtime, currentGraph)));
+            JavaType riType = (JavaType) con;
+            if (riType instanceof ResolvedJavaType) {
+                frameState.push(Kind.Object, append(ConstantNode.forConstant(((ResolvedJavaType) riType).getEncoding(Representation.JavaClass), runtime, currentGraph)));
             } else {
-                append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
-                frameState.push(CiKind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
+                append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+                frameState.push(Kind.Object, append(ConstantNode.forObject(null, runtime, currentGraph)));
             }
-        } else if (con instanceof CiConstant) {
-            CiConstant constant = (CiConstant) con;
+        } else if (con instanceof Constant) {
+            Constant constant = (Constant) con;
             frameState.push(constant.kind.stackKind(), appendConstant(constant));
         } else {
             throw new Error("lookupConstant returned an object of incorrect type");
         }
     }
 
-    private void genLoadIndexed(CiKind kind) {
+    private void genLoadIndexed(Kind kind) {
         emitExplicitExceptions(frameState.peek(1), frameState.peek(0));
 
         ValueNode index = frameState.ipop();
         ValueNode array = frameState.apop();
-        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
-        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, length, kind, graphId)));
+        ValueNode v = append(currentGraph.add(new LoadIndexedNode(array, index, kind, graphId)));
         frameState.push(kind.stackKind(), v);
     }
 
-    private void genStoreIndexed(CiKind kind) {
+    private void genStoreIndexed(Kind kind) {
         emitExplicitExceptions(frameState.peek(2), frameState.peek(1));
 
         ValueNode value = frameState.pop(kind.stackKind());
         ValueNode index = frameState.ipop();
         ValueNode array = frameState.apop();
-        ValueNode length = append(currentGraph.add(new ArrayLengthNode(array)));
-        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, length, kind, value, graphId));
+        StoreIndexedNode result = currentGraph.add(new StoreIndexedNode(array, index, kind, value, graphId));
         append(result);
     }
 
@@ -397,7 +398,7 @@
 
     }
 
-    private void genArithmeticOp(CiKind result, int opcode, boolean canTrap) {
+    private void genArithmeticOp(Kind result, int opcode, boolean canTrap) {
         ValueNode y = frameState.pop(result);
         ValueNode x = frameState.pop(result);
         boolean isStrictFP = isStrict(method.accessFlags());
@@ -433,11 +434,11 @@
         frameState.push(result, result1);
     }
 
-    private void genNegateOp(CiKind kind) {
+    private void genNegateOp(Kind kind) {
         frameState.push(kind, append(currentGraph.unique(new NegateNode(frameState.pop(kind)))));
     }
 
-    private void genShiftOp(CiKind kind, int opcode) {
+    private void genShiftOp(Kind kind, int opcode) {
         ValueNode s = frameState.ipop();
         ValueNode x = frameState.pop(kind);
         ShiftNode v;
@@ -454,7 +455,7 @@
         frameState.push(kind, append(currentGraph.unique(v)));
     }
 
-    private void genLogicOp(CiKind kind, int opcode) {
+    private void genLogicOp(Kind kind, int opcode) {
         ValueNode y = frameState.pop(kind);
         ValueNode x = frameState.pop(kind);
         LogicNode v;
@@ -471,7 +472,7 @@
         frameState.push(kind, append(currentGraph.unique(v)));
     }
 
-    private void genCompareOp(CiKind kind, boolean isUnorderedLess) {
+    private void genCompareOp(Kind kind, boolean isUnorderedLess) {
         ValueNode y = frameState.pop(kind);
         ValueNode x = frameState.pop(kind);
         frameState.ipush(append(currentGraph.unique(new NormalizeCompareNode(x, y, isUnorderedLess))));
@@ -487,7 +488,7 @@
         int delta = stream().readIncrement();
         ValueNode x = frameState.loadLocal(index);
         ValueNode y = append(ConstantNode.forInt(delta, currentGraph));
-        frameState.storeLocal(index, append(currentGraph.unique(new IntegerAddNode(CiKind.Int, x, y))));
+        frameState.storeLocal(index, append(currentGraph.unique(new IntegerAddNode(Kind.Int, x, y))));
     }
 
     private void genGoto() {
@@ -516,25 +517,47 @@
             probability = 0.5;
         }
 
-        CompareNode condition = currentGraph.unique(new CompareNode(x, cond, y));
+        // the mirroring and negation operations get the condition into canonical form
+        boolean mirror = cond.canonicalMirror();
+        boolean negate = cond.canonicalNegate();
+
+        ValueNode a = mirror ? y : x;
+        ValueNode b = mirror ? x : y;
+
+        CompareNode condition;
+        assert !a.kind().isFloatOrDouble();
+        if (cond == Condition.EQ || cond == Condition.NE) {
+            if (a.kind() == Kind.Object) {
+                condition = new ObjectEqualsNode(a, b);
+            } else {
+                condition = new IntegerEqualsNode(a, b);
+            }
+        } else {
+            assert a.kind() != Kind.Object && !cond.isUnsigned();
+            condition = new IntegerLessThanNode(a, b);
+        }
+        condition = currentGraph.unique(condition);
+
         BeginNode trueSuccessor = createBlockTarget(probability, trueBlock, frameState);
         BeginNode falseSuccessor = createBlockTarget(1 - probability, falseBlock, frameState);
-        append(currentGraph.add(new IfNode(condition, trueSuccessor, falseSuccessor, probability)));
+
+        IfNode ifNode = negate ? new IfNode(condition, falseSuccessor, trueSuccessor, 1 - probability, graphId) : new IfNode(condition, trueSuccessor, falseSuccessor, probability, graphId);
+        append(currentGraph.add(ifNode));
     }
 
     private void genIfZero(Condition cond) {
-        ValueNode y = appendConstant(CiConstant.INT_0);
+        ValueNode y = appendConstant(Constant.INT_0);
         ValueNode x = frameState.ipop();
         ifNode(x, cond, y);
     }
 
     private void genIfNull(Condition cond) {
-        ValueNode y = appendConstant(CiConstant.NULL_OBJECT);
+        ValueNode y = appendConstant(Constant.NULL_OBJECT);
         ValueNode x = frameState.apop();
         ifNode(x, cond, y);
     }
 
-    private void genIfSame(CiKind kind, Condition cond) {
+    private void genIfSame(Kind kind, Condition cond) {
         ValueNode y = frameState.pop(kind);
         ValueNode x = frameState.pop(kind);
         assert !x.isDeleted() && !y.isDeleted();
@@ -543,44 +566,44 @@
 
     private void genThrow() {
         ValueNode exception = frameState.apop();
-        FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, graphId));
+        FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true, graphId));
         append(node);
         append(handleException(exception, bci()));
     }
 
-    private RiType lookupType(int cpi, int bytecode) {
+    private JavaType lookupType(int cpi, int bytecode) {
         eagerResolvingForSnippets(cpi, bytecode);
-        RiType result = constantPool.lookupType(cpi, bytecode);
-        assert !graphBuilderConfig.eagerResolvingForSnippets() || result instanceof RiResolvedType;
+        JavaType result = constantPool.lookupType(cpi, bytecode);
+        assert !graphBuilderConfig.eagerResolvingForSnippets() || result instanceof ResolvedJavaType;
         return result;
     }
 
-    private RiMethod lookupMethod(int cpi, int opcode) {
+    private JavaMethod lookupMethod(int cpi, int opcode) {
         eagerResolvingForSnippets(cpi, opcode);
-        RiMethod result = constantPool.lookupMethod(cpi, opcode);
-        assert !graphBuilderConfig.eagerResolvingForSnippets() || ((result instanceof RiResolvedMethod) && ((RiResolvedMethod) result).holder().isInitialized());
+        JavaMethod result = constantPool.lookupMethod(cpi, opcode);
+        assert !graphBuilderConfig.eagerResolvingForSnippets() || ((result instanceof ResolvedJavaMethod) && ((ResolvedJavaMethod) result).holder().isInitialized());
         return result;
     }
 
-    private RiField lookupField(int cpi, int opcode) {
+    private JavaField lookupField(int cpi, int opcode) {
         eagerResolvingForSnippets(cpi, opcode);
-        RiField result = constantPool.lookupField(cpi, opcode);
-        assert !graphBuilderConfig.eagerResolvingForSnippets() || (result instanceof RiResolvedField && ((RiResolvedField) result).holder().isInitialized());
+        JavaField result = constantPool.lookupField(cpi, opcode);
+        assert !graphBuilderConfig.eagerResolvingForSnippets() || (result instanceof ResolvedJavaField && ((ResolvedJavaField) result).holder().isInitialized());
         return result;
     }
 
     private Object lookupConstant(int cpi, int opcode) {
-        eagerResolving(cpi, opcode);
+        eagerResolvingForSnippets(cpi, opcode);
         Object result = constantPool.lookupConstant(cpi);
-        assert !graphBuilderConfig.eagerResolving() || !(result instanceof RiType) || (result instanceof RiResolvedType);
+        assert !graphBuilderConfig.eagerResolving() || !(result instanceof JavaType) || (result instanceof ResolvedJavaType);
         return result;
     }
 
-    private void eagerResolving(int cpi, int bytecode) {
-        if (graphBuilderConfig.eagerResolving()) {
-            constantPool.loadReferencedType(cpi, bytecode);
-        }
-    }
+//    private void eagerResolving(int cpi, int bytecode) {
+//        if (graphBuilderConfig.eagerResolving()) {
+//            constantPool.loadReferencedType(cpi, bytecode);
+//        }
+//    }
 
     private void eagerResolvingForSnippets(int cpi, int bytecode) {
         if (graphBuilderConfig.eagerResolvingForSnippets()) {
@@ -588,87 +611,63 @@
         }
     }
 
-    private static final RiResolvedType[] EMPTY_TYPE_ARRAY = new RiResolvedType[0];
-
-    private RiResolvedType[] getTypeCheckHints(RiResolvedType type, int maxHints) {
-        if (!optimisticOpts.useUseTypeCheckHints() || Util.isFinalClass(type)) {
-            return new RiResolvedType[] {type};
+    private JavaTypeProfile getProfileForTypeCheck(ResolvedJavaType type) {
+        if (!optimisticOpts.useTypeCheckHints() || TypeCheckHints.isFinalClass(type)) {
+            return null;
         } else {
-            RiResolvedType uniqueSubtype = type.uniqueConcreteSubtype();
+            ResolvedJavaType uniqueSubtype = type.uniqueConcreteSubtype();
             if (uniqueSubtype != null) {
-                return new RiResolvedType[] {uniqueSubtype};
+                return new JavaTypeProfile(0.0D, new ProfiledType(uniqueSubtype, 1.0D));
             } else {
-                RiTypeProfile typeProfile = profilingInfo.getTypeProfile(bci());
-                if (typeProfile != null) {
-                    double notRecordedTypes = typeProfile.getNotRecordedProbability();
-                    RiResolvedType[] types = typeProfile.getTypes();
-
-                    if (notRecordedTypes == 0 && types != null && types.length > 0 && types.length <= maxHints) {
-                        RiResolvedType[] hints = new RiResolvedType[types.length];
-                        int hintCount = 0;
-                        for (RiResolvedType hint : types) {
-                            if (hint.isSubtypeOf(type)) {
-                                hints[hintCount++] = hint;
-                            }
-                        }
-                        return Arrays.copyOf(hints, Math.min(maxHints, hintCount));
-                    }
-                }
-                return EMPTY_TYPE_ARRAY;
+                return profilingInfo.getTypeProfile(bci());
             }
         }
     }
 
     private void genCheckCast() {
         int cpi = stream().readCPI();
-        RiType type = lookupType(cpi, CHECKCAST);
-        boolean initialized = type instanceof RiResolvedType;
+        JavaType type = lookupType(cpi, CHECKCAST);
+        boolean initialized = type instanceof ResolvedJavaType;
         if (initialized) {
-            ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, true);
+            ConstantNode typeInstruction = genTypeOrDeopt(JavaType.Representation.ObjectHub, type, true);
             ValueNode object = frameState.apop();
-            AnchorNode anchor = currentGraph.add(new AnchorNode());
-            append(anchor);
-            CheckCastNode checkCast;
-            RiResolvedType[] hints = getTypeCheckHints((RiResolvedType) type, 2);
-            checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object, hints, Util.isFinalClass((RiResolvedType) type)));
-            append(currentGraph.add(new ValueAnchorNode(checkCast)));
+            CheckCastNode checkCast = currentGraph.add(new CheckCastNode(typeInstruction, (ResolvedJavaType) type, object, getProfileForTypeCheck((ResolvedJavaType) type)));
+            append(checkCast);
             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, RiDeoptAction.InvalidateRecompile, graphId)));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+            append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IsNullNode(object)), DeoptimizationReason.Unresolved, DeoptimizationAction.InvalidateRecompile, graphId)));
+            frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
     }
 
     private void genInstanceOf() {
         int cpi = stream().readCPI();
-        RiType type = lookupType(cpi, INSTANCEOF);
+        JavaType type = lookupType(cpi, INSTANCEOF);
         ValueNode object = frameState.apop();
-        if (type instanceof RiResolvedType) {
-            RiResolvedType resolvedType = (RiResolvedType) type;
-            ConstantNode hub = appendConstant(resolvedType.getEncoding(RiType.Representation.ObjectHub));
-
-            RiResolvedType[] hints = getTypeCheckHints(resolvedType, 1);
-            InstanceOfNode instanceOfNode = new InstanceOfNode(hub, (RiResolvedType) type, object, hints, Util.isFinalClass(resolvedType), false);
+        if (type instanceof ResolvedJavaType) {
+            ResolvedJavaType resolvedType = (ResolvedJavaType) type;
+            ConstantNode hub = appendConstant(resolvedType.getEncoding(JavaType.Representation.ObjectHub));
+            InstanceOfNode instanceOfNode = new InstanceOfNode(hub, (ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType));
             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, graphId));
-            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(object, true)), trueSucc, deopt, 1));
+            BlockPlaceholderNode successor = currentGraph.add(new BlockPlaceholderNode());
+            DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId));
+            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(object)), successor, deopt, 1, graphId));
             append(ifNode);
-            lastInstr = trueSucc;
-            frameState.ipush(appendConstant(CiConstant.INT_0));
+            lastInstr = successor;
+            frameState.ipush(appendConstant(Constant.INT_0));
         }
     }
 
     void genNewInstance(int cpi) {
-        RiType type = lookupType(cpi, NEW);
-        if (type instanceof RiResolvedType) {
-            NewInstanceNode n = currentGraph.add(new NewInstanceNode((RiResolvedType) type));
+        JavaType type = lookupType(cpi, NEW);
+        if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) {
+            NewInstanceNode n = currentGraph.add(new NewInstanceNode((ResolvedJavaType) type));
             frameState.apush(append(n));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
     }
 
@@ -678,68 +677,68 @@
      * @param code the array type code
      * @return the kind from the array type code
      */
-    public static CiKind arrayTypeCodeToKind(int code) {
+    public static Kind arrayTypeCodeToKind(int code) {
         // Checkstyle: stop
         switch (code) {
-            case 4:  return CiKind.Boolean;
-            case 5:  return CiKind.Char;
-            case 6:  return CiKind.Float;
-            case 7:  return CiKind.Double;
-            case 8:  return CiKind.Byte;
-            case 9:  return CiKind.Short;
-            case 10: return CiKind.Int;
-            case 11: return CiKind.Long;
+            case 4:  return Kind.Boolean;
+            case 5:  return Kind.Char;
+            case 6:  return Kind.Float;
+            case 7:  return Kind.Double;
+            case 8:  return Kind.Byte;
+            case 9:  return Kind.Short;
+            case 10: return Kind.Int;
+            case 11: return Kind.Long;
             default: throw new IllegalArgumentException("unknown array type code: " + code);
         }
         // Checkstyle: resume
     }
 
     private void genNewTypeArray(int typeCode) {
-        CiKind kind = arrayTypeCodeToKind(typeCode);
-        RiResolvedType elementType = runtime.asRiType(kind);
+        Kind kind = arrayTypeCodeToKind(typeCode);
+        ResolvedJavaType elementType = runtime.getResolvedJavaType(kind);
         NewTypeArrayNode nta = currentGraph.add(new NewTypeArrayNode(frameState.ipop(), elementType));
         frameState.apush(append(nta));
     }
 
     private void genNewObjectArray(int cpi) {
-        RiType type = lookupType(cpi, ANEWARRAY);
+        JavaType type = lookupType(cpi, ANEWARRAY);
         ValueNode length = frameState.ipop();
-        if (type instanceof RiResolvedType) {
-            NewArrayNode n = currentGraph.add(new NewObjectArrayNode((RiResolvedType) type, length));
+        if (type instanceof ResolvedJavaType) {
+            NewArrayNode n = currentGraph.add(new NewObjectArrayNode((ResolvedJavaType) type, length));
             frameState.apush(append(n));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
 
     }
 
     private void genNewMultiArray(int cpi) {
-        RiType type = lookupType(cpi, MULTIANEWARRAY);
+        JavaType type = lookupType(cpi, MULTIANEWARRAY);
         int rank = stream().readUByte(bci() + 3);
         ValueNode[] dims = new ValueNode[rank];
         for (int i = rank - 1; i >= 0; i--) {
             dims[i] = frameState.ipop();
         }
-        if (type instanceof RiResolvedType) {
-            FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((RiResolvedType) type, dims));
+        if (type instanceof ResolvedJavaType) {
+            FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((ResolvedJavaType) type, dims));
             frameState.apush(append(n));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
-            frameState.apush(appendConstant(CiConstant.NULL_OBJECT));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
+            frameState.apush(appendConstant(Constant.NULL_OBJECT));
         }
     }
 
-    private void genGetField(RiField field) {
+    private void genGetField(JavaField field) {
         emitExplicitExceptions(frameState.peek(0), null);
 
-        CiKind kind = field.kind(false);
+        Kind kind = field.kind();
         ValueNode receiver = frameState.apop();
-        if ((field instanceof RiResolvedField) && ((RiResolvedField) field).holder().isInitialized()) {
-            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (RiResolvedField) field));
+        if ((field instanceof ResolvedJavaField) && ((ResolvedJavaField) field).holder().isInitialized()) {
+            LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (ResolvedJavaField) field, graphId));
             appendOptimizedLoadField(kind, load);
         } else {
-            append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
             frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
         }
     }
@@ -758,18 +757,18 @@
     private void emitNullCheck(ValueNode receiver) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(receiver, false)), trueSucc, falseSucc, 1));
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.5, graphId));
 
         append(ifNode);
-        lastInstr = trueSucc;
+        lastInstr = falseSucc;
 
         if (GraalOptions.OmitHotExceptionStacktrace) {
             ValueNode exception = ConstantNode.forObject(new NullPointerException(), runtime, currentGraph);
-            falseSucc.setNext(handleException(exception, bci()));
+            trueSucc.setNext(handleException(exception, bci()));
         } else {
-            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateNullPointerException));
+            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(RuntimeCall.CreateNullPointerException));
             call.setStateAfter(frameState.create(bci()));
-            falseSucc.setNext(call);
+            trueSucc.setNext(call);
             call.setNext(handleException(call, bci()));
         }
     }
@@ -777,7 +776,7 @@
     private void emitBoundsCheck(ValueNode index, ValueNode length) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new CompareNode(index, Condition.BT, length)), trueSucc, falseSucc, 1));
+        IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.5, graphId));
 
         append(ifNode);
         lastInstr = trueSucc;
@@ -786,7 +785,7 @@
             ValueNode exception = ConstantNode.forObject(new ArrayIndexOutOfBoundsException(), runtime, currentGraph);
             falseSucc.setNext(handleException(exception, bci()));
         } else {
-            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(CiRuntimeCall.CreateOutOfBoundsException, new ValueNode[] {index}));
+            RuntimeCallNode call = currentGraph.add(new RuntimeCallNode(RuntimeCall.CreateOutOfBoundsException, new ValueNode[] {index}));
             call.setStateAfter(frameState.create(bci()));
             falseSucc.setNext(call);
             call.setNext(handleException(call, bci()));
@@ -795,7 +794,7 @@
 
     private void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) {
         assert receiver != null;
-        if (!GraalOptions.AllowExplicitExceptionChecks || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == RiExceptionSeen.FALSE)) {
+        if (!GraalOptions.AllowExplicitExceptionChecks || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == ExceptionSeen.FALSE)) {
             return;
         }
 
@@ -807,33 +806,33 @@
         Debug.metric("ExplicitExceptions").increment();
     }
 
-    private void genPutField(RiField field) {
+    private void genPutField(JavaField field) {
         emitExplicitExceptions(frameState.peek(1), null);
 
-        ValueNode value = frameState.pop(field.kind(false).stackKind());
+        ValueNode value = frameState.pop(field.kind().stackKind());
         ValueNode receiver = frameState.apop();
-        if (field instanceof RiResolvedField && ((RiResolvedField) field).holder().isInitialized()) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (RiResolvedField) field, value));
+        if (field instanceof ResolvedJavaField && ((ResolvedJavaField) field).holder().isInitialized()) {
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (ResolvedJavaField) field, value, graphId));
             appendOptimizedStoreField(store);
         } else {
-            append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
         }
     }
 
-    private void genGetStatic(RiField field) {
-        RiType holder = field.holder();
-        boolean isInitialized = (field instanceof RiResolvedField) && ((RiResolvedType) holder).isInitialized();
-        CiConstant constantValue = null;
+    private void genGetStatic(JavaField field) {
+        JavaType holder = field.holder();
+        boolean isInitialized = (field instanceof ResolvedJavaField) && ((ResolvedJavaType) holder).isInitialized();
+        Constant constantValue = null;
         if (isInitialized) {
-            constantValue = ((RiResolvedField) field).constantValue(null);
+            constantValue = ((ResolvedJavaField) field).constantValue(null);
         }
         if (constantValue != null) {
             frameState.push(constantValue.kind.stackKind(), appendConstant(constantValue));
         } else {
-            ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, isInitialized);
-            CiKind kind = field.kind(false);
+            ValueNode container = genTypeOrDeopt(JavaType.Representation.StaticFields, holder, isInitialized);
+            Kind kind = field.kind();
             if (container != null) {
-                LoadFieldNode load = currentGraph.add(new LoadFieldNode(container, (RiResolvedField) field));
+                LoadFieldNode load = currentGraph.add(new LoadFieldNode(container, (ResolvedJavaField) field, graphId));
                 appendOptimizedLoadField(kind, load);
             } else {
                 // deopt will be generated by genTypeOrDeopt, not needed here
@@ -842,23 +841,23 @@
         }
     }
 
-    private void genPutStatic(RiField field) {
-        RiType holder = field.holder();
-        ValueNode container = genTypeOrDeopt(RiType.Representation.StaticFields, holder, field instanceof RiResolvedField && ((RiResolvedType) holder).isInitialized());
-        ValueNode value = frameState.pop(field.kind(false).stackKind());
+    private void genPutStatic(JavaField field) {
+        JavaType holder = field.holder();
+        ValueNode container = genTypeOrDeopt(JavaType.Representation.StaticFields, holder, field instanceof ResolvedJavaField && ((ResolvedJavaType) holder).isInitialized());
+        ValueNode value = frameState.pop(field.kind().stackKind());
         if (container != null) {
-            StoreFieldNode store = currentGraph.add(new StoreFieldNode(container, (RiResolvedField) field, value));
+            StoreFieldNode store = currentGraph.add(new StoreFieldNode(container, (ResolvedJavaField) field, value, graphId));
             appendOptimizedStoreField(store);
         } else {
             // deopt will be generated by genTypeOrDeopt, not needed here
         }
     }
 
-    private ConstantNode genTypeOrDeopt(RiType.Representation representation, RiType holder, boolean initialized) {
+    private ConstantNode genTypeOrDeopt(JavaType.Representation representation, JavaType holder, boolean initialized) {
         if (initialized) {
-            return appendConstant(((RiResolvedType) holder).getEncoding(representation));
+            return appendConstant(((ResolvedJavaType) holder).getEncoding(representation));
         } else {
-            append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
+            append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
             return null;
         }
     }
@@ -867,16 +866,16 @@
         append(store);
     }
 
-    private void appendOptimizedLoadField(CiKind kind, LoadFieldNode load) {
+    private void appendOptimizedLoadField(Kind kind, LoadFieldNode load) {
         // append the load to the instruction
         ValueNode optimized = append(load);
         frameState.push(kind.stackKind(), optimized);
     }
 
-    private void genInvokeStatic(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
-            RiResolvedMethod resolvedTarget = (RiResolvedMethod) target;
-            RiResolvedType holder = resolvedTarget.holder();
+    private void genInvokeStatic(JavaMethod target) {
+        if (target instanceof ResolvedJavaMethod) {
+            ResolvedJavaMethod resolvedTarget = (ResolvedJavaMethod) target;
+            ResolvedJavaType holder = resolvedTarget.holder();
             if (!holder.isInitialized() && GraalOptions.ResolveClassBeforeStaticInvoke) {
                 genInvokeDeopt(target, false);
             } else {
@@ -888,49 +887,49 @@
         }
     }
 
-    private void genInvokeInterface(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
+    private void genInvokeInterface(JavaMethod target) {
+        if (target instanceof ResolvedJavaMethod) {
             ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
-            genInvokeIndirect(InvokeKind.Interface, (RiResolvedMethod) target, args);
+            genInvokeIndirect(InvokeKind.Interface, (ResolvedJavaMethod) target, args);
         } else {
             genInvokeDeopt(target, true);
         }
     }
 
-    private void genInvokeVirtual(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
+    private void genInvokeVirtual(JavaMethod target) {
+        if (target instanceof ResolvedJavaMethod) {
             ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
-            genInvokeIndirect(InvokeKind.Virtual, (RiResolvedMethod) target, args);
+            genInvokeIndirect(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
         } else {
             genInvokeDeopt(target, true);
         }
 
     }
 
-    private void genInvokeSpecial(RiMethod target) {
-        if (target instanceof RiResolvedMethod) {
+    private void genInvokeSpecial(JavaMethod target) {
+        if (target instanceof ResolvedJavaMethod) {
             assert target != null;
             assert target.signature() != null;
             ValueNode[] args = frameState.popArguments(target.signature().argumentSlots(true), target.signature().argumentCount(true));
-            invokeDirect((RiResolvedMethod) target, args);
+            invokeDirect((ResolvedJavaMethod) target, args);
         } else {
             genInvokeDeopt(target, true);
         }
     }
 
-    private void genInvokeDeopt(RiMethod unresolvedTarget, boolean withReceiver) {
-        append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved, graphId)));
+    private void genInvokeDeopt(JavaMethod unresolvedTarget, boolean withReceiver) {
+        append(currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.Unresolved, graphId)));
         frameState.popArguments(unresolvedTarget.signature().argumentSlots(withReceiver), unresolvedTarget.signature().argumentCount(withReceiver));
-        CiKind kind = unresolvedTarget.signature().returnKind(false);
-        if (kind != CiKind.Void) {
+        Kind kind = unresolvedTarget.signature().returnKind();
+        if (kind != Kind.Void) {
             frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph)));
         }
     }
 
-    private void genInvokeIndirect(InvokeKind invokeKind, RiResolvedMethod target, ValueNode[] args) {
+    private void genInvokeIndirect(InvokeKind invokeKind, ResolvedJavaMethod target, ValueNode[] args) {
         ValueNode receiver = args[0];
         // attempt to devirtualize the call
-        RiResolvedType klass = target.holder();
+        ResolvedJavaType klass = target.holder();
 
         // 0. check for trivial cases
         if (target.canBeStaticallyBound() && !isAbstract(target.accessFlags())) {
@@ -939,7 +938,10 @@
             return;
         }
         // 1. check if the exact type of the receiver can be determined
-        RiResolvedType exact = getExactType(klass, receiver);
+        ResolvedJavaType exact = klass.exactType();
+        if (exact == null && receiver.objectStamp().isExactType()) {
+            exact = receiver.objectStamp().type();
+        }
         if (exact != null) {
             // either the holder class is exact, or the receiver object has an exact type
             invokeDirect(exact.resolveMethodImpl(target), args);
@@ -949,14 +951,14 @@
         appendInvoke(invokeKind, target, args);
     }
 
-    private void invokeDirect(RiResolvedMethod target, ValueNode[] args) {
+    private void invokeDirect(ResolvedJavaMethod target, ValueNode[] args) {
         appendInvoke(InvokeKind.Special, target, args);
     }
 
-    private void appendInvoke(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] args) {
-        CiKind resultType = targetMethod.signature().returnKind(false);
+    private void appendInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args) {
+        Kind resultType = targetMethod.signature().returnKind();
         if (GraalOptions.DeoptALot) {
-            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(RiDeoptAction.None, RiDeoptReason.RuntimeConstraint, StructuredGraph.INVALID_GRAPH_ID));
+            DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint, graphId));
             deoptimize.setMessage("invoke " + targetMethod.name());
             append(deoptimize);
             frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph));
@@ -965,12 +967,12 @@
 
         MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, targetMethod.signature().returnType(method.holder())));
         // be conservative if information was not recorded (could result in endless recompiles otherwise)
-        if (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == RiExceptionSeen.FALSE) {
+        if (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == ExceptionSeen.FALSE) {
             ValueNode result = appendWithBCI(currentGraph.add(new InvokeNode(callTarget, bci(), graphId)));
             frameState.pushReturn(resultType, result);
 
         } else {
-            BeginNode exceptionEdge = handleException(null, bci());
+            DispatchBeginNode exceptionEdge = handleException(null, bci());
             InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci(), graphId));
             ValueNode result = append(invoke);
             frameState.pushReturn(resultType, result);
@@ -984,25 +986,6 @@
         }
     }
 
-    private RiResolvedType getExactType(RiResolvedType staticType, ValueNode receiver) {
-        RiResolvedType exact = staticType.exactType();
-        if (exact == null) {
-            exact = receiver.exactType();
-            if (exact == null) {
-                if (receiver.isConstant()) {
-                    exact = runtime.getTypeOf(receiver.asConstant());
-                }
-                if (exact == null) {
-                    RiResolvedType declared = receiver.declaredType();
-                    if (declared != null) {
-                        exact = declared.exactType();
-                    }
-                }
-            }
-        }
-        return exact;
-    }
-
     private void callRegisterFinalizer() {
         // append a call to the finalizer registration
         append(currentGraph.add(new RegisterFinalizerNode(frameState.loadLocal(0))));
@@ -1038,7 +1021,7 @@
         if (successor.jsrScope.nextReturnAddress() != stream().nextBCI()) {
             throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
         }
-        frameState.push(CiKind.Jsr, ConstantNode.forJsr(stream().nextBCI(), currentGraph));
+        frameState.push(Kind.Jsr, ConstantNode.forJsr(stream().nextBCI(), currentGraph));
         appendGoto(createTarget(successor, frameState));
     }
 
@@ -1047,29 +1030,13 @@
         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, RiDeoptAction.InvalidateReprofile, graphId)));
+        append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new IntegerEqualsNode(local, ConstantNode.forJsr(retAddress, currentGraph))), DeoptimizationReason.JavaSubroutineMismatch, DeoptimizationAction.InvalidateReprofile, graphId)));
         if (!successor.jsrScope.equals(scope.pop())) {
             throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
         }
         appendGoto(createTarget(successor, frameState));
     }
 
-    private void genTableswitch() {
-        int bci = bci();
-        ValueNode value = frameState.ipop();
-        BytecodeTableSwitch ts = new BytecodeTableSwitch(stream(), bci);
-
-        int nofCases = ts.numberOfCases() + 1; // including default case
-        assert currentBlock.numNormalSuccessors() == nofCases;
-
-        double[] probabilities = switchProbability(nofCases, bci);
-        TableSwitchNode tableSwitch = currentGraph.add(new TableSwitchNode(value, ts.lowKey(), probabilities));
-        for (int i = 0; i < nofCases; ++i) {
-            tableSwitch.setBlockSuccessor(i, createBlockTarget(probabilities[i], currentBlock.successors.get(i), frameState));
-        }
-        append(tableSwitch);
-    }
-
     private double[] switchProbability(int numberOfCases, int bci) {
         double[] prob = profilingInfo.getSwitchProbabilities(bci);
         if (prob != null) {
@@ -1094,28 +1061,42 @@
         return true;
     }
 
-    private void genLookupswitch() {
+    private void genSwitch(BytecodeSwitch bs) {
         int bci = bci();
         ValueNode value = frameState.ipop();
-        BytecodeLookupSwitch ls = new BytecodeLookupSwitch(stream(), bci);
+
+        int nofCases = bs.numberOfCases();
 
-        int nofCases = ls.numberOfCases() + 1; // including default case
-        assert currentBlock.numNormalSuccessors() == nofCases;
+        Map<Integer, Integer> bciToSuccessorIndex = new HashMap<>();
+        int successorCount = currentBlock.successors.size();
+        for (int i = 0; i < successorCount; i++) {
+            assert !bciToSuccessorIndex.containsKey(currentBlock.successors.get(i).startBci);
+            if (!bciToSuccessorIndex.containsKey(currentBlock.successors.get(i).startBci)) {
+                bciToSuccessorIndex.put(currentBlock.successors.get(i).startBci, i);
+            }
+        }
 
-        int[] keys = new int[nofCases - 1];
-        for (int i = 0; i < nofCases - 1; ++i) {
-            keys[i] = ls.keyAt(i);
+        double[] keyProbabilities = switchProbability(nofCases + 1, bci);
+
+        int[] keys = new int[nofCases];
+        int[] keySuccessors = new int[nofCases + 1];
+        for (int i = 0; i < nofCases; i++) {
+            keys[i] = bs.keyAt(i);
+            keySuccessors[i] = bciToSuccessorIndex.get(bs.targetAt(i));
         }
-        double[] probabilities = switchProbability(nofCases, bci);
-        LookupSwitchNode lookupSwitch = currentGraph.add(new LookupSwitchNode(value, keys, probabilities));
-        for (int i = 0; i < nofCases; ++i) {
-            lookupSwitch.setBlockSuccessor(i, createBlockTarget(probabilities[i], currentBlock.successors.get(i), frameState));
+        keySuccessors[nofCases] = bciToSuccessorIndex.get(bs.defaultTarget());
+
+        double[] successorProbabilities = IntegerSwitchNode.successorProbabilites(successorCount, keySuccessors, keyProbabilities);
+        IntegerSwitchNode lookupSwitch = currentGraph.add(new IntegerSwitchNode(value, successorCount, keys, keyProbabilities, keySuccessors));
+        for (int i = 0; i < successorCount; i++) {
+            lookupSwitch.setBlockSuccessor(i, createBlockTarget(successorProbabilities[i], currentBlock.successors.get(i), frameState));
         }
         append(lookupSwitch);
     }
 
-    private ConstantNode appendConstant(CiConstant constant) {
-        return ConstantNode.forCiConstant(constant, runtime, currentGraph);
+    private ConstantNode appendConstant(Constant constant) {
+        assert constant != null;
+        return ConstantNode.forConstant(constant, runtime, currentGraph);
     }
 
     private ValueNode append(FixedNode fixed) {
@@ -1204,7 +1185,7 @@
     private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) {
         assert probability >= 0 && probability <= 1;
         if (probability == 0 && optimisticOpts.removeNeverExecutedCode()) {
-            return currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.UnreachedCode, graphId));
+            return currentGraph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode, graphId));
         } else {
             return createTarget(block, stateAfter);
         }
@@ -1229,7 +1210,7 @@
 
         // We already saw this block before, so we have to merge states.
         if (!block.entryState.isCompatibleWith(state)) {
-            throw new CiBailout("stacks do not match; bytecodes would not verify");
+            throw new BailoutException("stacks do not match; bytecodes would not verify");
         }
 
         if (block.firstInstruction instanceof LoopBeginNode) {
@@ -1290,9 +1271,9 @@
         return begin;
     }
 
-    private ValueNode synchronizedObject(FrameStateBuilder state, RiResolvedMethod target) {
+    private ValueNode synchronizedObject(FrameStateBuilder state, ResolvedJavaMethod target) {
         if (isStatic(target.accessFlags())) {
-            return append(ConstantNode.forCiConstant(target.holder().getEncoding(Representation.JavaClass), runtime, currentGraph));
+            return append(ConstantNode.forConstant(target.holder().getEncoding(Representation.JavaClass), runtime, currentGraph));
         } else {
             return state.loadLocal(0);
         }
@@ -1363,8 +1344,8 @@
         if (method.isConstructor() && method.holder().superType() == null) {
             callRegisterFinalizer();
         }
-        CiKind returnKind = method.signature().returnKind(false).stackKind();
-        ValueNode x = returnKind == CiKind.Void ? null : frameState.pop(returnKind);
+        Kind returnKind = method.signature().returnKind().stackKind();
+        ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind);
         assert frameState.stackSize() == 0;
 
         // TODO (gdub) remove this when FloatingRead can handle this case
@@ -1394,14 +1375,14 @@
             return;
         }
 
-        RiType catchType = block.handler.catchType();
+        JavaType catchType = block.handler.catchType();
         if (graphBuilderConfig.eagerResolving()) {
             catchType = lookupType(block.handler.catchTypeCPI(), INSTANCEOF);
         }
-        boolean initialized = (catchType instanceof RiResolvedType);
+        boolean initialized = (catchType instanceof ResolvedJavaType);
         if (initialized && graphBuilderConfig.getSkippedExceptionTypes() != null) {
-            RiResolvedType resolvedCatchType = (RiResolvedType) catchType;
-            for (RiResolvedType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
+            ResolvedJavaType resolvedCatchType = (ResolvedJavaType) catchType;
+            for (ResolvedJavaType skippedType : graphBuilderConfig.getSkippedExceptionTypes()) {
                 initialized &= !resolvedCatchType.isSubtypeOf(skippedType);
                 if (!initialized) {
                     break;
@@ -1409,13 +1390,19 @@
             }
         }
 
-        ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, catchType, initialized);
+        ConstantNode typeInstruction = genTypeOrDeopt(JavaType.Representation.ObjectHub, catchType, initialized);
         if (typeInstruction != null) {
             Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1);
+            ValueNode exception = frameState.stackAt(0);
+            CheckCastNode checkCast = currentGraph.add(new CheckCastNode(typeInstruction, (ResolvedJavaType) catchType, exception));
+            frameState.apop();
+            frameState.push(Kind.Object, checkCast);
             FixedNode catchSuccessor = createTarget(block.successors.get(0), frameState);
+            frameState.apop();
+            frameState.push(Kind.Object, exception);
             FixedNode nextDispatch = createTarget(nextBlock, frameState);
-            ValueNode exception = frameState.stackAt(0);
-            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode(typeInstruction, (RiResolvedType) catchType, exception, false)), catchSuccessor, nextDispatch, 0.5));
+            checkCast.setNext(catchSuccessor);
+            IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new InstanceOfNode(typeInstruction, (ResolvedJavaType) catchType, exception)), checkCast, nextDispatch, 0.5, graphId));
             append(ifNode);
         }
     }
@@ -1491,9 +1478,13 @@
                 frameState.clearNonLiveLocals(currentBlock.localsLiveOut);
             }
             if (lastInstr instanceof StateSplit) {
-                StateSplit stateSplit = (StateSplit) lastInstr;
-                if (stateSplit.stateAfter() == null && stateSplit.needsStateAfter()) {
-                    stateSplit.setStateAfter(frameState.create(bci));
+                if (lastInstr.getClass() == BeginNode.class) {
+                    // BeginNodes do not need a frame state
+                } else {
+                    StateSplit stateSplit = (StateSplit) lastInstr;
+                    if (stateSplit.stateAfter() == null) {
+                        stateSplit.setStateAfter(frameState.create(bci));
+                    }
                 }
             }
             if (bci < endBCI) {
@@ -1528,92 +1519,92 @@
         // Checkstyle: stop
         switch (opcode) {
             case NOP            : /* nothing to do */ break;
-            case ACONST_NULL    : frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); break;
-            case ICONST_M1      : frameState.ipush(appendConstant(CiConstant.INT_MINUS_1)); break;
-            case ICONST_0       : frameState.ipush(appendConstant(CiConstant.INT_0)); break;
-            case ICONST_1       : frameState.ipush(appendConstant(CiConstant.INT_1)); break;
-            case ICONST_2       : frameState.ipush(appendConstant(CiConstant.INT_2)); break;
-            case ICONST_3       : frameState.ipush(appendConstant(CiConstant.INT_3)); break;
-            case ICONST_4       : frameState.ipush(appendConstant(CiConstant.INT_4)); break;
-            case ICONST_5       : frameState.ipush(appendConstant(CiConstant.INT_5)); break;
-            case LCONST_0       : frameState.lpush(appendConstant(CiConstant.LONG_0)); break;
-            case LCONST_1       : frameState.lpush(appendConstant(CiConstant.LONG_1)); break;
-            case FCONST_0       : frameState.fpush(appendConstant(CiConstant.FLOAT_0)); break;
-            case FCONST_1       : frameState.fpush(appendConstant(CiConstant.FLOAT_1)); break;
-            case FCONST_2       : frameState.fpush(appendConstant(CiConstant.FLOAT_2)); break;
-            case DCONST_0       : frameState.dpush(appendConstant(CiConstant.DOUBLE_0)); break;
-            case DCONST_1       : frameState.dpush(appendConstant(CiConstant.DOUBLE_1)); break;
-            case BIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readByte()))); break;
-            case SIPUSH         : frameState.ipush(appendConstant(CiConstant.forInt(stream.readShort()))); break;
+            case ACONST_NULL    : frameState.apush(appendConstant(Constant.NULL_OBJECT)); break;
+            case ICONST_M1      : frameState.ipush(appendConstant(Constant.INT_MINUS_1)); break;
+            case ICONST_0       : frameState.ipush(appendConstant(Constant.INT_0)); break;
+            case ICONST_1       : frameState.ipush(appendConstant(Constant.INT_1)); break;
+            case ICONST_2       : frameState.ipush(appendConstant(Constant.INT_2)); break;
+            case ICONST_3       : frameState.ipush(appendConstant(Constant.INT_3)); break;
+            case ICONST_4       : frameState.ipush(appendConstant(Constant.INT_4)); break;
+            case ICONST_5       : frameState.ipush(appendConstant(Constant.INT_5)); break;
+            case LCONST_0       : frameState.lpush(appendConstant(Constant.LONG_0)); break;
+            case LCONST_1       : frameState.lpush(appendConstant(Constant.LONG_1)); break;
+            case FCONST_0       : frameState.fpush(appendConstant(Constant.FLOAT_0)); break;
+            case FCONST_1       : frameState.fpush(appendConstant(Constant.FLOAT_1)); break;
+            case FCONST_2       : frameState.fpush(appendConstant(Constant.FLOAT_2)); break;
+            case DCONST_0       : frameState.dpush(appendConstant(Constant.DOUBLE_0)); break;
+            case DCONST_1       : frameState.dpush(appendConstant(Constant.DOUBLE_1)); break;
+            case BIPUSH         : frameState.ipush(appendConstant(Constant.forInt(stream.readByte()))); break;
+            case SIPUSH         : frameState.ipush(appendConstant(Constant.forInt(stream.readShort()))); break;
             case LDC            : // fall through
             case LDC_W          : // fall through
             case LDC2_W         : genLoadConstant(stream.readCPI(), opcode); break;
-            case ILOAD          : loadLocal(stream.readLocalIndex(), CiKind.Int); break;
-            case LLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Long); break;
-            case FLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Float); break;
-            case DLOAD          : loadLocal(stream.readLocalIndex(), CiKind.Double); break;
-            case ALOAD          : loadLocal(stream.readLocalIndex(), CiKind.Object); break;
+            case ILOAD          : loadLocal(stream.readLocalIndex(), Kind.Int); break;
+            case LLOAD          : loadLocal(stream.readLocalIndex(), Kind.Long); break;
+            case FLOAD          : loadLocal(stream.readLocalIndex(), Kind.Float); break;
+            case DLOAD          : loadLocal(stream.readLocalIndex(), Kind.Double); break;
+            case ALOAD          : loadLocal(stream.readLocalIndex(), Kind.Object); break;
             case ILOAD_0        : // fall through
             case ILOAD_1        : // fall through
             case ILOAD_2        : // fall through
-            case ILOAD_3        : loadLocal(opcode - ILOAD_0, CiKind.Int); break;
+            case ILOAD_3        : loadLocal(opcode - ILOAD_0, Kind.Int); break;
             case LLOAD_0        : // fall through
             case LLOAD_1        : // fall through
             case LLOAD_2        : // fall through
-            case LLOAD_3        : loadLocal(opcode - LLOAD_0, CiKind.Long); break;
+            case LLOAD_3        : loadLocal(opcode - LLOAD_0, Kind.Long); break;
             case FLOAD_0        : // fall through
             case FLOAD_1        : // fall through
             case FLOAD_2        : // fall through
-            case FLOAD_3        : loadLocal(opcode - FLOAD_0, CiKind.Float); break;
+            case FLOAD_3        : loadLocal(opcode - FLOAD_0, Kind.Float); break;
             case DLOAD_0        : // fall through
             case DLOAD_1        : // fall through
             case DLOAD_2        : // fall through
-            case DLOAD_3        : loadLocal(opcode - DLOAD_0, CiKind.Double); break;
+            case DLOAD_3        : loadLocal(opcode - DLOAD_0, Kind.Double); break;
             case ALOAD_0        : // fall through
             case ALOAD_1        : // fall through
             case ALOAD_2        : // fall through
-            case ALOAD_3        : loadLocal(opcode - ALOAD_0, CiKind.Object); break;
-            case IALOAD         : genLoadIndexed(CiKind.Int   ); break;
-            case LALOAD         : genLoadIndexed(CiKind.Long  ); break;
-            case FALOAD         : genLoadIndexed(CiKind.Float ); break;
-            case DALOAD         : genLoadIndexed(CiKind.Double); break;
-            case AALOAD         : genLoadIndexed(CiKind.Object); break;
-            case BALOAD         : genLoadIndexed(CiKind.Byte  ); break;
-            case CALOAD         : genLoadIndexed(CiKind.Char  ); break;
-            case SALOAD         : genLoadIndexed(CiKind.Short ); break;
-            case ISTORE         : storeLocal(CiKind.Int, stream.readLocalIndex()); break;
-            case LSTORE         : storeLocal(CiKind.Long, stream.readLocalIndex()); break;
-            case FSTORE         : storeLocal(CiKind.Float, stream.readLocalIndex()); break;
-            case DSTORE         : storeLocal(CiKind.Double, stream.readLocalIndex()); break;
-            case ASTORE         : storeLocal(CiKind.Object, stream.readLocalIndex()); break;
+            case ALOAD_3        : loadLocal(opcode - ALOAD_0, Kind.Object); break;
+            case IALOAD         : genLoadIndexed(Kind.Int   ); break;
+            case LALOAD         : genLoadIndexed(Kind.Long  ); break;
+            case FALOAD         : genLoadIndexed(Kind.Float ); break;
+            case DALOAD         : genLoadIndexed(Kind.Double); break;
+            case AALOAD         : genLoadIndexed(Kind.Object); break;
+            case BALOAD         : genLoadIndexed(Kind.Byte  ); break;
+            case CALOAD         : genLoadIndexed(Kind.Char  ); break;
+            case SALOAD         : genLoadIndexed(Kind.Short ); break;
+            case ISTORE         : storeLocal(Kind.Int, stream.readLocalIndex()); break;
+            case LSTORE         : storeLocal(Kind.Long, stream.readLocalIndex()); break;
+            case FSTORE         : storeLocal(Kind.Float, stream.readLocalIndex()); break;
+            case DSTORE         : storeLocal(Kind.Double, stream.readLocalIndex()); break;
+            case ASTORE         : storeLocal(Kind.Object, stream.readLocalIndex()); break;
             case ISTORE_0       : // fall through
             case ISTORE_1       : // fall through
             case ISTORE_2       : // fall through
-            case ISTORE_3       : storeLocal(CiKind.Int, opcode - ISTORE_0); break;
+            case ISTORE_3       : storeLocal(Kind.Int, opcode - ISTORE_0); break;
             case LSTORE_0       : // fall through
             case LSTORE_1       : // fall through
             case LSTORE_2       : // fall through
-            case LSTORE_3       : storeLocal(CiKind.Long, opcode - LSTORE_0); break;
+            case LSTORE_3       : storeLocal(Kind.Long, opcode - LSTORE_0); break;
             case FSTORE_0       : // fall through
             case FSTORE_1       : // fall through
             case FSTORE_2       : // fall through
-            case FSTORE_3       : storeLocal(CiKind.Float, opcode - FSTORE_0); break;
+            case FSTORE_3       : storeLocal(Kind.Float, opcode - FSTORE_0); break;
             case DSTORE_0       : // fall through
             case DSTORE_1       : // fall through
             case DSTORE_2       : // fall through
-            case DSTORE_3       : storeLocal(CiKind.Double, opcode - DSTORE_0); break;
+            case DSTORE_3       : storeLocal(Kind.Double, opcode - DSTORE_0); break;
             case ASTORE_0       : // fall through
             case ASTORE_1       : // fall through
             case ASTORE_2       : // fall through
-            case ASTORE_3       : storeLocal(CiKind.Object, opcode - ASTORE_0); break;
-            case IASTORE        : genStoreIndexed(CiKind.Int   ); break;
-            case LASTORE        : genStoreIndexed(CiKind.Long  ); break;
-            case FASTORE        : genStoreIndexed(CiKind.Float ); break;
-            case DASTORE        : genStoreIndexed(CiKind.Double); break;
-            case AASTORE        : genStoreIndexed(CiKind.Object); break;
-            case BASTORE        : genStoreIndexed(CiKind.Byte  ); break;
-            case CASTORE        : genStoreIndexed(CiKind.Char  ); break;
-            case SASTORE        : genStoreIndexed(CiKind.Short ); break;
+            case ASTORE_3       : storeLocal(Kind.Object, opcode - ASTORE_0); break;
+            case IASTORE        : genStoreIndexed(Kind.Int   ); break;
+            case LASTORE        : genStoreIndexed(Kind.Long  ); break;
+            case FASTORE        : genStoreIndexed(Kind.Float ); break;
+            case DASTORE        : genStoreIndexed(Kind.Double); break;
+            case AASTORE        : genStoreIndexed(Kind.Object); break;
+            case BASTORE        : genStoreIndexed(Kind.Byte  ); break;
+            case CASTORE        : genStoreIndexed(Kind.Char  ); break;
+            case SASTORE        : genStoreIndexed(Kind.Short ); break;
             case POP            : // fall through
             case POP2           : // fall through
             case DUP            : // fall through
@@ -1625,40 +1616,40 @@
             case SWAP           : stackOp(opcode); break;
             case IADD           : // fall through
             case ISUB           : // fall through
-            case IMUL           : genArithmeticOp(CiKind.Int, opcode, false); break;
+            case IMUL           : genArithmeticOp(Kind.Int, opcode, false); break;
             case IDIV           : // fall through
-            case IREM           : genArithmeticOp(CiKind.Int, opcode, true); break;
+            case IREM           : genArithmeticOp(Kind.Int, opcode, true); break;
             case LADD           : // fall through
             case LSUB           : // fall through
-            case LMUL           : genArithmeticOp(CiKind.Long, opcode, false); break;
+            case LMUL           : genArithmeticOp(Kind.Long, opcode, false); break;
             case LDIV           : // fall through
-            case LREM           : genArithmeticOp(CiKind.Long, opcode, true); break;
+            case LREM           : genArithmeticOp(Kind.Long, opcode, true); break;
             case FADD           : // fall through
             case FSUB           : // fall through
             case FMUL           : // fall through
             case FDIV           : // fall through
-            case FREM           : genArithmeticOp(CiKind.Float, opcode, false); break;
+            case FREM           : genArithmeticOp(Kind.Float, opcode, false); break;
             case DADD           : // fall through
             case DSUB           : // fall through
             case DMUL           : // fall through
             case DDIV           : // fall through
-            case DREM           : genArithmeticOp(CiKind.Double, opcode, false); break;
-            case INEG           : genNegateOp(CiKind.Int); break;
-            case LNEG           : genNegateOp(CiKind.Long); break;
-            case FNEG           : genNegateOp(CiKind.Float); break;
-            case DNEG           : genNegateOp(CiKind.Double); break;
+            case DREM           : genArithmeticOp(Kind.Double, opcode, false); break;
+            case INEG           : genNegateOp(Kind.Int); break;
+            case LNEG           : genNegateOp(Kind.Long); break;
+            case FNEG           : genNegateOp(Kind.Float); break;
+            case DNEG           : genNegateOp(Kind.Double); break;
             case ISHL           : // fall through
             case ISHR           : // fall through
-            case IUSHR          : genShiftOp(CiKind.Int, opcode); break;
+            case IUSHR          : genShiftOp(Kind.Int, opcode); break;
             case IAND           : // fall through
             case IOR            : // fall through
-            case IXOR           : genLogicOp(CiKind.Int, opcode); break;
+            case IXOR           : genLogicOp(Kind.Int, opcode); break;
             case LSHL           : // fall through
             case LSHR           : // fall through
-            case LUSHR          : genShiftOp(CiKind.Long, opcode); break;
+            case LUSHR          : genShiftOp(Kind.Long, opcode); break;
             case LAND           : // fall through
             case LOR            : // fall through
-            case LXOR           : genLogicOp(CiKind.Long, opcode); break;
+            case LXOR           : genLogicOp(Kind.Long, opcode); break;
             case IINC           : genIncrement(); break;
             case I2L            : genConvert(ConvertNode.Op.I2L); break;
             case I2F            : genConvert(ConvertNode.Op.I2F); break;
@@ -1675,30 +1666,30 @@
             case I2B            : genConvert(ConvertNode.Op.I2B); break;
             case I2C            : genConvert(ConvertNode.Op.I2C); break;
             case I2S            : genConvert(ConvertNode.Op.I2S); break;
-            case LCMP           : genCompareOp(CiKind.Long, false); break;
-            case FCMPL          : genCompareOp(CiKind.Float, true); break;
-            case FCMPG          : genCompareOp(CiKind.Float, false); break;
-            case DCMPL          : genCompareOp(CiKind.Double, true); break;
-            case DCMPG          : genCompareOp(CiKind.Double, false); break;
+            case LCMP           : genCompareOp(Kind.Long, false); break;
+            case FCMPL          : genCompareOp(Kind.Float, true); break;
+            case FCMPG          : genCompareOp(Kind.Float, false); break;
+            case DCMPL          : genCompareOp(Kind.Double, true); break;
+            case DCMPG          : genCompareOp(Kind.Double, false); break;
             case IFEQ           : genIfZero(Condition.EQ); break;
             case IFNE           : genIfZero(Condition.NE); break;
             case IFLT           : genIfZero(Condition.LT); break;
             case IFGE           : genIfZero(Condition.GE); break;
             case IFGT           : genIfZero(Condition.GT); break;
             case IFLE           : genIfZero(Condition.LE); break;
-            case IF_ICMPEQ      : genIfSame(CiKind.Int, Condition.EQ); break;
-            case IF_ICMPNE      : genIfSame(CiKind.Int, Condition.NE); break;
-            case IF_ICMPLT      : genIfSame(CiKind.Int, Condition.LT); break;
-            case IF_ICMPGE      : genIfSame(CiKind.Int, Condition.GE); break;
-            case IF_ICMPGT      : genIfSame(CiKind.Int, Condition.GT); break;
-            case IF_ICMPLE      : genIfSame(CiKind.Int, Condition.LE); break;
-            case IF_ACMPEQ      : genIfSame(CiKind.Object, Condition.EQ); break;
-            case IF_ACMPNE      : genIfSame(CiKind.Object, Condition.NE); break;
+            case IF_ICMPEQ      : genIfSame(Kind.Int, Condition.EQ); break;
+            case IF_ICMPNE      : genIfSame(Kind.Int, Condition.NE); break;
+            case IF_ICMPLT      : genIfSame(Kind.Int, Condition.LT); break;
+            case IF_ICMPGE      : genIfSame(Kind.Int, Condition.GE); break;
+            case IF_ICMPGT      : genIfSame(Kind.Int, Condition.GT); break;
+            case IF_ICMPLE      : genIfSame(Kind.Int, Condition.LE); break;
+            case IF_ACMPEQ      : genIfSame(Kind.Object, Condition.EQ); break;
+            case IF_ACMPNE      : genIfSame(Kind.Object, Condition.NE); break;
             case GOTO           : genGoto(); break;
             case JSR            : genJsr(stream.readBranchDest()); break;
             case RET            : genRet(stream.readLocalIndex()); break;
-            case TABLESWITCH    : genTableswitch(); break;
-            case LOOKUPSWITCH   : genLookupswitch(); break;
+            case TABLESWITCH    : genSwitch(new BytecodeTableSwitch(stream(), bci())); break;
+            case LOOKUPSWITCH   : genSwitch(new BytecodeLookupSwitch(stream(), bci())); break;
             case IRETURN        : genReturn(frameState.ipop()); break;
             case LRETURN        : genReturn(frameState.lpop()); break;
             case FRETURN        : genReturn(frameState.fpop()); break;
@@ -1728,9 +1719,9 @@
             case GOTO_W         : genGoto(); break;
             case JSR_W          : genJsr(stream.readBranchDest()); break;
             case BREAKPOINT:
-                throw new CiBailout("concurrent setting of breakpoint");
+                throw new BailoutException("concurrent setting of breakpoint");
             default:
-                throw new CiBailout("Unsupported opcode " + opcode + " (" + nameOf(opcode) + ") [bci=" + bci + "]");
+                throw new BailoutException("Unsupported opcode " + opcode + " (" + nameOf(opcode) + ") [bci=" + bci + "]");
         }
         // Checkstyle: resume
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/JsrNotSupportedBailout.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/JsrNotSupportedBailout.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.java;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
 
 
-public class JsrNotSupportedBailout extends CiBailout{
+public class JsrNotSupportedBailout extends BailoutException{
     private static final long serialVersionUID = -7476925652727154272L;
 
     public JsrNotSupportedBailout(String reason) {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/bytecode/BytecodeLookupSwitch.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.java.bytecode;
-
-/**
- * A utility for processing {@link Bytecodes#LOOKUPSWITCH} bytecodes.
- */
-public class BytecodeLookupSwitch extends BytecodeSwitch {
-    private static final int OFFSET_TO_NUMBER_PAIRS = 4;
-    private static final int OFFSET_TO_FIRST_PAIR_MATCH = 8;
-    private static final int OFFSET_TO_FIRST_PAIR_OFFSET = 12;
-    private static final int PAIR_SIZE = 8;
-
-    /**
-     * Constructor for a {@link BytecodeStream}.
-     * @param stream the {@code BytecodeStream} containing the switch instruction
-     * @param bci the index in the stream of the switch instruction
-     */
-    public BytecodeLookupSwitch(BytecodeStream stream, int bci) {
-        super(stream, bci);
-    }
-
-    @Override
-    public int defaultOffset() {
-        return stream.readInt(alignedBci);
-    }
-
-    @Override
-    public int offsetAt(int i) {
-        return stream.readInt(alignedBci + OFFSET_TO_FIRST_PAIR_OFFSET + PAIR_SIZE * i);
-    }
-
-    @Override
-    public int keyAt(int i) {
-        return stream.readInt(alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * i);
-    }
-
-    @Override
-    public int numberOfCases() {
-        return stream.readInt(alignedBci + OFFSET_TO_NUMBER_PAIRS);
-    }
-
-    @Override
-    public int size() {
-        return alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * numberOfCases() - bci;
-    }
-}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/bytecode/BytecodeStream.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.java.bytecode;
-
-
-/**
- * A utility class that makes iterating over bytecodes and reading operands
- * simpler and less error prone. For example, it handles the {@link Bytecodes#WIDE} instruction
- * and wide variants of instructions internally.
- */
-public final class BytecodeStream {
-
-    private final byte[] code;
-    private int opcode;
-    private int curBCI;
-    private int nextBCI;
-
-    /**
-     * Creates a new {@code BytecodeStream} for the specified bytecode.
-     * @param code the array of bytes that contains the bytecode
-     */
-    public BytecodeStream(byte[] code) {
-        assert code != null;
-        this.code = code;
-        setBCI(0);
-    }
-
-    /**
-     * Advances to the next bytecode.
-     */
-    public void next() {
-        setBCI(nextBCI);
-    }
-
-    /**
-     * Gets the next bytecode index (no side-effects).
-     * @return the next bytecode index
-     */
-    public int nextBCI() {
-        return nextBCI;
-    }
-
-    /**
-     * Gets the current bytecode index.
-     * @return the current bytecode index
-     */
-    public int currentBCI() {
-        return curBCI;
-    }
-
-    /**
-     * Gets the bytecode index of the end of the code.
-     * @return the index of the end of the code
-     */
-    public int endBCI() {
-        return code.length;
-    }
-
-    /**
-     * Gets the current opcode. This method will never return the
-     * {@link Bytecodes#WIDE WIDE} opcode, but will instead
-     * return the opcode that is modified by the {@code WIDE} opcode.
-     * @return the current opcode; {@link Bytecodes#END} if at or beyond the end of the code
-     */
-    public int currentBC() {
-        if (opcode == Bytecodes.WIDE) {
-            return Bytes.beU1(code, curBCI + 1);
-        } else {
-            return opcode;
-        }
-    }
-
-    /**
-     * Reads the index of a local variable for one of the load or store instructions.
-     * The WIDE modifier is handled internally.
-     * @return the index of the local variable
-     */
-    public int readLocalIndex() {
-        // read local variable index for load/store
-        if (opcode == Bytecodes.WIDE) {
-            return Bytes.beU2(code, curBCI + 2);
-        }
-        return Bytes.beU1(code, curBCI + 1);
-    }
-
-    /**
-     * Read the delta for an {@link Bytecodes#IINC} bytecode.
-     * @return the delta for the {@code IINC}
-     */
-    public int readIncrement() {
-        // read the delta for the iinc bytecode
-        if (opcode == Bytecodes.WIDE) {
-            return Bytes.beS2(code, curBCI + 4);
-        }
-        return Bytes.beS1(code, curBCI + 2);
-    }
-
-    /**
-     * Read the destination of a {@link Bytecodes#GOTO} or {@code IF} instructions.
-     * @return the destination bytecode index
-     */
-    public int readBranchDest() {
-        // reads the destination for a branch bytecode
-        if (opcode == Bytecodes.GOTO_W || opcode == Bytecodes.JSR_W) {
-            return curBCI + Bytes.beS4(code, curBCI + 1);
-        } else {
-            return curBCI + Bytes.beS2(code, curBCI + 1);
-        }
-    }
-
-    /**
-     * Read a signed 4-byte integer from the bytecode stream at the specified bytecode index.
-     * @param bci the bytecode index
-     * @return the integer value
-     */
-    public int readInt(int bci) {
-        // reads a 4-byte signed value
-        return Bytes.beS4(code, bci);
-    }
-
-    /**
-     * Reads an unsigned, 1-byte value from the bytecode stream at the specified bytecode index.
-     * @param bci the bytecode index
-     * @return the byte
-     */
-    public int readUByte(int bci) {
-        return Bytes.beU1(code, bci);
-    }
-
-    /**
-     * Reads a constant pool index for the current instruction.
-     * @return the constant pool index
-     */
-    public char readCPI() {
-        if (opcode == Bytecodes.LDC) {
-            return (char) Bytes.beU1(code, curBCI + 1);
-        }
-        return (char) Bytes.beU2(code, curBCI + 1);
-    }
-
-    /**
-     * Reads a signed, 1-byte value for the current instruction (e.g. BIPUSH).
-     * @return the byte
-     */
-    public byte readByte() {
-        return code[curBCI + 1];
-    }
-
-    /**
-     * Reads a signed, 2-byte short for the current instruction (e.g. SIPUSH).
-     * @return the short value
-     */
-    public short readShort() {
-        return (short) Bytes.beS2(code, curBCI + 1);
-    }
-
-    /**
-     * Sets the bytecode index to the specified value.
-     * If {@code bci} is beyond the end of the array, {@link #currentBC} will return
-     * {@link Bytecodes#END} and other methods may throw {@link ArrayIndexOutOfBoundsException}.
-     * @param bci the new bytecode index
-     */
-    public void setBCI(int bci) {
-        curBCI = bci;
-        if (curBCI < code.length) {
-            opcode = Bytes.beU1(code, bci);
-            assert opcode < Bytecodes.BREAKPOINT : "illegal bytecode";
-            nextBCI = bci + lengthOf();
-        } else {
-            opcode = Bytecodes.END;
-            nextBCI = curBCI;
-        }
-    }
-
-    /**
-     * Gets the length of the current bytecode.
-     */
-    private int lengthOf() {
-        int length = Bytecodes.lengthOf(opcode);
-        if (length == 0) {
-            switch (opcode) {
-                case Bytecodes.TABLESWITCH: {
-                    return new BytecodeTableSwitch(this, curBCI).size();
-                }
-                case Bytecodes.LOOKUPSWITCH: {
-                    return new BytecodeLookupSwitch(this, curBCI).size();
-                }
-                case Bytecodes.WIDE: {
-                    int opc = Bytes.beU1(code, curBCI + 1);
-                    if (opc == Bytecodes.RET) {
-                        return 4;
-                    } else if (opc == Bytecodes.IINC) {
-                        return 6;
-                    } else {
-                        return 4; // a load or store bytecode
-                    }
-                }
-                default:
-                    throw new Error("unknown variable-length bytecode: " + opcode);
-            }
-        }
-        return length;
-    }
-}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/bytecode/BytecodeSwitch.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.java.bytecode;
-
-/**
- * An abstract class that provides the state and methods common to {@link Bytecodes#LOOKUPSWITCH}
- * and {@link Bytecodes#TABLESWITCH} instructions.
- */
-public abstract class BytecodeSwitch {
-    /**
-     * The {@link BytecodeStream} containing the bytecode array.
-     */
-    protected final BytecodeStream stream;
-    /**
-     * Index of start of switch instruction.
-     */
-    protected final int bci;
-    /**
-     * Index of the start of the additional data for the switch instruction, aligned to a multiple of four from the method start.
-     */
-    protected final int alignedBci;
-
-    /**
-     * Constructor for a {@link BytecodeStream}.
-     * @param stream the {@code BytecodeStream} containing the switch instruction
-     * @param bci the index in the stream of the switch instruction
-     */
-    public BytecodeSwitch(BytecodeStream stream, int bci) {
-        this.stream = stream;
-        this.bci = bci;
-        this.alignedBci = (bci + 4) & 0xfffffffc;
-    }
-
-    /**
-     * Gets the current bytecode index.
-     * @return the current bytecode index
-     */
-    public int bci() {
-        return bci;
-    }
-
-    /**
-     * Gets the index of the instruction denoted by the {@code i}'th switch target.
-     * @param i index of the switch target
-     * @return the index of the instruction denoted by the {@code i}'th switch target
-     */
-    public int targetAt(int i) {
-        return bci + offsetAt(i);
-    }
-
-    /**
-     * Gets the index of the instruction for the default switch target.
-     * @return the index of the instruction for the default switch target
-     */
-    public int defaultTarget() {
-        return bci + defaultOffset();
-    }
-
-    /**
-     * Gets the offset from the start of the switch instruction to the default switch target.
-     * @return the offset to the default switch target
-     */
-    public abstract int defaultOffset();
-
-    /**
-     * Gets the key at {@code i}'th switch target index.
-     * @param i the switch target index
-     * @return the key at {@code i}'th switch target index
-     */
-    public abstract int keyAt(int i);
-
-    /**
-     * Gets the offset from the start of the switch instruction for the {@code i}'th switch target.
-     * @param i the switch target index
-     * @return the offset to the {@code i}'th switch target
-     */
-    public abstract int offsetAt(int i);
-
-    /**
-     * Gets the number of switch targets.
-     * @return the number of switch targets
-     */
-    public abstract int numberOfCases();
-
-    /**
-     * Gets the total size in bytes of the switch instruction.
-     * @return the total size in bytes of the switch instruction
-     */
-    public abstract int size();
-}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/bytecode/BytecodeTableSwitch.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.java.bytecode;
-
-/**
- * A utility for processing {@link Bytecodes#TABLESWITCH} bytecodes.
- */
-public class BytecodeTableSwitch extends BytecodeSwitch {
-    private static final int OFFSET_TO_LOW_KEY = 4;
-    private static final int OFFSET_TO_HIGH_KEY = 8;
-    private static final int OFFSET_TO_FIRST_JUMP_OFFSET = 12;
-    private static final int JUMP_OFFSET_SIZE = 4;
-
-    /**
-     * Constructor for a {@link BytecodeStream}.
-     * @param stream the {@code BytecodeStream} containing the switch instruction
-     * @param bci the index in the stream of the switch instruction
-     */
-    public BytecodeTableSwitch(BytecodeStream stream, int bci) {
-        super(stream, bci);
-    }
-
-    /**
-     * Gets the low key of the table switch.
-     * @return the low key
-     */
-    public int lowKey() {
-        return stream.readInt(alignedBci + OFFSET_TO_LOW_KEY);
-    }
-
-    /**
-     * Gets the high key of the table switch.
-     * @return the high key
-     */
-    public int highKey() {
-        return stream.readInt(alignedBci + OFFSET_TO_HIGH_KEY);
-    }
-
-    @Override
-    public int keyAt(int i) {
-        return lowKey() + i;
-    }
-
-    @Override
-    public int defaultOffset() {
-        return stream.readInt(alignedBci);
-    }
-
-    @Override
-    public int offsetAt(int i) {
-        return stream.readInt(alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * i);
-    }
-
-    @Override
-    public int numberOfCases() {
-        return highKey() - lowKey() + 1;
-    }
-
-    @Override
-    public int size() {
-        return alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * numberOfCases() - bci;
-    }
-}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/bytecode/Bytecodes.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,940 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.java.bytecode;
-
-import static com.oracle.graal.java.bytecode.Bytecodes.Flags.*;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.regex.*;
-
-/**
- * The definitions of the bytecodes that are valid input to the compiler and
- * related utility methods. This comprises two groups: the standard Java
- * bytecodes defined by <a href=
- * "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html">
- * Java Virtual Machine Specification</a>, and a set of <i>extended</i>
- * bytecodes that support low-level programming, for example, memory barriers.
- *
- * The extended bytecodes are one or three bytes in size. The one-byte bytecodes
- * follow the values in the standard set, with no gap. The three-byte extended
- * bytecodes share a common first byte and carry additional instruction-specific
- * information in the second and third bytes.
- */
-public class Bytecodes {
-    public static final int NOP                  =   0; // 0x00
-    public static final int ACONST_NULL          =   1; // 0x01
-    public static final int ICONST_M1            =   2; // 0x02
-    public static final int ICONST_0             =   3; // 0x03
-    public static final int ICONST_1             =   4; // 0x04
-    public static final int ICONST_2             =   5; // 0x05
-    public static final int ICONST_3             =   6; // 0x06
-    public static final int ICONST_4             =   7; // 0x07
-    public static final int ICONST_5             =   8; // 0x08
-    public static final int LCONST_0             =   9; // 0x09
-    public static final int LCONST_1             =  10; // 0x0A
-    public static final int FCONST_0             =  11; // 0x0B
-    public static final int FCONST_1             =  12; // 0x0C
-    public static final int FCONST_2             =  13; // 0x0D
-    public static final int DCONST_0             =  14; // 0x0E
-    public static final int DCONST_1             =  15; // 0x0F
-    public static final int BIPUSH               =  16; // 0x10
-    public static final int SIPUSH               =  17; // 0x11
-    public static final int LDC                  =  18; // 0x12
-    public static final int LDC_W                =  19; // 0x13
-    public static final int LDC2_W               =  20; // 0x14
-    public static final int ILOAD                =  21; // 0x15
-    public static final int LLOAD                =  22; // 0x16
-    public static final int FLOAD                =  23; // 0x17
-    public static final int DLOAD                =  24; // 0x18
-    public static final int ALOAD                =  25; // 0x19
-    public static final int ILOAD_0              =  26; // 0x1A
-    public static final int ILOAD_1              =  27; // 0x1B
-    public static final int ILOAD_2              =  28; // 0x1C
-    public static final int ILOAD_3              =  29; // 0x1D
-    public static final int LLOAD_0              =  30; // 0x1E
-    public static final int LLOAD_1              =  31; // 0x1F
-    public static final int LLOAD_2              =  32; // 0x20
-    public static final int LLOAD_3              =  33; // 0x21
-    public static final int FLOAD_0              =  34; // 0x22
-    public static final int FLOAD_1              =  35; // 0x23
-    public static final int FLOAD_2              =  36; // 0x24
-    public static final int FLOAD_3              =  37; // 0x25
-    public static final int DLOAD_0              =  38; // 0x26
-    public static final int DLOAD_1              =  39; // 0x27
-    public static final int DLOAD_2              =  40; // 0x28
-    public static final int DLOAD_3              =  41; // 0x29
-    public static final int ALOAD_0              =  42; // 0x2A
-    public static final int ALOAD_1              =  43; // 0x2B
-    public static final int ALOAD_2              =  44; // 0x2C
-    public static final int ALOAD_3              =  45; // 0x2D
-    public static final int IALOAD               =  46; // 0x2E
-    public static final int LALOAD               =  47; // 0x2F
-    public static final int FALOAD               =  48; // 0x30
-    public static final int DALOAD               =  49; // 0x31
-    public static final int AALOAD               =  50; // 0x32
-    public static final int BALOAD               =  51; // 0x33
-    public static final int CALOAD               =  52; // 0x34
-    public static final int SALOAD               =  53; // 0x35
-    public static final int ISTORE               =  54; // 0x36
-    public static final int LSTORE               =  55; // 0x37
-    public static final int FSTORE               =  56; // 0x38
-    public static final int DSTORE               =  57; // 0x39
-    public static final int ASTORE               =  58; // 0x3A
-    public static final int ISTORE_0             =  59; // 0x3B
-    public static final int ISTORE_1             =  60; // 0x3C
-    public static final int ISTORE_2             =  61; // 0x3D
-    public static final int ISTORE_3             =  62; // 0x3E
-    public static final int LSTORE_0             =  63; // 0x3F
-    public static final int LSTORE_1             =  64; // 0x40
-    public static final int LSTORE_2             =  65; // 0x41
-    public static final int LSTORE_3             =  66; // 0x42
-    public static final int FSTORE_0             =  67; // 0x43
-    public static final int FSTORE_1             =  68; // 0x44
-    public static final int FSTORE_2             =  69; // 0x45
-    public static final int FSTORE_3             =  70; // 0x46
-    public static final int DSTORE_0             =  71; // 0x47
-    public static final int DSTORE_1             =  72; // 0x48
-    public static final int DSTORE_2             =  73; // 0x49
-    public static final int DSTORE_3             =  74; // 0x4A
-    public static final int ASTORE_0             =  75; // 0x4B
-    public static final int ASTORE_1             =  76; // 0x4C
-    public static final int ASTORE_2             =  77; // 0x4D
-    public static final int ASTORE_3             =  78; // 0x4E
-    public static final int IASTORE              =  79; // 0x4F
-    public static final int LASTORE              =  80; // 0x50
-    public static final int FASTORE              =  81; // 0x51
-    public static final int DASTORE              =  82; // 0x52
-    public static final int AASTORE              =  83; // 0x53
-    public static final int BASTORE              =  84; // 0x54
-    public static final int CASTORE              =  85; // 0x55
-    public static final int SASTORE              =  86; // 0x56
-    public static final int POP                  =  87; // 0x57
-    public static final int POP2                 =  88; // 0x58
-    public static final int DUP                  =  89; // 0x59
-    public static final int DUP_X1               =  90; // 0x5A
-    public static final int DUP_X2               =  91; // 0x5B
-    public static final int DUP2                 =  92; // 0x5C
-    public static final int DUP2_X1              =  93; // 0x5D
-    public static final int DUP2_X2              =  94; // 0x5E
-    public static final int SWAP                 =  95; // 0x5F
-    public static final int IADD                 =  96; // 0x60
-    public static final int LADD                 =  97; // 0x61
-    public static final int FADD                 =  98; // 0x62
-    public static final int DADD                 =  99; // 0x63
-    public static final int ISUB                 = 100; // 0x64
-    public static final int LSUB                 = 101; // 0x65
-    public static final int FSUB                 = 102; // 0x66
-    public static final int DSUB                 = 103; // 0x67
-    public static final int IMUL                 = 104; // 0x68
-    public static final int LMUL                 = 105; // 0x69
-    public static final int FMUL                 = 106; // 0x6A
-    public static final int DMUL                 = 107; // 0x6B
-    public static final int IDIV                 = 108; // 0x6C
-    public static final int LDIV                 = 109; // 0x6D
-    public static final int FDIV                 = 110; // 0x6E
-    public static final int DDIV                 = 111; // 0x6F
-    public static final int IREM                 = 112; // 0x70
-    public static final int LREM                 = 113; // 0x71
-    public static final int FREM                 = 114; // 0x72
-    public static final int DREM                 = 115; // 0x73
-    public static final int INEG                 = 116; // 0x74
-    public static final int LNEG                 = 117; // 0x75
-    public static final int FNEG                 = 118; // 0x76
-    public static final int DNEG                 = 119; // 0x77
-    public static final int ISHL                 = 120; // 0x78
-    public static final int LSHL                 = 121; // 0x79
-    public static final int ISHR                 = 122; // 0x7A
-    public static final int LSHR                 = 123; // 0x7B
-    public static final int IUSHR                = 124; // 0x7C
-    public static final int LUSHR                = 125; // 0x7D
-    public static final int IAND                 = 126; // 0x7E
-    public static final int LAND                 = 127; // 0x7F
-    public static final int IOR                  = 128; // 0x80
-    public static final int LOR                  = 129; // 0x81
-    public static final int IXOR                 = 130; // 0x82
-    public static final int LXOR                 = 131; // 0x83
-    public static final int IINC                 = 132; // 0x84
-    public static final int I2L                  = 133; // 0x85
-    public static final int I2F                  = 134; // 0x86
-    public static final int I2D                  = 135; // 0x87
-    public static final int L2I                  = 136; // 0x88
-    public static final int L2F                  = 137; // 0x89
-    public static final int L2D                  = 138; // 0x8A
-    public static final int F2I                  = 139; // 0x8B
-    public static final int F2L                  = 140; // 0x8C
-    public static final int F2D                  = 141; // 0x8D
-    public static final int D2I                  = 142; // 0x8E
-    public static final int D2L                  = 143; // 0x8F
-    public static final int D2F                  = 144; // 0x90
-    public static final int I2B                  = 145; // 0x91
-    public static final int I2C                  = 146; // 0x92
-    public static final int I2S                  = 147; // 0x93
-    public static final int LCMP                 = 148; // 0x94
-    public static final int FCMPL                = 149; // 0x95
-    public static final int FCMPG                = 150; // 0x96
-    public static final int DCMPL                = 151; // 0x97
-    public static final int DCMPG                = 152; // 0x98
-    public static final int IFEQ                 = 153; // 0x99
-    public static final int IFNE                 = 154; // 0x9A
-    public static final int IFLT                 = 155; // 0x9B
-    public static final int IFGE                 = 156; // 0x9C
-    public static final int IFGT                 = 157; // 0x9D
-    public static final int IFLE                 = 158; // 0x9E
-    public static final int IF_ICMPEQ            = 159; // 0x9F
-    public static final int IF_ICMPNE            = 160; // 0xA0
-    public static final int IF_ICMPLT            = 161; // 0xA1
-    public static final int IF_ICMPGE            = 162; // 0xA2
-    public static final int IF_ICMPGT            = 163; // 0xA3
-    public static final int IF_ICMPLE            = 164; // 0xA4
-    public static final int IF_ACMPEQ            = 165; // 0xA5
-    public static final int IF_ACMPNE            = 166; // 0xA6
-    public static final int GOTO                 = 167; // 0xA7
-    public static final int JSR                  = 168; // 0xA8
-    public static final int RET                  = 169; // 0xA9
-    public static final int TABLESWITCH          = 170; // 0xAA
-    public static final int LOOKUPSWITCH         = 171; // 0xAB
-    public static final int IRETURN              = 172; // 0xAC
-    public static final int LRETURN              = 173; // 0xAD
-    public static final int FRETURN              = 174; // 0xAE
-    public static final int DRETURN              = 175; // 0xAF
-    public static final int ARETURN              = 176; // 0xB0
-    public static final int RETURN               = 177; // 0xB1
-    public static final int GETSTATIC            = 178; // 0xB2
-    public static final int PUTSTATIC            = 179; // 0xB3
-    public static final int GETFIELD             = 180; // 0xB4
-    public static final int PUTFIELD             = 181; // 0xB5
-    public static final int INVOKEVIRTUAL        = 182; // 0xB6
-    public static final int INVOKESPECIAL        = 183; // 0xB7
-    public static final int INVOKESTATIC         = 184; // 0xB8
-    public static final int INVOKEINTERFACE      = 185; // 0xB9
-    public static final int XXXUNUSEDXXX         = 186; // 0xBA
-    public static final int NEW                  = 187; // 0xBB
-    public static final int NEWARRAY             = 188; // 0xBC
-    public static final int ANEWARRAY            = 189; // 0xBD
-    public static final int ARRAYLENGTH          = 190; // 0xBE
-    public static final int ATHROW               = 191; // 0xBF
-    public static final int CHECKCAST            = 192; // 0xC0
-    public static final int INSTANCEOF           = 193; // 0xC1
-    public static final int MONITORENTER         = 194; // 0xC2
-    public static final int MONITOREXIT          = 195; // 0xC3
-    public static final int WIDE                 = 196; // 0xC4
-    public static final int MULTIANEWARRAY       = 197; // 0xC5
-    public static final int IFNULL               = 198; // 0xC6
-    public static final int IFNONNULL            = 199; // 0xC7
-    public static final int GOTO_W               = 200; // 0xC8
-    public static final int JSR_W                = 201; // 0xC9
-    public static final int BREAKPOINT           = 202; // 0xCA
-
-    public static final int ILLEGAL = 255;
-    public static final int END = 256;
-
-    /**
-     * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes:
-     * <pre>
-     *     for (int opcode = 0; opcode <= Bytecodes.LAST_JVM_OPCODE; ++opcode) {
-     *         //
-     *     }
-     * </pre>
-     */
-    public static final int LAST_JVM_OPCODE = JSR_W;
-
-    /**
-     * A collection of flags describing various bytecode attributes.
-     */
-    static class Flags {
-
-        /**
-         * Denotes an instruction that ends a basic block and does not let control flow fall through to its lexical successor.
-         */
-        static final int STOP = 0x00000001;
-
-        /**
-         * Denotes an instruction that ends a basic block and may let control flow fall through to its lexical successor.
-         * In practice this means it is a conditional branch.
-         */
-        static final int FALL_THROUGH = 0x00000002;
-
-        /**
-         * Denotes an instruction that has a 2 or 4 byte operand that is an offset to another instruction in the same method.
-         * This does not include the {@link Bytecodes#TABLESWITCH} or {@link Bytecodes#LOOKUPSWITCH} instructions.
-         */
-        static final int BRANCH = 0x00000004;
-
-        /**
-         * Denotes an instruction that reads the value of a static or instance field.
-         */
-        static final int FIELD_READ = 0x00000008;
-
-        /**
-         * Denotes an instruction that writes the value of a static or instance field.
-         */
-        static final int FIELD_WRITE = 0x00000010;
-
-        /**
-         * Denotes an instruction that is not defined in the JVM specification.
-         */
-        static final int EXTENSION = 0x00000020;
-
-        /**
-         * Denotes an instruction that can cause a trap.
-         */
-        static final int TRAP        = 0x00000080;
-        /**
-         * Denotes an instruction that is commutative.
-         */
-        static final int COMMUTATIVE = 0x00000100;
-        /**
-         * Denotes an instruction that is associative.
-         */
-        static final int ASSOCIATIVE = 0x00000200;
-        /**
-         * Denotes an instruction that loads an operand.
-         */
-        static final int LOAD        = 0x00000400;
-        /**
-         * Denotes an instruction that stores an operand.
-         */
-        static final int STORE       = 0x00000800;
-        /**
-         * Denotes the 4 INVOKE* instructions.
-         */
-        static final int INVOKE       = 0x00001000;
-    }
-
-    // Performs a sanity check that none of the flags overlap.
-    static {
-        int allFlags = 0;
-        try {
-            for (Field field : Flags.class.getDeclaredFields()) {
-                int flagsFilter = Modifier.FINAL | Modifier.STATIC;
-                if ((field.getModifiers() & flagsFilter) == flagsFilter && !field.isSynthetic()) {
-                    assert field.getType() == int.class : "Field is not int : " + field;
-                    final int flag = field.getInt(null);
-                    assert flag != 0;
-                    assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag";
-                    allFlags |= flag;
-                }
-            }
-        } catch (Exception e) {
-            throw new InternalError(e.toString());
-        }
-    }
-
-    /**
-     * An array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic.
-     * This will include the root instruction for the three-byte extended instructions.
-     */
-    private static final String[] nameArray = new String[256];
-
-    /**
-     * An array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction.
-     */
-    private static final int[] flagsArray = new int[256];
-
-    /**
-     * An array that maps from a bytecode value to the length in bytes for the corresponding instruction.
-     */
-    private static final int[] lengthArray = new int[256];
-
-    /**
-     * An array that maps from a bytecode value to the estimated complexity of the bytecode in terms of generated machine code.
-     */
-    private static final int[] compilationComplexityArray = new int[256];
-
-    // Checkstyle: stop
-    static {
-        def(NOP                 , "nop"             , "b"    , 0);
-        def(ACONST_NULL         , "aconst_null"     , "b"    , 0);
-        def(ICONST_M1           , "iconst_m1"       , "b"    , 0);
-        def(ICONST_0            , "iconst_0"        , "b"    , 0);
-        def(ICONST_1            , "iconst_1"        , "b"    , 0);
-        def(ICONST_2            , "iconst_2"        , "b"    , 0);
-        def(ICONST_3            , "iconst_3"        , "b"    , 0);
-        def(ICONST_4            , "iconst_4"        , "b"    , 0);
-        def(ICONST_5            , "iconst_5"        , "b"    , 0);
-        def(LCONST_0            , "lconst_0"        , "b"    , 0);
-        def(LCONST_1            , "lconst_1"        , "b"    , 0);
-        def(FCONST_0            , "fconst_0"        , "b"    , 0);
-        def(FCONST_1            , "fconst_1"        , "b"    , 0);
-        def(FCONST_2            , "fconst_2"        , "b"    , 0);
-        def(DCONST_0            , "dconst_0"        , "b"    , 0);
-        def(DCONST_1            , "dconst_1"        , "b"    , 0);
-        def(BIPUSH              , "bipush"          , "bc"   , 0);
-        def(SIPUSH              , "sipush"          , "bcc"  , 0);
-        def(LDC                 , "ldc"             , "bi"   , 0, TRAP);
-        def(LDC_W               , "ldc_w"           , "bii"  , 0, TRAP);
-        def(LDC2_W              , "ldc2_w"          , "bii"  , 0, TRAP);
-        def(ILOAD               , "iload"           , "bi"   , 0, LOAD);
-        def(LLOAD               , "lload"           , "bi"   , 0, LOAD);
-        def(FLOAD               , "fload"           , "bi"   , 0, LOAD);
-        def(DLOAD               , "dload"           , "bi"   , 0, LOAD);
-        def(ALOAD               , "aload"           , "bi"   , 0, LOAD);
-        def(ILOAD_0             , "iload_0"         , "b"    , 0, LOAD);
-        def(ILOAD_1             , "iload_1"         , "b"    , 0, LOAD);
-        def(ILOAD_2             , "iload_2"         , "b"    , 0, LOAD);
-        def(ILOAD_3             , "iload_3"         , "b"    , 0, LOAD);
-        def(LLOAD_0             , "lload_0"         , "b"    , 0, LOAD);
-        def(LLOAD_1             , "lload_1"         , "b"    , 0, LOAD);
-        def(LLOAD_2             , "lload_2"         , "b"    , 0, LOAD);
-        def(LLOAD_3             , "lload_3"         , "b"    , 0, LOAD);
-        def(FLOAD_0             , "fload_0"         , "b"    , 0, LOAD);
-        def(FLOAD_1             , "fload_1"         , "b"    , 0, LOAD);
-        def(FLOAD_2             , "fload_2"         , "b"    , 0, LOAD);
-        def(FLOAD_3             , "fload_3"         , "b"    , 0, LOAD);
-        def(DLOAD_0             , "dload_0"         , "b"    , 0, LOAD);
-        def(DLOAD_1             , "dload_1"         , "b"    , 0, LOAD);
-        def(DLOAD_2             , "dload_2"         , "b"    , 0, LOAD);
-        def(DLOAD_3             , "dload_3"         , "b"    , 0, LOAD);
-        def(ALOAD_0             , "aload_0"         , "b"    , 0, LOAD);
-        def(ALOAD_1             , "aload_1"         , "b"    , 0, LOAD);
-        def(ALOAD_2             , "aload_2"         , "b"    , 0, LOAD);
-        def(ALOAD_3             , "aload_3"         , "b"    , 0, LOAD);
-        def(IALOAD              , "iaload"          , "b"    , 0, TRAP);
-        def(LALOAD              , "laload"          , "b"    , 0, TRAP);
-        def(FALOAD              , "faload"          , "b"    , 0, TRAP);
-        def(DALOAD              , "daload"          , "b"    , 0, TRAP);
-        def(AALOAD              , "aaload"          , "b"    , 0, TRAP);
-        def(BALOAD              , "baload"          , "b"    , 0, TRAP);
-        def(CALOAD              , "caload"          , "b"    , 0, TRAP);
-        def(SALOAD              , "saload"          , "b"    , 0, TRAP);
-        def(ISTORE              , "istore"          , "bi"   , 0, STORE);
-        def(LSTORE              , "lstore"          , "bi"   , 0, STORE);
-        def(FSTORE              , "fstore"          , "bi"   , 0, STORE);
-        def(DSTORE              , "dstore"          , "bi"   , 0, STORE);
-        def(ASTORE              , "astore"          , "bi"   , 0, STORE);
-        def(ISTORE_0            , "istore_0"        , "b"    , 0, STORE);
-        def(ISTORE_1            , "istore_1"        , "b"    , 0, STORE);
-        def(ISTORE_2            , "istore_2"        , "b"    , 0, STORE);
-        def(ISTORE_3            , "istore_3"        , "b"    , 0, STORE);
-        def(LSTORE_0            , "lstore_0"        , "b"    , 0, STORE);
-        def(LSTORE_1            , "lstore_1"        , "b"    , 0, STORE);
-        def(LSTORE_2            , "lstore_2"        , "b"    , 0, STORE);
-        def(LSTORE_3            , "lstore_3"        , "b"    , 0, STORE);
-        def(FSTORE_0            , "fstore_0"        , "b"    , 0, STORE);
-        def(FSTORE_1            , "fstore_1"        , "b"    , 0, STORE);
-        def(FSTORE_2            , "fstore_2"        , "b"    , 0, STORE);
-        def(FSTORE_3            , "fstore_3"        , "b"    , 0, STORE);
-        def(DSTORE_0            , "dstore_0"        , "b"    , 0, STORE);
-        def(DSTORE_1            , "dstore_1"        , "b"    , 0, STORE);
-        def(DSTORE_2            , "dstore_2"        , "b"    , 0, STORE);
-        def(DSTORE_3            , "dstore_3"        , "b"    , 0, STORE);
-        def(ASTORE_0            , "astore_0"        , "b"    , 0, STORE);
-        def(ASTORE_1            , "astore_1"        , "b"    , 0, STORE);
-        def(ASTORE_2            , "astore_2"        , "b"    , 0, STORE);
-        def(ASTORE_3            , "astore_3"        , "b"    , 0, STORE);
-        def(IASTORE             , "iastore"         , "b"    , 3, TRAP);
-        def(LASTORE             , "lastore"         , "b"    , 3, TRAP);
-        def(FASTORE             , "fastore"         , "b"    , 3, TRAP);
-        def(DASTORE             , "dastore"         , "b"    , 3, TRAP);
-        def(AASTORE             , "aastore"         , "b"    , 4, TRAP);
-        def(BASTORE             , "bastore"         , "b"    , 3, TRAP);
-        def(CASTORE             , "castore"         , "b"    , 3, TRAP);
-        def(SASTORE             , "sastore"         , "b"    , 3, TRAP);
-        def(POP                 , "pop"             , "b"    , 0);
-        def(POP2                , "pop2"            , "b"    , 0);
-        def(DUP                 , "dup"             , "b"    , 0);
-        def(DUP_X1              , "dup_x1"          , "b"    , 0);
-        def(DUP_X2              , "dup_x2"          , "b"    , 0);
-        def(DUP2                , "dup2"            , "b"    , 0);
-        def(DUP2_X1             , "dup2_x1"         , "b"    , 0);
-        def(DUP2_X2             , "dup2_x2"         , "b"    , 0);
-        def(SWAP                , "swap"            , "b"    , 0);
-        def(IADD                , "iadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(LADD                , "ladd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(FADD                , "fadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(DADD                , "dadd"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(ISUB                , "isub"            , "b"    , 1);
-        def(LSUB                , "lsub"            , "b"    , 1);
-        def(FSUB                , "fsub"            , "b"    , 1);
-        def(DSUB                , "dsub"            , "b"    , 1);
-        def(IMUL                , "imul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(LMUL                , "lmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(FMUL                , "fmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(DMUL                , "dmul"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(IDIV                , "idiv"            , "b"    , 1, TRAP);
-        def(LDIV                , "ldiv"            , "b"    , 1, TRAP);
-        def(FDIV                , "fdiv"            , "b"    , 1);
-        def(DDIV                , "ddiv"            , "b"    , 1);
-        def(IREM                , "irem"            , "b"    , 1, TRAP);
-        def(LREM                , "lrem"            , "b"    , 1, TRAP);
-        def(FREM                , "frem"            , "b"    , 1);
-        def(DREM                , "drem"            , "b"    , 1);
-        def(INEG                , "ineg"            , "b"    , 1);
-        def(LNEG                , "lneg"            , "b"    , 1);
-        def(FNEG                , "fneg"            , "b"    , 1);
-        def(DNEG                , "dneg"            , "b"    , 1);
-        def(ISHL                , "ishl"            , "b"    , 1);
-        def(LSHL                , "lshl"            , "b"    , 1);
-        def(ISHR                , "ishr"            , "b"    , 1);
-        def(LSHR                , "lshr"            , "b"    , 1);
-        def(IUSHR               , "iushr"           , "b"    , 1);
-        def(LUSHR               , "lushr"           , "b"    , 1);
-        def(IAND                , "iand"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(LAND                , "land"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(IOR                 , "ior"             , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(LOR                 , "lor"             , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(IXOR                , "ixor"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(LXOR                , "lxor"            , "b"    , 1, COMMUTATIVE | ASSOCIATIVE);
-        def(IINC                , "iinc"            , "bic"  , 1, LOAD | STORE);
-        def(I2L                 , "i2l"             , "b"    , 1);
-        def(I2F                 , "i2f"             , "b"    , 1);
-        def(I2D                 , "i2d"             , "b"    , 1);
-        def(L2I                 , "l2i"             , "b"    , 1);
-        def(L2F                 , "l2f"             , "b"    , 1);
-        def(L2D                 , "l2d"             , "b"    , 1);
-        def(F2I                 , "f2i"             , "b"    , 1);
-        def(F2L                 , "f2l"             , "b"    , 1);
-        def(F2D                 , "f2d"             , "b"    , 1);
-        def(D2I                 , "d2i"             , "b"    , 1);
-        def(D2L                 , "d2l"             , "b"    , 1);
-        def(D2F                 , "d2f"             , "b"    , 1);
-        def(I2B                 , "i2b"             , "b"    , 1);
-        def(I2C                 , "i2c"             , "b"    , 1);
-        def(I2S                 , "i2s"             , "b"    , 1);
-        def(LCMP                , "lcmp"            , "b"    , 1);
-        def(FCMPL               , "fcmpl"           , "b"    , 1);
-        def(FCMPG               , "fcmpg"           , "b"    , 1);
-        def(DCMPL               , "dcmpl"           , "b"    , 1);
-        def(DCMPG               , "dcmpg"           , "b"    , 1);
-        def(IFEQ                , "ifeq"            , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IFNE                , "ifne"            , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IFLT                , "iflt"            , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IFGE                , "ifge"            , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IFGT                , "ifgt"            , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IFLE                , "ifle"            , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IF_ICMPEQ           , "if_icmpeq"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ICMPNE           , "if_icmpne"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ICMPLT           , "if_icmplt"       , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IF_ICMPGE           , "if_icmpge"       , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IF_ICMPGT           , "if_icmpgt"       , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IF_ICMPLE           , "if_icmple"       , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IF_ACMPEQ           , "if_acmpeq"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(IF_ACMPNE           , "if_acmpne"       , "boo"  , 2, COMMUTATIVE | FALL_THROUGH | BRANCH);
-        def(GOTO                , "goto"            , "boo"  , 1, STOP | BRANCH);
-        def(JSR                 , "jsr"             , "boo"  , 0, STOP | BRANCH);
-        def(RET                 , "ret"             , "bi"   , 0, STOP);
-        def(TABLESWITCH         , "tableswitch"     , ""     , 4, STOP);
-        def(LOOKUPSWITCH        , "lookupswitch"    , ""     , 4, STOP);
-        def(IRETURN             , "ireturn"         , "b"    , 1, TRAP | STOP);
-        def(LRETURN             , "lreturn"         , "b"    , 1, TRAP | STOP);
-        def(FRETURN             , "freturn"         , "b"    , 1, TRAP | STOP);
-        def(DRETURN             , "dreturn"         , "b"    , 1, TRAP | STOP);
-        def(ARETURN             , "areturn"         , "b"    , 1, TRAP | STOP);
-        def(RETURN              , "return"          , "b"    , 1, TRAP | STOP);
-        def(GETSTATIC           , "getstatic"       , "bjj"  , 2, TRAP | FIELD_READ);
-        def(PUTSTATIC           , "putstatic"       , "bjj"  , 2, TRAP | FIELD_WRITE);
-        def(GETFIELD            , "getfield"        , "bjj"  , 2, TRAP | FIELD_READ);
-        def(PUTFIELD            , "putfield"        , "bjj"  , 2, TRAP | FIELD_WRITE);
-        def(INVOKEVIRTUAL       , "invokevirtual"   , "bjj"  , 7, TRAP | INVOKE);
-        def(INVOKESPECIAL       , "invokespecial"   , "bjj"  , 5, TRAP | INVOKE);
-        def(INVOKESTATIC        , "invokestatic"    , "bjj"  , 5, TRAP | INVOKE);
-        def(INVOKEINTERFACE     , "invokeinterface" , "bjja_", 7, TRAP | INVOKE);
-        def(XXXUNUSEDXXX        , "xxxunusedxxx"    , ""     , 0);
-        def(NEW                 , "new"             , "bii"  , 6, TRAP);
-        def(NEWARRAY            , "newarray"        , "bc"   , 6, TRAP);
-        def(ANEWARRAY           , "anewarray"       , "bii"  , 6, TRAP);
-        def(ARRAYLENGTH         , "arraylength"     , "b"    , 2, TRAP);
-        def(ATHROW              , "athrow"          , "b"    , 5, TRAP | STOP);
-        def(CHECKCAST           , "checkcast"       , "bii"  , 3, TRAP);
-        def(INSTANCEOF          , "instanceof"      , "bii"  , 4, TRAP);
-        def(MONITORENTER        , "monitorenter"    , "b"    , 5, TRAP);
-        def(MONITOREXIT         , "monitorexit"     , "b"    , 5, TRAP);
-        def(WIDE                , "wide"            , ""     , 0);
-        def(MULTIANEWARRAY      , "multianewarray"  , "biic" , 6, TRAP);
-        def(IFNULL              , "ifnull"          , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(IFNONNULL           , "ifnonnull"       , "boo"  , 2, FALL_THROUGH | BRANCH);
-        def(GOTO_W              , "goto_w"          , "boooo", 1, STOP | BRANCH);
-        def(JSR_W               , "jsr_w"           , "boooo", 0, STOP | BRANCH);
-        def(BREAKPOINT          , "breakpoint"      , "b"    , 0, TRAP);
-    }
-    // Checkstyle: resume
-
-    /**
-     * Determines if an opcode is commutative.
-     * @param opcode the opcode to check
-     * @return {@code true} iff commutative
-     */
-    public static boolean isCommutative(int opcode) {
-        return (flagsArray[opcode & 0xff] & COMMUTATIVE) != 0;
-    }
-
-    /**
-     * Gets the length of an instruction denoted by a given opcode.
-     *
-     * @param opcode an instruction opcode
-     * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a
-     *         variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned.
-     */
-    public static int lengthOf(int opcode) {
-        return lengthArray[opcode & 0xff];
-    }
-
-    /**
-     * Gets the compilation complexity for a given opcode.
-     * @param opcode an opcode
-     * @return a value >= 0
-     */
-    public static int compilationComplexity(int opcode) {
-        return compilationComplexityArray[opcode & 0xff];
-    }
-
-    /**
-     * Gets the lower-case mnemonic for a given opcode.
-     *
-     * @param opcode an opcode
-     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode
-     */
-    public static String nameOf(int opcode) throws IllegalArgumentException {
-        String name = nameArray[opcode & 0xff];
-        if (name == null) {
-            return "<illegal opcode: " + opcode + ">";
-        }
-        return name;
-    }
-
-    /**
-     * Allocation-free version of {@linkplain #nameOf(int)}.
-     * @param opcode an opcode.
-     * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode.
-     */
-    public static String baseNameOf(int opcode) {
-        String name = nameArray[opcode & 0xff];
-        if (name == null) {
-            return "<illegal opcode>";
-        }
-        return name;
-    }
-
-    /**
-     * Gets the opcode corresponding to a given mnemonic.
-     *
-     * @param name an opcode mnemonic
-     * @return the opcode corresponding to {@code mnemonic}
-     * @throws IllegalArgumentException if {@code name} does not denote a valid opcode
-     */
-    public static int valueOf(String name) {
-        for (int opcode = 0; opcode < nameArray.length; ++opcode) {
-            if (name.equalsIgnoreCase(nameArray[opcode])) {
-                return opcode;
-            }
-        }
-        throw new IllegalArgumentException("No opcode for " + name);
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that can cause an implicit exception.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise
-     */
-    public static boolean canTrap(int opcode) {
-        return (flagsArray[opcode & 0xff] & TRAP) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise
-     */
-    public static boolean isLoad(int opcode) {
-        return (flagsArray[opcode & 0xff] & LOAD) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall
-     * through to its lexical successor.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} properly ends a basic block
-     */
-    public static boolean isStop(int opcode) {
-        return (flagsArray[opcode & 0xff] & STOP) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that stores a value to a local variable
-     * after popping it from the operand stack.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
-     */
-    public static boolean isInvoke(int opcode) {
-        return (flagsArray[opcode & 0xff] & INVOKE) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an instruction that stores a value to a local variable
-     * after popping it from the operand stack.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise
-     */
-    public static boolean isStore(int opcode) {
-        return (flagsArray[opcode & 0xff] & STORE) != 0;
-    }
-
-    /**
-     * Determines if a given opcode is an instruction that delimits a basic block.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} delimits a basic block
-     */
-    public static boolean isBlockEnd(int opcode) {
-        return (flagsArray[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0;
-    }
-
-    /**
-     * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another
-     * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} is a branch instruction with a single operand
-     */
-    public static boolean isBranch(int opcode) {
-        return (flagsArray[opcode & 0xff] & BRANCH) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes a conditional branch.
-     * @param opcode
-     * @return {@code true} iff {@code opcode} is a conditional branch
-     */
-    public static boolean isConditionalBranch(int opcode) {
-        return (flagsArray[opcode & 0xff] & FALL_THROUGH) != 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes a standard bytecode. A standard bytecode is
-     * defined in the JVM specification.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} iff {@code opcode} is a standard bytecode
-     */
-    public static boolean isStandard(int opcode) {
-        return (flagsArray[opcode & 0xff] & EXTENSION) == 0;
-    }
-
-    /**
-     * Determines if a given opcode denotes an extended bytecode.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} if {@code opcode} is an extended bytecode
-     */
-    public static boolean isExtended(int opcode) {
-        return (flagsArray[opcode & 0xff] & EXTENSION) != 0;
-    }
-
-    /**
-     * Determines if a given opcode is a three-byte extended bytecode.
-     *
-     * @param opcode an opcode to test
-     * @return {@code true} if {@code (opcode & ~0xff) != 0}
-     */
-    public static boolean isThreeByteExtended(int opcode) {
-        return (opcode & ~0xff) != 0;
-    }
-
-    /**
-     * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an
-     * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned
-     * instead.
-     *
-     * @param op an opcode
-     * @return the arithmetic operator name
-     */
-    public static String operator(int op) {
-        // Checkstyle: stop
-        switch (op) {
-            // arithmetic ops
-            case IADD : // fall through
-            case LADD : // fall through
-            case FADD : // fall through
-            case DADD : return "+";
-            case ISUB : // fall through
-            case LSUB : // fall through
-            case FSUB : // fall through
-            case DSUB : return "-";
-            case IMUL : // fall through
-            case LMUL : // fall through
-            case FMUL : // fall through
-            case DMUL : return "*";
-            case IDIV : // fall through
-            case LDIV : // fall through
-            case FDIV : // fall through
-            case DDIV : return "/";
-            case IREM : // fall through
-            case LREM : // fall through
-            case FREM : // fall through
-            case DREM : return "%";
-            // shift ops
-            case ISHL : // fall through
-            case LSHL : return "<<";
-            case ISHR : // fall through
-            case LSHR : return ">>";
-            case IUSHR: // fall through
-            case LUSHR: return ">>>";
-            // logic ops
-            case IAND : // fall through
-            case LAND : return "&";
-            case IOR  : // fall through
-            case LOR  : return "|";
-            case IXOR : // fall through
-            case LXOR : return "^";
-        }
-        // Checkstyle: resume
-        return nameOf(op);
-    }
-
-    /**
-     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
-     *
-     * @param name instruction name (should be lower case)
-     * @param format encodes the length of the instruction
-     * @param flagsArray the set of {@link Flags} associated with the instruction
-     */
-    private static void def(int opcode, String name, String format, int compilationComplexity) {
-        def(opcode, name, format, compilationComplexity, 0);
-    }
-
-    /**
-     * Defines a bytecode by entering it into the arrays that record its name, length and flags.
-     *
-     * @param name instruction name (lower case)
-     * @param format encodes the length of the instruction
-     * @param flags the set of {@link Flags} associated with the instruction
-     */
-    private static void def(int opcode, String name, String format, int compilationComplexity, int flags) {
-        assert nameArray[opcode] == null : "opcode " + opcode + " is already bound to name " + nameArray[opcode];
-        nameArray[opcode] = name;
-        int instructionLength = format.length();
-        lengthArray[opcode] = instructionLength;
-        compilationComplexityArray[opcode] = compilationComplexity;
-        Bytecodes.flagsArray[opcode] = flags;
-
-        assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch";
-    }
-
-    /**
-     * Utility for ensuring that the extended opcodes are contiguous and follow on directly
-     * from the standard JVM opcodes. If these conditions do not hold for the input source
-     * file, then it is modified 'in situ' to fix the problem.
-     *
-     * @param args {@code args[0]} is the path to this source file
-     */
-    public static void main(String[] args) throws Exception {
-        Method findWorkspaceDirectory = Class.forName("com.sun.max.ide.JavaProject").getDeclaredMethod("findWorkspaceDirectory");
-        File base = new File((File) findWorkspaceDirectory.invoke(null), "com.oracle.max.cri/src");
-        File file = new File(base, Bytecodes.class.getName().replace('.', File.separatorChar) + ".java").getAbsoluteFile();
-
-        Pattern opcodeDecl = Pattern.compile("(\\s*public static final int )(\\w+)(\\s*=\\s*)(\\d+)(;.*)");
-
-        BufferedReader br = new BufferedReader(new FileReader(file));
-        CharArrayWriter buffer = new CharArrayWriter((int) file.length());
-        PrintWriter out = new PrintWriter(buffer);
-        String line;
-        int lastExtendedOpcode = BREAKPOINT;
-        boolean modified = false;
-        int section = 0;
-        while ((line = br.readLine()) != null) {
-            if (section == 0) {
-                if (line.equals("    // Start extended bytecodes")) {
-                    section = 1;
-                }
-            } else if (section == 1) {
-                if (line.equals("    // End extended bytecodes")) {
-                    section = 2;
-                } else {
-                    Matcher matcher = opcodeDecl.matcher(line);
-                    if (matcher.matches()) {
-                        String name = matcher.group(2);
-                        String value = matcher.group(4);
-                        int opcode = Integer.parseInt(value);
-                        if (nameArray[opcode] == null || !nameArray[opcode].equalsIgnoreCase(name)) {
-                            throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + nameArray[opcode]);
-                        }
-                        if (opcode != lastExtendedOpcode + 1) {
-                            System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")");
-                            opcode = lastExtendedOpcode + 1;
-                            line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4));
-                            modified = true;
-                        }
-
-                        if (opcode >= 256) {
-                            throw new RuntimeException("Exceeded maximum opcode value with " + name);
-                        }
-
-                        lastExtendedOpcode = opcode;
-                    }
-                }
-            }
-
-            out.println(line);
-        }
-        if (section == 0) {
-            throw new RuntimeException("Did not find line starting extended bytecode declarations:\n\n    // Start extended bytecodes");
-        } else if (section == 1) {
-            throw new RuntimeException("Did not find line ending extended bytecode declarations:\n\n    // End extended bytecodes");
-        }
-
-        if (modified) {
-            out.flush();
-            FileWriter fileWriter = new FileWriter(file);
-            fileWriter.write(buffer.toCharArray());
-            fileWriter.close();
-
-            System.out.println("Modified: " + file);
-        }
-
-
-        // Uncomment to print out visitor method declarations:
-//        for (int opcode = 0; opcode < flags.length; ++opcode) {
-//            if (isExtension(opcode)) {
-//                String visitorParams = length(opcode) == 1 ? "" : "int index";
-//                System.out.println("@Override");
-//                System.out.println("protected void " + name(opcode) + "(" + visitorParams + ") {");
-//                System.out.println("}");
-//                System.out.println();
-//            }
-//        }
-
-        // Uncomment to print out visitor method declarations:
-//        for (int opcode = 0; opcode < flags.length; ++opcode) {
-//            if (isExtension(opcode)) {
-//                System.out.println("case " + name(opcode).toUpperCase() + ": {");
-//                String arg = "";
-//                int length = length(opcode);
-//                if (length == 2) {
-//                    arg = "readUnsigned1()";
-//                } else if (length == 3) {
-//                    arg = "readUnsigned2()";
-//                }
-//                System.out.println("    bytecodeVisitor." + name(opcode) + "(" + arg + ");");
-//                System.out.println("    break;");
-//                System.out.println("}");
-//            }
-//        }
-
-    }
-}
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/bytecode/Bytes.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.java.bytecode;
-
-/**
- * A collection of utility methods for dealing with bytes, particularly in byte arrays.
- */
-public class Bytes {
-    /**
-     * Gets a signed 1-byte value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the signed 1-byte value at index {@code bci} in array {@code data}
-     */
-    public static int beS1(byte[] data, int bci) {
-        return data[bci];
-    }
-
-    /**
-     * Gets a signed 2-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the signed 2-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beS2(byte[] data, int bci) {
-        return (data[bci] << 8) | (data[bci + 1] & 0xff);
-    }
-
-    /**
-     * Gets an unsigned 1-byte value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the unsigned 1-byte value at index {@code bci} in array {@code data}
-     */
-    public static int beU1(byte[] data, int bci) {
-        return data[bci] & 0xff;
-    }
-
-    /**
-     * Gets an unsigned 2-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the unsigned 2-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beU2(byte[] data, int bci) {
-        return ((data[bci] & 0xff) << 8) | (data[bci + 1] & 0xff);
-    }
-
-    /**
-     * Gets a signed 4-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @return the signed 4-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beS4(byte[] data, int bci) {
-        return (data[bci] << 24) | ((data[bci + 1] & 0xff) << 16) | ((data[bci + 2] & 0xff) << 8) | (data[bci + 3] & 0xff);
-    }
-
-    /**
-     * Gets either a signed 2-byte or a signed 4-byte big-endian value.
-     * @param data the array containing the data
-     * @param bci the start index of the value to retrieve
-     * @param fourByte if true, this method will return a 4-byte value
-     * @return the signed 2 or 4-byte, big-endian, value at index {@code bci} in array {@code data}
-     */
-    public static int beSVar(byte[] data, int bci, boolean fourByte) {
-        if (fourByte) {
-            return beS4(data, bci);
-        } else {
-            return beS2(data, bci);
-        }
-    }
-}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ldiv2.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ldiv2.java	Wed Jun 27 17:35:32 2012 +0200
@@ -27,6 +27,8 @@
 /*
  */
 public class BC_ldiv2 {
+    public static long MIN = Long.MIN_VALUE;
+    public static long MAX = Long.MAX_VALUE;
 
     public static long test(long a, long b) {
         return a / b;
@@ -34,12 +36,16 @@
 
     @Test
     public void run0() throws Throwable {
-        Assert.assertEquals(-9223372036854775808L, test(-9223372036854775808L, -1));
+        Assert.assertEquals(MIN, test(MIN, -1));
     }
 
     @Test
     public void run1() throws Throwable {
-        Assert.assertEquals(-9223372036854775808L, test(-9223372036854775808L, 1));
+        Assert.assertEquals(MIN, test(MIN, 1));
     }
 
+    @Test
+    public void run2() throws Throwable {
+        Assert.assertEquals(-1, test(MIN, MAX));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_ldiv3.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009, 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.jtt.bytecode;
+
+import org.junit.*;
+
+/*
+ */
+public class BC_ldiv3 {
+    public static long PLUS7 = 7;
+    public static long PLUS3 = 3;
+    public static long MIN7 = -7;
+    public static long MIN3 = -3;
+
+    public static long test(long a, long b) {
+        return a / b;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(3, test(PLUS7, 2));
+        Assert.assertEquals(1, test(PLUS3, 2));
+        Assert.assertEquals(-3, test(MIN7, 2));
+        Assert.assertEquals(-1, test(MIN3, 2));
+    }
+
+    @Test
+    public void run1() throws Throwable {
+        Assert.assertEquals(-1, test(PLUS7, -4));
+        Assert.assertEquals(0, test(PLUS3, -4));
+        Assert.assertEquals(1, test(MIN7, -4));
+        Assert.assertEquals(0, test(MIN3, -4));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopEscape.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+// Checkstyle: stop
+package com.oracle.graal.jtt.loop;
+
+import org.junit.*;
+
+/*
+ * Test around an object that escapes directly from inside a loop (no virtual phi on the loop)
+ */
+public class LoopEscape {
+    public static L ll = new L(0, 1, 2);
+
+    private static class L {
+        public int a;
+        public int b;
+        public int c;
+        public L(int a, int b, int c) {
+            this.a = a;
+            this.b = b;
+            this.c = c;
+        }
+    }
+
+
+    public static int test0(int count) {
+        L l = new L(5, 5, 5);
+        for (int i = 0; i < count; i++) {
+            l.a++;
+            l.b--;
+            l.c = 4;
+        }
+
+        return l.a + l.b * 10 + l.c * 100;
+    }
+
+    public static int test1(int count) {
+        L l = new L(5, 5, 5);
+        for (int i = 0; i < count; i++) {
+            if (l.a % 2 == 0) {
+                l.a++;
+                l.b--;
+                l.c = 4;
+            } else {
+                l.a++;
+            }
+        }
+
+        return l.a + l.b * 10 + l.c * 100;
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertEquals(555, test1(0));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertEquals(556, test1(1));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertEquals(447, test1(2));
+    }
+
+    @Test
+    public void run00() throws Throwable {
+        Assert.assertEquals(555, test0(0));
+    }
+
+    @Test
+    public void run01() throws Throwable {
+        Assert.assertEquals(446, test0(1));
+    }
+
+    @Test
+    public void run02() throws Throwable {
+        Assert.assertEquals(437, test0(2));
+    }
+
+    @Test
+    public void run05() throws Throwable {
+        Assert.assertEquals(410, test0(5));
+    }
+}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopLastIndexOf.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopLastIndexOf.java	Wed Jun 27 17:35:32 2012 +0200
@@ -34,8 +34,9 @@
     private final char[] v3 = new char[]{'d', 'b', 'c'};
     private final char[] v4 = new char[]{'z', 'a', 'b', 'c'};
 
-    public static int test(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) {
+    public static int test(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndexParam) {
         int rightIndex = sourceCount - targetCount;
+        int fromIndex = fromIndexParam;
         if (fromIndex < 0) {
             return -1;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy02.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests calls to the array copy method.
+ */
+public class ArrayCopy02 {
+
+    public static int[] src = new int[]{0, 1, 2, 3, 4, 5};
+    public static int[] dest0 = new int[]{5, 4, 3, 2, 1, 0};
+    public static int[] dest = new int[]{5, 4, 3, 2, 1, 0};
+
+    @Before
+    public void setUp() {
+        System.currentTimeMillis();
+        for (int i = 0; i < dest.length; i++) {
+            dest[i] = dest0[i];
+        }
+    }
+
+    public static int[] test(int srcPos, int destPos, int length) {
+        System.arraycopy(src, srcPos, dest, destPos, length);
+        return dest;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertArrayEquals(new int[] {5, 4, 3, 2, 1, 0}, test(0, 0, 0));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(0, 0, -1);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(-1, 0, 0);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(0, -1, 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertArrayEquals(new int[] {0, 1, 3, 2, 1, 0}, test(0, 0, 2));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(0, 1, 6);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run6() throws Throwable {
+        test(1, 0, 6);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run7() throws Throwable {
+        test(1, 1, -1);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertArrayEquals(new int[] {5, 0, 1, 2, 1, 0}, test(0, 1, 2));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertArrayEquals(new int[] {1, 2, 3, 2, 1, 0}, test(1, 0, 2));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertArrayEquals(new int[] {5, 1, 2, 2, 1, 0}, test(1, 1, 2));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertArrayEquals(new int[] {0, 1, 2, 3, 4, 5}, test(0, 0, 6));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertArrayEquals(new int[] {5, 0, 1, 2, 3, 4}, test(0, 1, 5));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertArrayEquals(new int[] {1, 2, 3, 4, 5, 0}, test(1, 0, 5));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertArrayEquals(new int[] {5, 1, 2, 3, 4, 5}, test(1, 1, 5));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy03.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests calls to the array copy method.
+ */
+public class ArrayCopy03 {
+
+    public static byte[] src = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    public static byte[] dest0 = new byte[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+    public static byte[] dest = new byte[]{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+
+    @Before
+    public void setUp() {
+        System.currentTimeMillis();
+        for (int i = 0; i < dest.length; i++) {
+            dest[i] = dest0[i];
+        }
+    }
+
+    public static byte[] test(int srcPos, int destPos, int length) {
+        System.arraycopy(src, srcPos, dest, destPos, length);
+        return dest;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, test(0, 0, 0));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(0, 0, -1);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(-1, 0, 0);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(0, -1, 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 8, 7, 6, 5, 4, 3, 2, 1, 0}, test(0, 0, 2));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(0, 1, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run6() throws Throwable {
+        test(1, 0, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run7() throws Throwable {
+        test(1, 1, -1);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {10, 0, 1, 7, 6, 5, 4, 3, 2, 1, 0}, test(0, 1, 2));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {1, 2, 8, 7, 6, 5, 4, 3, 2, 1, 0}, test(1, 0, 2));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {10, 1, 2, 7, 6, 5, 4, 3, 2, 1, 0}, test(1, 1, 2));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0}, test(0, 0, 6));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {10, 0, 1, 2, 3, 4, 4, 3, 2, 1, 0}, test(0, 1, 5));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0}, test(1, 0, 5));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {10, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0}, test(1, 1, 5));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 11));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ArrayCopy04.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.jtt.optimize;
+
+import org.junit.*;
+
+/*
+ * Tests calls to the array copy method.
+ */
+public class ArrayCopy04 {
+
+    public static byte[] array = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+    public static byte[] array0 = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+
+    @Before
+    public void setUp() {
+        System.currentTimeMillis();
+        for (int i = 0; i < array.length; i++) {
+            array[i] = array0[i];
+        }
+    }
+
+    public static byte[] test(int srcPos, int destPos, int length) {
+        System.arraycopy(array, srcPos, array, destPos, length);
+        return array;
+    }
+
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 0));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run1() throws Throwable {
+        test(0, 0, -1);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run2() throws Throwable {
+        test(-1, 0, 0);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run3() throws Throwable {
+        test(0, -1, 0);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 2));
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run5() throws Throwable {
+        test(0, 1, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run6() throws Throwable {
+        test(1, 0, 11);
+    }
+
+    @Test(expected = java.lang.IndexOutOfBoundsException.class)
+    public void run7() throws Throwable {
+        test(1, 1, -1);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 1, 2));
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 0, 2));
+    }
+
+    @Test
+    public void run10() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 1, 2));
+    }
+
+    @Test
+    public void run11() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 6));
+    }
+
+    @Test
+    public void run12() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 0, 1, 2, 3, 4, 6, 7, 8, 9, 10}, test(0, 1, 5));
+    }
+
+    @Test
+    public void run13() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10}, test(1, 0, 5));
+    }
+
+    @Test
+    public void run14() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(1, 1, 5));
+    }
+
+    @Test
+    public void run15() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, test(0, 0, 11));
+    }
+
+    @Test
+    public void run16() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, test(0, 1, 10));
+    }
+
+    @Test
+    public void run17() throws Throwable {
+        Assert.assertArrayEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10}, test(1, 0, 10));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ReassociateConstants.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 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.jtt.optimize;
+
+import org.junit.*;
+
+
+public class ReassociateConstants {
+    public static int rnd = (int) (Math.random() * 100);
+    @Test
+    public void run0() throws Throwable {
+        Assert.assertEquals(rnd + 3, 1 + (rnd + 2));
+        Assert.assertEquals(rnd + 3, (rnd + 2) + 1);
+        Assert.assertEquals(rnd + 3, 1 + (2 + rnd));
+        Assert.assertEquals(rnd + 3, (2 + rnd) + 1);
+
+        Assert.assertEquals(-1 - rnd, 1 - (rnd + 2));
+        Assert.assertEquals(rnd + 1, (rnd + 2) - 1);
+        Assert.assertEquals(-1 - rnd, 1 - (2 + rnd));
+        Assert.assertEquals(rnd + 1, (2 + rnd) - 1);
+
+        Assert.assertEquals(rnd - 1, 1 + (rnd - 2));
+        Assert.assertEquals(rnd - 1, (rnd - 2) + 1);
+        Assert.assertEquals(-rnd + 3, 1 + (2 - rnd));
+        Assert.assertEquals(-rnd + 3, (2 - rnd) + 1);
+
+        Assert.assertEquals(-rnd + 3, 1 - (rnd - 2));
+        Assert.assertEquals(rnd - 3, (rnd - 2) - 1);
+        Assert.assertEquals(rnd + -1, 1 - (2 - rnd));
+        Assert.assertEquals(-rnd + 1, (2 - rnd) - 1);
+    }
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,14 @@
  */
 package com.oracle.graal.lir.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -48,14 +48,14 @@
 
 
     public static class Op1Reg extends AMD64LIRInstruction {
-        public Op1Reg(AMD64Arithmetic opcode, CiValue result, CiValue x) {
-            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public Op1Reg(AMD64Arithmetic opcode, Value result, Value x) {
+            super(opcode, new Value[] {result}, null, new Value[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue result = output(0);
-            CiValue x = input(0);
+            Value result = output(0);
+            Value x = input(0);
 
             emit(tasm, masm, (AMD64Arithmetic) code, result, x, null);
         }
@@ -72,14 +72,14 @@
     }
 
     public static class Op1Stack extends AMD64LIRInstruction {
-        public Op1Stack(AMD64Arithmetic opcode, CiValue result, CiValue x) {
-            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public Op1Stack(AMD64Arithmetic opcode, Value result, Value x) {
+            super(opcode, new Value[] {result}, null, new Value[] {x}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue result = output(0);
-            CiValue x = input(0);
+            Value result = output(0);
+            Value x = input(0);
 
             AMD64Move.move(tasm, masm, result, x);
             emit(tasm, masm, (AMD64Arithmetic) code, result);
@@ -97,15 +97,15 @@
     }
 
     public static class Op2Stack extends AMD64LIRInstruction {
-        public Op2Stack(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
-            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        public Op2Stack(AMD64Arithmetic opcode, Value result, Value x, Value y) {
+            super(opcode, new Value[] {result}, null, new Value[] {x}, new Value[] {y}, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = alive(0);
 
             AMD64Move.move(tasm, masm, result, x);
             emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
@@ -125,9 +125,9 @@
 
         @Override
         public void verify() {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = alive(0);
 
             super.verify();
             assert differentRegisters(result, y) || sameRegister(x, y);
@@ -136,15 +136,15 @@
     }
 
     public static class Op2Reg extends AMD64LIRInstruction {
-        public Op2Reg(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
-            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        public Op2Reg(AMD64Arithmetic opcode, Value result, Value x, Value y) {
+            super(opcode, new Value[] {result}, null, new Value[] {x}, new Value[] {y}, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = alive(0);
 
             AMD64Move.move(tasm, masm, result, x);
             emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
@@ -164,9 +164,9 @@
 
         @Override
         public void verify() {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = alive(0);
 
             super.verify();
             assert differentRegisters(result, y) || sameRegister(x, y);
@@ -175,15 +175,15 @@
     }
 
     public static class Op2RegCommutative extends AMD64LIRInstruction {
-        public Op2RegCommutative(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
-            super(opcode, new CiValue[] {result}, null, new CiValue[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public Op2RegCommutative(AMD64Arithmetic opcode, Value result, Value x, Value y) {
+            super(opcode, new Value[] {result}, null, new Value[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = input(1);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = input(1);
 
             if (sameRegister(result, y)) {
                 emit(tasm, masm, (AMD64Arithmetic) code, result, x, null);
@@ -207,9 +207,9 @@
 
         @Override
         protected void verify() {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = input(1);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = input(1);
 
             super.verify();
             verifyKind((AMD64Arithmetic) code, result, x, y);
@@ -217,15 +217,15 @@
     }
 
     public static class ShiftOp extends AMD64LIRInstruction {
-        public ShiftOp(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
-            super(opcode, new CiValue[] {result}, null, new CiValue[] {x}, new CiValue[] {y}, LIRInstruction.NO_OPERANDS);
+        public ShiftOp(AMD64Arithmetic opcode, Value result, Value x, Value y) {
+            super(opcode, new Value[] {result}, null, new Value[] {x}, new Value[] {y}, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = alive(0);
 
             AMD64Move.move(tasm, masm, result, x);
             emit(tasm, masm, (AMD64Arithmetic) code, result, y, null);
@@ -245,27 +245,27 @@
 
         @Override
         public void verify() {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = alive(0);
 
             super.verify();
             assert isConstant(y) || asRegister(y) == AMD64.rcx;
             assert differentRegisters(result, y) || sameRegister(x, y);
             verifyKind((AMD64Arithmetic) code, result, x, x);
-            assert y.kind.stackKind() == CiKind.Int;
+            assert y.kind.stackKind() == Kind.Int;
         }
     }
 
     public static class DivOp extends AMD64LIRInstruction {
-        public DivOp(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y, LIRDebugInfo info) {
-            super(opcode, new CiValue[] {result}, info, new CiValue[] {x}, new CiValue[] {y}, new CiValue[] {asRegister(result) == AMD64.rax ? AMD64.rdx.asValue(result.kind) : AMD64.rax.asValue(result.kind)});
+        public DivOp(AMD64Arithmetic opcode, Value result, Value x, Value y, LIRDebugInfo info) {
+            super(opcode, new Value[] {result}, info, new Value[] {x}, new Value[] {y}, new Value[] {asRegister(result) == AMD64.rax ? AMD64.rdx.asValue(result.kind) : AMD64.rax.asValue(result.kind)});
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue result = output(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value y = alive(0);
 
             emit(tasm, masm, (AMD64Arithmetic) code, result, y, info);
         }
@@ -286,9 +286,9 @@
 
         @Override
         protected void verify() {
-            CiValue result = output(0);
-            CiValue x = input(0);
-            CiValue y = alive(0);
+            Value result = output(0);
+            Value x = input(0);
+            Value y = alive(0);
 
             super.verify();
             // left input in rax, right input in any register but rax and rdx, result quotient in rax, result remainder in rdx
@@ -301,7 +301,7 @@
 
 
     @SuppressWarnings("unused")
-    protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, CiValue result) {
+    protected static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, Value result) {
         switch (opcode) {
             case INEG: masm.negl(asIntReg(result)); break;
             case LNEG: masm.negq(asLongReg(result)); break;
@@ -313,7 +313,7 @@
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, CiValue dst, CiValue src, LIRDebugInfo info) {
+    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Arithmetic opcode, Value dst, Value src, LIRDebugInfo info) {
         int exceptionOffset = -1;
         if (isRegister(src)) {
             switch (opcode) {
@@ -397,7 +397,7 @@
                         masm.movq(AMD64.rdx, java.lang.Long.MIN_VALUE);
                         masm.cmpq(AMD64.rax, AMD64.rdx);
                         masm.jcc(ConditionFlag.notEqual, normalCase);
-                        masm.cmpl(asRegister(src), -1);
+                        masm.cmpq(asRegister(src), -1);
                         masm.jcc(ConditionFlag.equal, continuation);
                         masm.bind(normalCase);
                     }
@@ -498,12 +498,12 @@
         }
     }
 
-    private static void emitConvertFixup(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
+    private static void emitConvertFixup(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value x) {
         ConvertSlowPath slowPath = new ConvertSlowPath(result, x);
         tasm.stubs.add(slowPath);
         switch (result.kind) {
             case Int:  masm.cmpl(asIntReg(result),  Integer.MIN_VALUE); break;
-            case Long: masm.cmpq(asLongReg(result), tasm.asLongConstRef(CiConstant.forLong(java.lang.Long.MIN_VALUE))); break;
+            case Long: masm.cmpq(asLongReg(result), tasm.asLongConstRef(Constant.forLong(java.lang.Long.MIN_VALUE))); break;
             default:   throw GraalInternalError.shouldNotReachHere();
         }
         masm.jcc(ConditionFlag.equal, slowPath.start);
@@ -513,10 +513,10 @@
     private static class ConvertSlowPath extends AMD64Code {
         public final Label start = new Label();
         public final Label continuation = new Label();
-        private final CiValue result;
-        private final CiValue x;
+        private final Value result;
+        private final Value x;
 
-        public ConvertSlowPath(CiValue result, CiValue x) {
+        public ConvertSlowPath(Value result, Value x) {
             this.result = result;
             this.x = x;
         }
@@ -525,8 +525,8 @@
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
             masm.bind(start);
             switch (x.kind) {
-                case Float:  masm.ucomiss(asFloatReg(x),  tasm.asFloatConstRef(CiConstant.FLOAT_0)); break;
-                case Double: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(CiConstant.DOUBLE_0)); break;
+                case Float:  masm.ucomiss(asFloatReg(x),  tasm.asFloatConstRef(Constant.FLOAT_0)); break;
+                case Double: masm.ucomisd(asDoubleReg(x), tasm.asDoubleConstRef(Constant.DOUBLE_0)); break;
                 default:     throw GraalInternalError.shouldNotReachHere();
             }
             Label nan = new Label();
@@ -555,10 +555,10 @@
     }
 
 
-    private static void verifyKind(AMD64Arithmetic opcode, CiValue result, CiValue x, CiValue y) {
-        assert (opcode.name().startsWith("I") && result.kind == CiKind.Int && x.kind.stackKind() == CiKind.Int && y.kind.stackKind() == CiKind.Int)
-            || (opcode.name().startsWith("L") && result.kind == CiKind.Long && x.kind == CiKind.Long && y.kind == CiKind.Long)
-            || (opcode.name().startsWith("F") && result.kind == CiKind.Float && x.kind == CiKind.Float && y.kind == CiKind.Float)
-            || (opcode.name().startsWith("D") && result.kind == CiKind.Double && x.kind == CiKind.Double && y.kind == CiKind.Double);
+    private static void verifyKind(AMD64Arithmetic opcode, Value result, Value x, Value y) {
+        assert (opcode.name().startsWith("I") && result.kind == Kind.Int && x.kind.stackKind() == Kind.Int && y.kind.stackKind() == Kind.Int)
+            || (opcode.name().startsWith("L") && result.kind == Kind.Long && x.kind == Kind.Long && y.kind == Kind.Long)
+            || (opcode.name().startsWith("F") && result.kind == Kind.Float && x.kind == Kind.Float && y.kind == Kind.Float)
+            || (opcode.name().startsWith("D") && result.kind == Kind.Double && x.kind == Kind.Double && y.kind == Kind.Double);
     }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,15 @@
  */
 package com.oracle.graal.lir.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.Mark;
 import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -40,8 +41,8 @@
         private final Object targetMethod;
         private final Map<XirMark, Mark> marks;
 
-        public DirectCallOp(Object targetMethod, CiValue result, CiValue[] parameters, LIRDebugInfo info, Map<XirMark, Mark> marks) {
-            super("CALL_DIRECT", new CiValue[] {result}, info, parameters, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public DirectCallOp(Object targetMethod, Value result, Value[] parameters, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+            super("CALL_DIRECT", new Value[] {result}, info, parameters, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
             this.targetMethod = targetMethod;
             this.marks = marks;
         }
@@ -70,19 +71,19 @@
         private final Object targetMethod;
         private final Map<XirMark, Mark> marks;
 
-        private static CiValue[] concat(CiValue[] parameters, CiValue targetAddress) {
-            CiValue[] result = Arrays.copyOf(parameters, parameters.length + 1);
+        private static Value[] concat(Value[] parameters, Value targetAddress) {
+            Value[] result = Arrays.copyOf(parameters, parameters.length + 1);
             result[result.length - 1] = targetAddress;
             return result;
         }
 
-        public IndirectCallOp(Object targetMethod, CiValue result, CiValue[] parameters, CiValue targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
-            super("CALL_INDIRECT", new CiValue[] {result}, info, concat(parameters, targetAddress), LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value targetAddress, LIRDebugInfo info, Map<XirMark, Mark> marks) {
+            super("CALL_INDIRECT", new Value[] {result}, info, concat(parameters, targetAddress), LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
             this.targetMethod = targetMethod;
             this.marks = marks;
         }
 
-        private CiValue targetAddress() {
+        private Value targetAddress() {
             return input(inputs.length - 1);
         }
 
@@ -118,12 +119,12 @@
 
     public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRDebugInfo info) {
         int before = masm.codeBuffer.position();
-        if (target instanceof CiRuntimeCall) {
-            long maxOffset = tasm.runtime.getMaxCallTargetOffset((CiRuntimeCall) target);
+        if (target instanceof RuntimeCall) {
+            long maxOffset = tasm.runtime.getMaxCallTargetOffset((RuntimeCall) target);
             if (maxOffset != (int) maxOffset) {
                 // offset might not fit a 32-bit immediate, generate an
                 // indirect call with a 64-bit immediate
-                CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
+                Register scratch = tasm.frameMap.registerConfig.getScratchRegister();
                 // TODO (cwimmer): we want to get rid of a generally reserved scratch register.
                 masm.movq(scratch, 0L);
                 masm.call(scratch);
@@ -147,7 +148,7 @@
         masm.ensureUniquePC();
     }
 
-    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiRegister dst, Object target, LIRDebugInfo info) {
+    public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register dst, Object target, LIRDebugInfo info) {
         int before = masm.codeBuffer.position();
         masm.call(dst);
         int after = masm.codeBuffer.position();
@@ -161,7 +162,7 @@
         assert (assertions = true) == true;
 
         if (assertions) {
-            directCall(tasm, masm, CiRuntimeCall.Debug, null);
+            directCall(tasm, masm, RuntimeCall.Debug, null);
             masm.hlt();
         }
     }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Compare.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.lir.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -36,14 +36,14 @@
     ICMP, LCMP, ACMP, FCMP, DCMP;
 
     public static class CompareOp extends AMD64LIRInstruction {
-        public CompareOp(AMD64Compare opcode, CiValue x, CiValue y) {
-            super(opcode, LIRInstruction.NO_OPERANDS, null, new CiValue[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public CompareOp(AMD64Compare opcode, Value x, Value y) {
+            super(opcode, LIRInstruction.NO_OPERANDS, null, new Value[] {x, y}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            CiValue x = input(0);
-            CiValue y = input(1);
+            Value x = input(0);
+            Value y = input(1);
             emit(tasm, masm, (AMD64Compare) code, x, y);
         }
 
@@ -59,20 +59,20 @@
 
         @Override
         protected void verify() {
-            CiValue x = input(0);
-            CiValue y = input(1);
+            Value x = input(0);
+            Value y = input(1);
 
             super.verify();
-            assert (name().startsWith("I") && x.kind == CiKind.Int && y.kind.stackKind() == CiKind.Int)
-                || (name().startsWith("I") && x.kind == CiKind.Jsr && y.kind == CiKind.Jsr)
-                || (name().startsWith("L") && x.kind == CiKind.Long && y.kind == CiKind.Long)
-                || (name().startsWith("A") && x.kind == CiKind.Object && y.kind == CiKind.Object)
-                || (name().startsWith("F") && x.kind == CiKind.Float && y.kind == CiKind.Float)
-                || (name().startsWith("D") && x.kind == CiKind.Double && y.kind == CiKind.Double);
+            assert (name().startsWith("I") && x.kind == Kind.Int && y.kind.stackKind() == Kind.Int)
+                || (name().startsWith("I") && x.kind == Kind.Jsr && y.kind == Kind.Jsr)
+                || (name().startsWith("L") && x.kind == Kind.Long && y.kind == Kind.Long)
+                || (name().startsWith("A") && x.kind == Kind.Object && y.kind == Kind.Object)
+                || (name().startsWith("F") && x.kind == Kind.Float && y.kind == Kind.Float)
+                || (name().startsWith("D") && x.kind == Kind.Double && y.kind == Kind.Double);
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Compare opcode, CiValue x, CiValue y) {
+    public static void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AMD64Compare opcode, Value x, Value y) {
         if (isRegister(y)) {
             switch (opcode) {
                 case ICMP: masm.cmpl(asIntReg(x), asIntReg(y)); break;
@@ -87,7 +87,7 @@
                 case ICMP: masm.cmpl(asIntReg(x), tasm.asIntConst(y)); break;
                 case LCMP: masm.cmpq(asLongReg(x), tasm.asIntConst(y)); break;
                 case ACMP:
-                    if (((CiConstant) y).isNull()) {
+                    if (((Constant) y).isNull()) {
                         masm.cmpq(asObjectReg(x), 0); break;
                     } else {
                         throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons");
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,26 +22,28 @@
  */
 package com.oracle.graal.lir.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiAddress.Scale;
-import com.oracle.max.cri.ci.CiTargetMethod.JumpTable;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Address.*;
+import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.FallThroughOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.calc.*;
 
 public class AMD64ControlFlow {
 
     public static class ReturnOp extends AMD64LIRInstruction {
-        public ReturnOp(CiValue input) {
-            super("RETURN", LIRInstruction.NO_OPERANDS, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public ReturnOp(Value input) {
+            super("RETURN", LIRInstruction.NO_OPERANDS, null, new Value[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
@@ -63,10 +65,14 @@
 
 
     public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp {
-        protected Condition condition;
+        protected ConditionFlag condition;
         protected LabelRef destination;
 
         public BranchOp(Condition condition, LabelRef destination, LIRDebugInfo info) {
+            this(intCond(condition), destination, info);
+        }
+
+        public BranchOp(ConditionFlag condition, LabelRef destination, LIRDebugInfo info) {
             super("BRANCH", LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
             this.condition = condition;
             this.destination = destination;
@@ -74,7 +80,7 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            masm.jcc(intCond(condition), destination.label());
+            masm.jcc(condition, destination.label());
         }
 
         @Override
@@ -104,7 +110,7 @@
         protected boolean unorderedIsTrue;
 
         public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef destination, LIRDebugInfo info) {
-            super(condition, destination, info);
+            super(floatCond(condition), destination, info);
             this.unorderedIsTrue = unorderedIsTrue;
         }
 
@@ -132,7 +138,7 @@
         private final LabelRef[] targets;
 
         public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) {
-            super("TABLE_SWITCH", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, new CiValue[] {index}, new CiValue[] {scratch});
+            super("TABLE_SWITCH", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, new Value[] {index}, new Value[] {scratch});
             this.lowKey = lowKey;
             this.defaultTarget = defaultTarget;
             this.targets = targets;
@@ -166,13 +172,162 @@
         }
     }
 
+    public static class SequentialSwitchOp extends AMD64LIRInstruction implements FallThroughOp {
+        private final Constant[] keyConstants;
+        private final LabelRef[] keyTargets;
+        private LabelRef defaultTarget;
+
+        public SequentialSwitchOp(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value... temp) {
+            super("SEQUENTIAL_SWITCH", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, new Value[] {key}, temp);
+            assert keyConstants.length == keyTargets.length;
+            this.keyConstants = keyConstants;
+            this.keyTargets = keyTargets;
+            this.defaultTarget = defaultTarget;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            Value key = alive(0);
+            if (key.kind == Kind.Int) {
+                Register intKey = asIntReg(key);
+                for (int i = 0; i < keyConstants.length; i++) {
+                    masm.cmpl(intKey, tasm.asIntConst(keyConstants[i]));
+                    masm.jcc(ConditionFlag.equal, keyTargets[i].label());
+                }
+            } else if (key.kind == Kind.Object) {
+                Register intKey = asObjectReg(key);
+                Register temp = asObjectReg(temp(0));
+                for (int i = 0; i < keyConstants.length; i++) {
+                    AMD64Move.move(tasm, masm, temp.asValue(Kind.Object), keyConstants[i]);
+                    masm.cmpptr(intKey, temp);
+                    masm.jcc(ConditionFlag.equal, keyTargets[i].label());
+                }
+            } else {
+                throw new GraalInternalError("sequential switch only supported for int and object");
+            }
+            if (defaultTarget != null) {
+                masm.jmp(defaultTarget.label());
+            } else {
+                masm.hlt();
+            }
+        }
+
+        @Override
+        public String operationString() {
+            StringBuilder buf = new StringBuilder(super.operationString());
+            buf.append("\ndefault: [").append(defaultTarget).append(']');
+            for (int i = 0; i < keyConstants.length; i++) {
+                buf.append("\ncase ").append(keyConstants[i]).append(": [").append(keyTargets[i]).append("]");
+            }
+            return buf.toString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Temp && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        public LabelRef fallThroughTarget() {
+            return defaultTarget;
+        }
+
+        @Override
+        public void setFallThroughTarget(LabelRef target) {
+            defaultTarget = target;
+        }
+    }
+
+    public static class SwitchRangesOp extends AMD64LIRInstruction implements FallThroughOp {
+        private final LabelRef[] keyTargets;
+        private LabelRef defaultTarget;
+        private final int[] lowKeys;
+        private final int[] highKeys;
+
+        public SwitchRangesOp(int[] lowKeys, int[] highKeys, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) {
+            super("SWITCH_RANGES", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, new Value[] {key}, LIRInstruction.NO_OPERANDS);
+            assert lowKeys.length == keyTargets.length;
+            assert highKeys.length == keyTargets.length;
+            assert key.kind == Kind.Int;
+            this.lowKeys = lowKeys;
+            this.highKeys = highKeys;
+            this.keyTargets = keyTargets;
+            this.defaultTarget = defaultTarget;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
+            Register key = asIntReg(alive(0));
+            for (int i = 0; i < lowKeys.length; i++) {
+                int lowKey = lowKeys[i];
+                int highKey = highKeys[i];
+                if (lowKey == highKey) {
+                    masm.cmpl(key, lowKey);
+                    masm.jcc(ConditionFlag.equal, keyTargets[i].label());
+                } else if (lowKey + 1 == highKey) {
+                    masm.cmpl(key, lowKey);
+                    masm.jcc(ConditionFlag.equal, keyTargets[i].label());
+                    masm.cmpl(key, highKey);
+                    masm.jcc(ConditionFlag.equal, keyTargets[i].label());
+                } else {
+                    Label skip = new Label();
+                    masm.cmpl(key, lowKey);
+                    masm.jcc(ConditionFlag.less, skip);
+                    masm.cmpl(key, highKey);
+                    masm.jcc(ConditionFlag.lessEqual, keyTargets[i].label());
+                    masm.bind(skip);
+                }
+            }
+            if (defaultTarget != null) {
+                masm.jmp(defaultTarget.label());
+            } else {
+                masm.hlt();
+            }
+        }
+
+        @Override
+        public String operationString() {
+            StringBuilder buf = new StringBuilder(super.operationString());
+            buf.append("\ndefault: [").append(defaultTarget).append(']');
+            for (int i = 0; i < lowKeys.length; i++) {
+                buf.append("\ncase ").append(lowKeys[i]).append(" - ").append(highKeys[i]).append(": [").append(keyTargets[i]).append("]");
+            }
+            return buf.toString();
+        }
+
+        @Override
+        protected EnumSet<OperandFlag> flagsFor(OperandMode mode, int index) {
+            if (mode == OperandMode.Alive && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            } else if (mode == OperandMode.Temp && index == 0) {
+                return EnumSet.of(OperandFlag.Register);
+            }
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        @Override
+        public LabelRef fallThroughTarget() {
+            return defaultTarget;
+        }
+
+        @Override
+        public void setFallThroughTarget(LabelRef target) {
+            defaultTarget = target;
+        }
+    }
+
 
     public static class CondMoveOp extends AMD64LIRInstruction {
-        private final Condition condition;
+        private final ConditionFlag condition;
 
-        public CondMoveOp(Variable result, Condition condition, Variable trueValue, CiValue falseValue) {
-            super("CMOVE", new CiValue[] {result}, null, new CiValue[] {falseValue}, new CiValue[] {trueValue}, LIRInstruction.NO_OPERANDS);
-            this.condition = condition;
+        public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) {
+            super("CMOVE", new Value[] {result}, null, new Value[] {falseValue}, new Value[] {trueValue}, LIRInstruction.NO_OPERANDS);
+            this.condition = intCond(condition);
         }
 
         @Override
@@ -200,12 +355,12 @@
 
 
     public static class FloatCondMoveOp extends AMD64LIRInstruction {
-        private final Condition condition;
+        private final ConditionFlag condition;
         private final boolean unorderedIsTrue;
 
         public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) {
-            super("FLOAT_CMOVE", new CiValue[] {result}, null, LIRInstruction.NO_OPERANDS, new CiValue[] {trueValue, falseValue}, LIRInstruction.NO_OPERANDS);
-            this.condition = condition;
+            super("FLOAT_CMOVE", new Value[] {result}, null, LIRInstruction.NO_OPERANDS, new Value[] {trueValue, falseValue}, LIRInstruction.NO_OPERANDS);
+            this.condition = floatCond(condition);
             this.unorderedIsTrue = unorderedIsTrue;
         }
 
@@ -232,8 +387,7 @@
         }
     }
 
-
-    private static void tableswitch(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiRegister value, CiRegister scratch) {
+    private static void tableswitch(TargetMethodAssembler tasm, AMD64MacroAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) {
         Buffer buf = masm.codeBuffer;
         // Compare index against jump table bounds
         int highKey = lowKey + targets.length - 1;
@@ -246,15 +400,17 @@
         }
 
         // Jump to default target if index is not within the jump table
-        masm.jcc(ConditionFlag.above, defaultTarget.label());
+        if (defaultTarget != null) {
+            masm.jcc(ConditionFlag.above, defaultTarget.label());
+        }
 
         // Set scratch to address of jump table
         int leaPos = buf.position();
-        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), 0));
+        masm.leaq(scratch, new Address(tasm.target.wordKind, AMD64.rip.asValue(), 0));
         int afterLea = buf.position();
 
         // Load jump table entry into scratch and jump to it
-        masm.movslq(value, new CiAddress(CiKind.Int, scratch.asValue(), value.asValue(), Scale.Times4, 0));
+        masm.movslq(value, new Address(Kind.Int, scratch.asValue(), value.asValue(), Scale.Times4, 0));
         masm.addq(scratch, value);
         masm.jmp(scratch);
 
@@ -266,7 +422,7 @@
         // Patch LEA instruction above now that we know the position of the jump table
         int jumpTablePos = buf.position();
         buf.setPosition(leaPos);
-        masm.leaq(scratch, new CiAddress(tasm.target.wordKind, AMD64.rip.asValue(), jumpTablePos - afterLea));
+        masm.leaq(scratch, new Address(tasm.target.wordKind, AMD64.rip.asValue(), jumpTablePos - afterLea));
         buf.setPosition(jumpTablePos);
 
         // Emit jump table entries
@@ -279,7 +435,7 @@
             } else {
                 label.addPatchAt(buf.position());
 
-                buf.emitByte(0); // psuedo-opcode for jump table entry
+                buf.emitByte(0); // pseudo-opcode for jump table entry
                 buf.emitShort(offsetToJumpTableBase);
                 buf.emitByte(0); // padding to make jump table entry 4 bytes wide
             }
@@ -289,36 +445,34 @@
         tasm.targetMethod.addAnnotation(jt);
     }
 
-    private static void floatJcc(AMD64MacroAssembler masm, Condition condition, boolean unorderedIsTrue, Label label) {
-        ConditionFlag cond = floatCond(condition);
+    private static void floatJcc(AMD64MacroAssembler masm, ConditionFlag condition, boolean unorderedIsTrue, Label label) {
         Label endLabel = new Label();
-        if (unorderedIsTrue && !trueOnUnordered(cond)) {
+        if (unorderedIsTrue && !trueOnUnordered(condition)) {
             masm.jcc(ConditionFlag.parity, label);
-        } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
+        } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
             masm.jcc(ConditionFlag.parity, endLabel);
         }
-        masm.jcc(cond, label);
+        masm.jcc(condition, label);
         masm.bind(endLabel);
     }
 
-    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, boolean isFloat, Condition condition, boolean unorderedIsTrue, CiValue trueValue, CiValue falseValue) {
-        ConditionFlag cond = isFloat ? floatCond(condition) : intCond(condition);
+    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         // check that we don't overwrite an input operand before it is used.
         assert !result.equals(trueValue);
 
         AMD64Move.move(tasm, masm, result, falseValue);
-        cmove(tasm, masm, result, cond, trueValue);
+        cmove(tasm, masm, result, condition, trueValue);
 
         if (isFloat) {
-            if (unorderedIsTrue && !trueOnUnordered(cond)) {
+            if (unorderedIsTrue && !trueOnUnordered(condition)) {
                 cmove(tasm, masm, result, ConditionFlag.parity, trueValue);
-            } else if (!unorderedIsTrue && trueOnUnordered(cond)) {
+            } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
                 cmove(tasm, masm, result, ConditionFlag.parity, falseValue);
             }
         }
     }
 
-    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, ConditionFlag cond, CiValue other) {
+    private static void cmove(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, ConditionFlag cond, Value other) {
         if (isRegister(other)) {
             assert asRegister(other) != asRegister(result) : "other already overwritten by previous move";
             switch (other.kind) {
@@ -347,8 +501,6 @@
             case AE: return ConditionFlag.aboveEqual;
             case AT: return ConditionFlag.above;
             case BT: return ConditionFlag.below;
-            case OF: return ConditionFlag.overflow;
-            case NOF: return ConditionFlag.noOverflow;
             default: throw GraalInternalError.shouldNotReachHere();
         }
     }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64LIRInstruction.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64LIRInstruction.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.lir.amd64;
 
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
@@ -32,7 +32,7 @@
  */
 public abstract class AMD64LIRInstruction extends LIRInstruction {
 
-    public AMD64LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+    public AMD64LIRInstruction(Object opcode, Value[] outputs, LIRDebugInfo info, Value[] inputs, Value[] alives, Value[] temps) {
         super(opcode, outputs, info, inputs, alives, temps);
     }
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.lir.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static java.lang.Double.*;
 import static java.lang.Float.*;
 
@@ -30,7 +30,8 @@
 
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.*;
@@ -39,8 +40,8 @@
 public class AMD64Move {
 
     public static class SpillMoveOp extends AMD64LIRInstruction implements MoveOp {
-        public SpillMoveOp(CiValue result, CiValue input) {
-            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public SpillMoveOp(Value result, Value input) {
+            super("MOVE", new Value[] {result}, null, new Value[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
@@ -49,11 +50,11 @@
         }
 
         @Override
-        public CiValue getInput() {
+        public Value getInput() {
             return input(0);
         }
         @Override
-        public CiValue getResult() {
+        public Value getResult() {
             return output(0);
         }
 
@@ -70,8 +71,8 @@
 
 
     public static class MoveToRegOp extends AMD64LIRInstruction implements MoveOp {
-        public MoveToRegOp(CiValue result, CiValue input) {
-            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public MoveToRegOp(Value result, Value input) {
+            super("MOVE", new Value[] {result}, null, new Value[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
@@ -80,11 +81,11 @@
         }
 
         @Override
-        public CiValue getInput() {
+        public Value getInput() {
             return input(0);
         }
         @Override
-        public CiValue getResult() {
+        public Value getResult() {
             return output(0);
         }
 
@@ -101,8 +102,8 @@
 
 
     public static class MoveFromRegOp extends AMD64LIRInstruction implements MoveOp {
-        public MoveFromRegOp(CiValue result, CiValue input) {
-            super("MOVE", new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public MoveFromRegOp(Value result, Value input) {
+            super("MOVE", new Value[] {result}, null, new Value[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
@@ -111,11 +112,11 @@
         }
 
         @Override
-        public CiValue getInput() {
+        public Value getInput() {
             return input(0);
         }
         @Override
-        public CiValue getResult() {
+        public Value getResult() {
             return output(0);
         }
 
@@ -132,13 +133,13 @@
 
 
     public static class LoadOp extends AMD64LIRInstruction {
-        public LoadOp(CiValue result, CiValue address, LIRDebugInfo info) {
-            super("LOAD", new CiValue[] {result}, info, new CiValue[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public LoadOp(Value result, Value address, LIRDebugInfo info) {
+            super("LOAD", new Value[] {result}, info, new Value[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            load(tasm, masm, output(0), (CiAddress) input(0), info);
+            load(tasm, masm, output(0), (Address) input(0), info);
         }
 
         @Override
@@ -154,13 +155,13 @@
 
 
     public static class StoreOp extends AMD64LIRInstruction {
-        public StoreOp(CiValue address, CiValue input, LIRDebugInfo info) {
-            super("STORE", LIRInstruction.NO_OPERANDS, info, new CiValue[] {address, input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public StoreOp(Value address, Value input, LIRDebugInfo info) {
+            super("STORE", LIRInstruction.NO_OPERANDS, info, new Value[] {address, input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            store(tasm, masm, (CiAddress) input(0), input(1), info);
+            store(tasm, masm, (Address) input(0), input(1), info);
         }
 
         @Override
@@ -176,8 +177,8 @@
 
 
     public static class LeaOp extends AMD64LIRInstruction {
-        public LeaOp(CiValue result, CiValue address) {
-            super("LEA", new CiValue[] {result}, null, new CiValue[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public LeaOp(Value result, Value address) {
+            super("LEA", new Value[] {result}, null, new Value[] {address}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
@@ -219,7 +220,7 @@
 
     public static class NullCheckOp extends AMD64LIRInstruction {
         public NullCheckOp(Variable input, LIRDebugInfo info) {
-            super("NULL_CHECK", LIRInstruction.NO_OPERANDS, info, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+            super("NULL_CHECK", LIRInstruction.NO_OPERANDS, info, new Value[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
@@ -239,8 +240,8 @@
 
 
     public static class CompareAndSwapOp extends AMD64LIRInstruction {
-        public CompareAndSwapOp(CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
-            super("CAS", new CiValue[] {result}, null, new CiValue[] {address, cmpValue, newValue}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+        public CompareAndSwapOp(Value result, Address address, Value cmpValue, Value newValue) {
+            super("CAS", new Value[] {result}, null, new Value[] {address, cmpValue, newValue}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
         @Override
@@ -264,7 +265,7 @@
     }
 
 
-    public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+    public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
                 reg2reg(masm, result, input);
@@ -281,9 +282,9 @@
             }
         } else if (isConstant(input)) {
             if (isRegister(result)) {
-                const2reg(tasm, masm, result, (CiConstant) input);
+                const2reg(tasm, masm, result, (Constant) input);
             } else if (isStackSlot(result)) {
-                const2stack(tasm, masm, result, (CiConstant) input);
+                const2stack(tasm, masm, result, (Constant) input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
@@ -292,7 +293,7 @@
         }
     }
 
-    private static void reg2reg(AMD64MacroAssembler masm, CiValue result, CiValue input) {
+    private static void reg2reg(AMD64MacroAssembler masm, Value result, Value input) {
         if (input.equals(result)) {
             return;
         }
@@ -307,7 +308,7 @@
         }
     }
 
-    private static void reg2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+    private static void reg2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
         switch (input.kind) {
             case Jsr:
             case Int:    masm.movl(tasm.asAddress(result),   asRegister(input)); break;
@@ -319,7 +320,7 @@
         }
     }
 
-    private static void stack2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue input) {
+    private static void stack2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) {
         switch (input.kind) {
             case Jsr:
             case Int:    masm.movl(asRegister(result),    tasm.asAddress(input)); break;
@@ -331,7 +332,7 @@
         }
     }
 
-    private static void const2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant input) {
+    private static void const2reg(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
         // Note: we use the kind of the input operand (and not the kind of the result operand) because they don't match
         // in all cases. For example, an object constant can be loaded to a long register when unsafe casts occurred (e.g.,
         // for a write barrier where arithmetic operations are then performed on the pointer).
@@ -383,7 +384,7 @@
         }
     }
 
-    private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiConstant input) {
+    private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
         switch (input.kind.stackKind()) {
             case Jsr:
             case Int:    masm.movl(tasm.asAddress(result), input.asInt()); break;
@@ -403,7 +404,7 @@
     }
 
 
-    public static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress loadAddr, LIRDebugInfo info) {
+    public static void load(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Address loadAddr, LIRDebugInfo info) {
         if (info != null) {
             tasm.recordImplicitException(masm.codeBuffer.position(), info);
         }
@@ -421,7 +422,7 @@
         }
     }
 
-    public static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiAddress storeAddr, CiValue input, LIRDebugInfo info) {
+    public static void store(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Address storeAddr, Value input, LIRDebugInfo info) {
         if (info != null) {
             tasm.recordImplicitException(masm.codeBuffer.position(), info);
         }
@@ -440,7 +441,7 @@
                 default:     throw GraalInternalError.shouldNotReachHere();
             }
         } else if (isConstant(input)) {
-            CiConstant c = (CiConstant) input;
+            Constant c = (Constant) input;
             switch (storeAddr.kind) {
                 case Boolean:
                 case Byte:   masm.movb(storeAddr, c.asInt() & 0xFF); break;
@@ -473,7 +474,7 @@
         }
     }
 
-    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiAddress address, CiValue cmpValue, CiValue newValue) {
+    protected static void compareAndSwap(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Address address, Value cmpValue, Value newValue) {
         assert asRegister(cmpValue) == AMD64.rax && asRegister(result) == AMD64.rax;
 
         if (tasm.target.isMP) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,18 +22,18 @@
  */
 package com.oracle.graal.lir;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiCallingConvention.Type;
-import com.oracle.max.cri.ri.*;
 
 /**
  * This class is used to build the stack frame layout for a compiled method.
- * A {@link CiStackSlot} is used to index slots of the frame relative to the stack pointer.
+ * A {@link StackSlot} is used to index slots of the frame relative to the stack pointer.
  * The frame size is only fixed after register allocation when all spill slots have
  * been allocated. Both the outgoing argument area and the spill are can grow until then.
  * Therefore, outgoing arguments are indexed from the stack pointer, while spill slots
@@ -71,18 +71,18 @@
  * of such a block may be greater than the size of a normal spill slot or the word size.
  * <br>
  * A runtime has two ways to reserve space in the stack frame for its own use: <ul>
- * <li>A memory block somewhere in the frame of size {@link RiRuntime#getCustomStackAreaSize()}. The offset
- *     to this block is returned in {@link CiTargetMethod#customStackAreaOffset()}.
+ * <li>A memory block somewhere in the frame of size {@link CodeCacheProvider#getCustomStackAreaSize()}. The offset
+ *     to this block is returned in {@link CompilationResult#customStackAreaOffset()}.
  * <li>At the beginning of the overflow argument area: The calling convention can specify that the first
  *     overflow stack argument is not at offset 0, but at a specified offset o. Use
- *     {@link RiRuntime#getMinimumOutgoingSize()} to make sure that call-free methods also have this space
+ *     {@link CodeCacheProvider#getMinimumOutgoingSize()} to make sure that call-free methods also have this space
  *     reserved. Then the VM can use memory the memory at offset 0 relative to the stack pointer.
  * </ul>
  */
 public final class FrameMap {
-    public final RiRuntime runtime;
-    public final CiTarget target;
-    public final RiRegisterConfig registerConfig;
+    public final CodeCacheProvider runtime;
+    public final TargetDescription target;
+    public final RegisterConfig registerConfig;
 
     /**
      * The initial frame size, not including the size of the return address.
@@ -110,22 +110,22 @@
     /**
      * The list of stack areas allocated in this frame that are present in every reference map.
      */
-    private final List<CiStackSlot> objectStackBlocks;
+    private final List<StackSlot> objectStackBlocks;
 
     /**
      * The stack area reserved for use by the VM, or {@code null} if the VM does not request stack space.
      */
-    private final CiStackSlot customArea;
+    private final StackSlot customArea;
 
     /**
-     * Records whether an offset to an incoming stack argument was ever returned by {@link #offsetForStackSlot(CiStackSlot)}.
+     * Records whether an offset to an incoming stack argument was ever returned by {@link #offsetForStackSlot(StackSlot)}.
      */
     private boolean accessesCallerFrame;
 
     /**
      * Creates a new frame map for the specified method.
      */
-    public FrameMap(RiRuntime runtime, CiTarget target, RiRegisterConfig registerConfig) {
+    public FrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) {
         this.runtime = runtime;
         this.target = target;
         this.registerConfig = registerConfig;
@@ -142,12 +142,12 @@
     }
 
     private int calleeSaveAreaSize() {
-        CiCalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
+        CalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
         return csl != null ? csl.size : 0;
     }
 
     /**
-     * Determines if an offset to an incoming stack argument was ever returned by {@link #offsetForStackSlot(CiStackSlot)}.
+     * Determines if an offset to an incoming stack argument was ever returned by {@link #offsetForStackSlot(StackSlot)}.
      */
     public boolean accessesCallerFrame() {
         return accessesCallerFrame;
@@ -194,7 +194,7 @@
      * @param slot a stack slot
      * @return the offset of the stack slot
      */
-    public int offsetForStackSlot(CiStackSlot slot) {
+    public int offsetForStackSlot(StackSlot slot) {
         assert (!slot.rawAddFrameSize() && slot.rawOffset() < outgoingSize) ||
             (slot.rawAddFrameSize() && slot.rawOffset() < 0 && -slot.rawOffset() <= spillSize) ||
             (slot.rawAddFrameSize() && slot.rawOffset() >= 0);
@@ -226,7 +226,7 @@
      * @param cc The calling convention for the called method.
      * @param type The type of calling convention.
      */
-    public void callsMethod(CiCallingConvention cc, Type type) {
+    public void callsMethod(CallingConvention cc, Type type) {
         // TODO look at the actual stack offsets?
         assert type.out;
         reserveOutgoing(cc.stackSize);
@@ -241,8 +241,8 @@
         outgoingSize = Math.max(outgoingSize, argsSize);
     }
 
-    private CiStackSlot getSlot(CiKind kind, int additionalOffset) {
-        return CiStackSlot.get(kind, -spillSize + additionalOffset, true);
+    private StackSlot getSlot(Kind kind, int additionalOffset) {
+        return StackSlot.get(kind, -spillSize + additionalOffset, true);
     }
 
     /**
@@ -251,7 +251,7 @@
      * @param kind The kind of the spill slot to be reserved.
      * @return A spill slot denoting the reserved memory area.
      */
-    public CiStackSlot allocateSpillSlot(CiKind kind) {
+    public StackSlot allocateSpillSlot(Kind kind) {
         assert frameSize == -1 : "frame size must not yet be fixed";
         int size = target.sizeInBytes(kind);
         spillSize = NumUtil.roundUp(spillSize + size, size);
@@ -267,7 +267,7 @@
      *             The caller is responsible to initialize the memory block before the first instruction that uses a reference map.
      * @return A stack slot describing the begin of the memory block.
      */
-    public CiStackSlot allocateStackBlock(int size, boolean refs) {
+    public StackSlot allocateStackBlock(int size, boolean refs) {
         assert frameSize == -1 : "frame size must not yet be fixed";
         if (size == 0) {
             return null;
@@ -276,10 +276,10 @@
 
         if (refs) {
             assert size % target.wordSize == 0;
-            CiStackSlot result = getSlot(CiKind.Object, 0);
+            StackSlot result = getSlot(Kind.Object, 0);
             objectStackBlocks.add(result);
             for (int i = target.wordSize; i < size; i += target.wordSize) {
-                objectStackBlocks.add(getSlot(CiKind.Object, i));
+                objectStackBlocks.add(getSlot(Kind.Object, i));
             }
             return result;
 
@@ -289,7 +289,7 @@
     }
 
 
-    private int frameRefMapIndex(CiStackSlot slot) {
+    private int frameRefMapIndex(StackSlot slot) {
         assert offsetForStackSlot(slot) % target.wordSize == 0;
         return offsetForStackSlot(slot) / target.wordSize;
     }
@@ -297,8 +297,8 @@
     /**
      * Initializes a reference map that covers all registers of the target architecture.
      */
-    public CiBitMap initRegisterRefMap() {
-        return new CiBitMap(target.arch.registerReferenceMapBitCount);
+    public BitSet initRegisterRefMap() {
+        return new BitSet(target.arch.registerReferenceMapBitCount);
     }
 
     /**
@@ -306,9 +306,9 @@
      * slots in the frame. If the method has incoming reference arguments on the stack,
      * the reference map might grow later when such a reference is set.
      */
-    public CiBitMap initFrameRefMap() {
-        CiBitMap frameRefMap = new CiBitMap(frameSize() / target.wordSize);
-        for (CiStackSlot slot : objectStackBlocks) {
+    public BitSet initFrameRefMap() {
+        BitSet frameRefMap = new BitSet(frameSize() / target.wordSize);
+        for (StackSlot slot : objectStackBlocks) {
             setReference(slot, null, frameRefMap);
         }
         return frameRefMap;
@@ -316,21 +316,19 @@
 
     /**
      * Marks the specified location as a reference in the reference map of the debug information.
-     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
-     * {@link CiConstant} is automatically tracked.
+     * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a
+     * {@link Constant} is automatically tracked.
      *
      * @param location The location to be added to the reference map.
      * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
      * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
      */
-    public void setReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
-        if (location.kind == CiKind.Object) {
+    public void setReference(Value location, BitSet registerRefMap, BitSet frameRefMap) {
+        if (location.kind == Kind.Object) {
             if (isRegister(location)) {
-                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
                 registerRefMap.set(asRegister(location).number);
             } else if (isStackSlot(location)) {
                 int index = frameRefMapIndex(asStackSlot(location));
-                frameRefMap.grow(index + 1);
                 frameRefMap.set(index);
             } else {
                 assert isConstant(location);
@@ -340,17 +338,16 @@
 
     /**
      * Clears the specified location as a reference in the reference map of the debug information.
-     * The tracked location can be a {@link CiRegisterValue} or a {@link CiStackSlot}. Note that a
-     * {@link CiConstant} is automatically tracked.
+     * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a
+     * {@link Constant} is automatically tracked.
      *
      * @param location The location to be removed from the reference map.
      * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
      * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
      */
-    public void clearReference(CiValue location, CiBitMap registerRefMap, CiBitMap frameRefMap) {
-        if (location.kind == CiKind.Object) {
-            if (location instanceof CiRegisterValue) {
-                assert registerRefMap.size() == target.arch.registerReferenceMapBitCount;
+    public void clearReference(Value location, BitSet registerRefMap, BitSet frameRefMap) {
+        if (location.kind == Kind.Object) {
+            if (location instanceof RegisterValue) {
                 registerRefMap.clear(asRegister(location).number);
             } else if (isStackSlot(location)) {
                 int index = frameRefMapIndex(asStackSlot(location));
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,11 +24,12 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.cfg.*;
+import com.oracle.graal.nodes.*;
 
 /**
  * This class implements the overall container for the LIR graph
@@ -42,7 +43,7 @@
      * The nodes for the blocks.
      * TODO: This should go away, we want all nodes connected with a next-pointer.
      */
-    private final BlockMap<List<Node>> blockToNodesMap;
+    private final BlockMap<List<ScheduledNode>> blockToNodesMap;
 
     /**
      * The linear-scan ordered list of blocks.
@@ -65,8 +66,8 @@
     public SpillMoveFactory spillMoveFactory;
 
     public interface SpillMoveFactory {
-        LIRInstruction createMove(CiValue result, CiValue input);
-        LIRInstruction createExchange(CiValue input1, CiValue input2);
+        LIRInstruction createMove(Value result, Value input);
+        LIRInstruction createExchange(Value input1, Value input2);
     }
 
     private boolean hasArgInCallerFrame;
@@ -87,7 +88,7 @@
      * @param numLoops number of loops
      * @param compilation the compilation
      */
-    public LIR(ControlFlowGraph cfg, BlockMap<List<Node>> blockToNodesMap, List<Block> linearScanOrder, List<Block> codeEmittingOrder) {
+    public LIR(ControlFlowGraph cfg, BlockMap<List<ScheduledNode>> blockToNodesMap, List<Block> linearScanOrder, List<Block> codeEmittingOrder) {
         this.cfg = cfg;
         this.blockToNodesMap = blockToNodesMap;
         this.codeEmittingOrder = codeEmittingOrder;
@@ -99,7 +100,7 @@
     /**
      * Gets the nodes in a given block.
      */
-    public List<Node> nodesFor(Block block) {
+    public List<ScheduledNode> nodesFor(Block block) {
         return blockToNodesMap.get(block);
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRDebugInfo.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRDebugInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.lir;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
@@ -35,13 +36,13 @@
  * This class represents garbage collection and deoptimization information attached to a LIR instruction.
  */
 public class LIRDebugInfo {
-    public final CiFrame topFrame;
-    private final CiVirtualObject[] virtualObjects;
-    private final List<CiStackSlot> pointerSlots;
+    public final BytecodeFrame topFrame;
+    private final VirtualObject[] virtualObjects;
+    private final List<StackSlot> pointerSlots;
     public final LabelRef exceptionEdge;
-    private CiDebugInfo debugInfo;
+    private DebugInfo debugInfo;
 
-    public LIRDebugInfo(CiFrame topFrame, CiVirtualObject[] virtualObjects, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) {
+    public LIRDebugInfo(BytecodeFrame topFrame, VirtualObject[] virtualObjects, List<StackSlot> pointerSlots, LabelRef exceptionEdge) {
         this.topFrame = topFrame;
         this.virtualObjects = virtualObjects;
         this.pointerSlots = pointerSlots;
@@ -52,7 +53,7 @@
         return debugInfo != null;
     }
 
-    public CiDebugInfo debugInfo() {
+    public DebugInfo debugInfo() {
         assert debugInfo != null : "debug info not allocated yet";
         return debugInfo;
     }
@@ -63,11 +64,11 @@
      * @param proc The procedure called for variables.
      */
     public void forEachState(ValueProcedure proc) {
-        for (CiFrame cur = topFrame; cur != null; cur = cur.caller()) {
+        for (BytecodeFrame cur = topFrame; cur != null; cur = cur.caller()) {
             processValues(cur.values, proc);
         }
         if (virtualObjects != null) {
-            for (CiVirtualObject obj : virtualObjects) {
+            for (VirtualObject obj : virtualObjects) {
                 processValues(obj.values(), proc);
             }
         }
@@ -78,13 +79,13 @@
      */
     private static final EnumSet<OperandFlag> STATE_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Stack);
 
-    private void processValues(CiValue[] values, ValueProcedure proc) {
+    private void processValues(Value[] values, ValueProcedure proc) {
         for (int i = 0; i < values.length; i++) {
-            CiValue value = values[i];
-            if (value instanceof CiMonitorValue) {
-                CiMonitorValue monitor = (CiMonitorValue) value;
-                if (processed(monitor.owner)) {
-                    monitor.owner = proc.doValue(monitor.owner, OperandMode.Alive, STATE_FLAGS);
+            Value value = values[i];
+            if (value instanceof MonitorValue) {
+                MonitorValue monitor = (MonitorValue) value;
+                if (processed(monitor.getOwner())) {
+                    monitor.setOwner(proc.doValue(monitor.getOwner(), OperandMode.Alive, STATE_FLAGS));
                 }
 
             } else if (processed(value)) {
@@ -93,7 +94,7 @@
         }
     }
 
-    private boolean processed(CiValue value) {
+    private boolean processed(Value value) {
         if (isIllegal(value)) {
             // Ignore dead local variables.
             return false;
@@ -109,12 +110,12 @@
     }
 
 
-    public void finish(CiBitMap registerRefMap, CiBitMap frameRefMap, FrameMap frameMap) {
-        debugInfo = new CiDebugInfo(topFrame, registerRefMap, frameRefMap);
+    public void finish(BitSet registerRefMap, BitSet frameRefMap, FrameMap frameMap) {
+        debugInfo = new DebugInfo(topFrame, registerRefMap, frameRefMap);
 
         // Add additional stack slots for outgoing method parameters.
         if (pointerSlots != null) {
-            for (CiStackSlot v : pointerSlots) {
+            for (StackSlot v : pointerSlots) {
                 frameMap.setReference(v, registerRefMap, frameRefMap);
             }
         }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.lir;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.asm.*;
 
@@ -35,7 +36,7 @@
  */
 public abstract class LIRInstruction {
 
-    public static final CiValue[] NO_OPERANDS = {};
+    public static final Value[] NO_OPERANDS = {};
 
     /**
      * Iterator for iterating over a list of values. Subclasses must overwrite one of the doValue methods.
@@ -49,7 +50,7 @@
          * @param value The value that is iterated.
          * @return The new value to replace the value that was passed in.
          */
-        protected CiValue doValue(CiValue value) {
+        protected Value doValue(Value value) {
             throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten");
         }
 
@@ -62,7 +63,7 @@
          * @param flags A set of flags for the value.
          * @return The new value to replace the value that was passed in.
          */
-        public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+        public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
             return doValue(value);
         }
     }
@@ -105,22 +106,22 @@
      */
     public enum OperandFlag {
         /**
-         * The value can be a {@link CiRegisterValue}.
+         * The value can be a {@link RegisterValue}.
          */
         Register,
 
         /**
-         * The value can be a {@link CiStackSlot}.
+         * The value can be a {@link StackSlot}.
          */
         Stack,
 
         /**
-         * The value can be a {@link CiAddress}.
+         * The value can be a {@link Address}.
          */
         Address,
 
         /**
-         * The value can be a {@link CiConstant}.
+         * The value can be a {@link Constant}.
          */
         Constant,
 
@@ -163,22 +164,22 @@
     /**
      * The output operands for this instruction (modified by the register allocator).
      */
-    protected CiValue[] outputs;
+    protected Value[] outputs;
 
     /**
      * The input operands for this instruction (modified by the register allocator).
      */
-    protected CiValue[] inputs;
+    protected Value[] inputs;
 
     /**
      * The alive operands for this instruction (modified by the register allocator).
      */
-    protected CiValue[] alives;
+    protected Value[] alives;
 
     /**
      * The temp operands for this instruction (modified by the register allocator).
      */
-    protected CiValue[] temps;
+    protected Value[] temps;
 
     /**
      * Used to emit debug information.
@@ -199,7 +200,7 @@
      * @param inputs the input operands for the instruction.
      * @param temps the temp operands for the instruction.
      */
-    public LIRInstruction(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps) {
+    public LIRInstruction(Object opcode, Value[] outputs, LIRDebugInfo info, Value[] inputs, Value[] alives, Value[] temps) {
         this.code = opcode;
         this.outputs = outputs;
         this.inputs = inputs;
@@ -226,7 +227,7 @@
      * @param index the index of the operand requested.
      * @return the {@code index}'th input operand.
      */
-    protected final CiValue input(int index) {
+    protected final Value input(int index) {
         return inputs[index];
     }
 
@@ -236,7 +237,7 @@
      * @param index the index of the operand requested.
      * @return the {@code index}'th alive operand.
      */
-    protected final CiValue alive(int index) {
+    protected final Value alive(int index) {
         return alives[index];
     }
 
@@ -246,7 +247,7 @@
      * @param index the index of the operand requested.
      * @return the {@code index}'th temp operand.
      */
-    protected final CiValue temp(int index) {
+    protected final Value temp(int index) {
         return temps[index];
     }
 
@@ -255,7 +256,7 @@
      *
      * @return return the result operand
      */
-    protected final CiValue output(int index) {
+    protected final Value output(int index) {
         return outputs[index];
     }
 
@@ -272,16 +273,16 @@
 
     private static final EnumSet<OperandFlag> ADDRESS_FLAGS = EnumSet.of(OperandFlag.Register, OperandFlag.Illegal);
 
-    private void forEach(CiValue[] values, OperandMode mode, ValueProcedure proc) {
+    private void forEach(Value[] values, OperandMode mode, ValueProcedure proc) {
         for (int i = 0; i < values.length; i++) {
             assert ALLOWED_FLAGS.get(mode).containsAll(flagsFor(mode, i));
 
-            CiValue value = values[i];
+            Value value = values[i];
             if (isAddress(value)) {
                 assert flagsFor(mode, i).contains(OperandFlag.Address);
-                CiAddress address = asAddress(value);
-                address.base = proc.doValue(address.base, mode, ADDRESS_FLAGS);
-                address.index = proc.doValue(address.index, mode, ADDRESS_FLAGS);
+                Address address = asAddress(value);
+                address.setBase(proc.doValue(address.getBase(), mode, ADDRESS_FLAGS));
+                address.setIndex(proc.doValue(address.getIndex(), mode, ADDRESS_FLAGS));
             } else {
                 values[i] = proc.doValue(values[i], mode, flagsFor(mode, i));
             }
@@ -337,8 +338,8 @@
      *             and the value is returned by this method, i.e., clients can stop the iteration once a suitable hint has been found.
      * @return The non-null value returned by the procedure, or null.
      */
-    public CiValue forEachRegisterHint(CiValue value, OperandMode mode, ValueProcedure proc) {
-        CiValue[] hints;
+    public Value forEachRegisterHint(Value value, OperandMode mode, ValueProcedure proc) {
+        Value[] hints;
         if (mode == OperandMode.Input) {
             hints = outputs;
         } else if (mode == OperandMode.Output) {
@@ -348,7 +349,7 @@
         }
 
         for (int i = 0; i < hints.length; i++) {
-            CiValue result = proc.doValue(hints[i], null, null);
+            Value result = proc.doValue(hints[i], null, null);
             if (result != null) {
                 return result;
             }
@@ -385,7 +386,7 @@
         if (outputs.length > 1) {
             buf.append("(");
         }
-        for (CiValue output : outputs) {
+        for (Value output : outputs) {
             buf.append(sep).append(output);
             sep = ", ";
         }
@@ -400,11 +401,11 @@
             buf.append("(");
         }
         sep = "";
-        for (CiValue input : inputs) {
+        for (Value input : inputs) {
             buf.append(sep).append(input);
             sep = ", ";
         }
-        for (CiValue input : alives) {
+        for (Value input : alives) {
             buf.append(sep).append(input).append(" ~");
             sep = ", ";
         }
@@ -416,7 +417,7 @@
             buf.append(" [");
         }
         sep = "";
-        for (CiValue temp : temps) {
+        for (Value temp : temps) {
             buf.append(sep).append(temp);
             sep = ", ";
         }
@@ -430,8 +431,8 @@
         if (info != null) {
             buf.append(" [bci:");
             String sep = "";
-            for (CiFrame cur = info.topFrame; cur != null; cur = cur.caller()) {
-                buf.append(sep).append(cur.bci);
+            for (BytecodeFrame cur = info.topFrame; cur != null; cur = cur.caller()) {
+                buf.append(sep).append(cur.getBCI());
                 sep = ",";
             }
             buf.append("]");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRValueUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+public class LIRValueUtil extends ValueUtil {
+    public static boolean isVariable(Value value) {
+        assert value != null;
+        return value instanceof Variable;
+    }
+
+    public static Variable asVariable(Value value) {
+        assert value != null;
+        return (Variable) value;
+    }
+}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.lir;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-import static com.oracle.graal.lir.ValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.LIRInstruction.*;
 import com.oracle.graal.lir.cfg.*;
@@ -53,12 +54,12 @@
         return frameMap.target.arch.registers.length;
     }
 
-    private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+    private boolean isAllocatableRegister(Value value) {
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable();
     }
 
     public static boolean verify(final LIRInstruction op) {
-        ValueProcedure allowedProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return allowed(op, value, mode, flags); } };
+        ValueProcedure allowedProc = new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return allowed(op, value, mode, flags); } };
 
         op.forEachInput(allowedProc);
         op.forEachAlive(allowedProc);
@@ -86,21 +87,21 @@
     }
 
     private BitSet curVariablesLive;
-    private CiValue[] curRegistersLive;
+    private Value[] curRegistersLive;
 
     private Block curBlock;
     private Object curInstruction;
     private BitSet curRegistersDefined;
 
     private void verify() {
-        ValueProcedure useProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
-        ValueProcedure defProc = new ValueProcedure() { @Override public CiValue doValue(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
+        ValueProcedure useProc = new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return use(value, mode, flags); } };
+        ValueProcedure defProc = new ValueProcedure() { @Override public Value doValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) { return def(value, mode, flags); } };
 
         curRegistersDefined = new BitSet();
         for (Block block : lir.linearScanOrder()) {
             curBlock = block;
             curVariablesLive = new BitSet();
-            curRegistersLive = new CiValue[maxRegisterNum()];
+            curRegistersLive = new Value[maxRegisterNum()];
 
             if (block.getDominator() != null) {
                 curVariablesLive.or(liveOutFor(block.getDominator()));
@@ -109,7 +110,7 @@
             assert block.lir.get(0) instanceof StandardOp.LabelOp : "block must start with label";
             if (block.numberOfPreds() > 1) {
                 assert block.lir.get(0) instanceof StandardOp.PhiLabelOp : "phi mapping required for multiple predecessors";
-                CiValue[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions();
+                Value[] phiDefinitions = ((StandardOp.PhiLabelOp) block.lir.get(0)).getPhiDefinitions();
                 if (!beforeRegisterAllocation) {
                     assert phiDefinitions.length == 0;
                 }
@@ -117,7 +118,7 @@
                     assert pred.numberOfSux() == 1;
                     LIRInstruction last = pred.lir.get(pred.lir.size() - 1);
                     assert last instanceof StandardOp.PhiJumpOp : "phi mapping required for multiple successors";
-                    CiValue[] phiUses = ((StandardOp.PhiJumpOp) last).getPhiInputs();
+                    Value[] phiUses = ((StandardOp.PhiJumpOp) last).getPhiInputs();
                     if (!beforeRegisterAllocation) {
                         assert phiUses.length == 0;
                     }
@@ -134,7 +135,7 @@
 
                 op.forEachInput(useProc);
                 if (op.hasCall()) {
-                    for (CiRegister register : frameMap.registerConfig.getCallerSaveRegisters()) {
+                    for (Register register : frameMap.registerConfig.getCallerSaveRegisters()) {
                         curRegistersLive[register.number] = null;
                     }
                 }
@@ -151,7 +152,7 @@
         }
     }
 
-    private CiValue use(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private Value use(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         allowed(curInstruction, value, mode, flags);
 
         if (isVariable(value)) {
@@ -184,7 +185,7 @@
         return value;
     }
 
-    private CiValue def(CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private Value def(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         allowed(curInstruction, value, mode, flags);
 
         if (isVariable(value)) {
@@ -225,7 +226,7 @@
         return value;
     }
 
-    private static CiValue allowed(Object op, CiValue value, OperandMode mode, EnumSet<OperandFlag> flags) {
+    private static Value allowed(Object op, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
         if ((isVariable(value)  && flags.contains(OperandFlag.Register)) ||
             (isRegister(value)  && flags.contains(OperandFlag.Register)) ||
             (isStackSlot(value) && flags.contains(OperandFlag.Stack)) ||
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRXirInstruction.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRXirInstruction.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,17 +22,17 @@
  */
 package com.oracle.graal.lir;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.xir.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 
 public abstract class LIRXirInstruction extends LIRInstruction {
 
-    public final CiValue[] originalOperands;
+    public final Value[] originalOperands;
     public final int outputOperandIndex;
     public final int[] inputOperandIndices;
     public final int[] tempOperandIndices;
@@ -43,9 +43,9 @@
 
     public LIRXirInstruction(Object opcode,
                              XirSnippet snippet,
-                             CiValue[] originalOperands,
-                             CiValue outputOperand,
-                             CiValue[] inputs, CiValue[] temps,
+                             Value[] originalOperands,
+                             Value outputOperand,
+                             Value[] inputs, Value[] temps,
                              int[] inputOperandIndices, int[] tempOperandIndices,
                              int outputOperandIndex,
                              LIRDebugInfo info,
@@ -54,7 +54,7 @@
                              LabelRef falseSuccessor) {
         // Note that we register the XIR input operands as Alive, because the XIR specification allows that input operands
         // are used at any time, even when the temp operands and the actual output operands have already be assigned.
-        super(opcode, isLegal(outputOperand) ? new CiValue[] {outputOperand} : LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, inputs, temps);
+        super(opcode, isLegal(outputOperand) ? new Value[] {outputOperand} : LIRInstruction.NO_OPERANDS, info, LIRInstruction.NO_OPERANDS, inputs, temps);
         this.infoAfter = infoAfter;
         this.snippet = snippet;
         this.inputOperandIndices = inputOperandIndices;
@@ -76,7 +76,7 @@
         throw GraalInternalError.shouldNotReachHere();
     }
 
-    public CiValue[] getOperands() {
+    public Value[] getOperands() {
         for (int i = 0; i < inputOperandIndices.length; i++) {
             originalOperands[inputOperandIndices[i]] = alive(i);
         }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.asm.*;
 
@@ -35,7 +35,16 @@
  */
 public class StandardOp {
 
-    private static CiValue[] EMPTY = new CiValue[0];
+    private static Value[] EMPTY = new Value[0];
+
+    /**
+     * Marker interface for LIR ops that can fall through to the next operation, like a switch statement.
+     * setFallThroughTarget(null) can be used to make the operation fall through to the next one.
+     */
+    public interface FallThroughOp {
+        LabelRef fallThroughTarget();
+        void setFallThroughTarget(LabelRef target);
+    }
 
     /**
      * LIR operation that defines the position of a label.
@@ -45,7 +54,7 @@
         private final Label label;
         private final boolean align;
 
-        protected LabelOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, Label label, boolean align) {
+        protected LabelOp(Object opcode, Value[] outputs, LIRDebugInfo info, Value[] inputs, Value[] alives, Value[] temps, Label label, boolean align) {
             super(opcode, outputs, info, inputs, alives, temps);
             this.label = label;
             this.align = align;
@@ -79,7 +88,7 @@
     }
 
     public static class PhiLabelOp extends LabelOp {
-        public PhiLabelOp(Label label, boolean align, CiValue[] phiDefinitions) {
+        public PhiLabelOp(Label label, boolean align, Value[] phiDefinitions) {
             super("PHI_LABEL", phiDefinitions, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, label, align);
         }
 
@@ -95,7 +104,7 @@
             outputs = EMPTY;
         }
 
-        public CiValue[] getPhiDefinitions() {
+        public Value[] getPhiDefinitions() {
             return outputs;
         }
     }
@@ -110,7 +119,7 @@
     public static class JumpOp extends LIRInstruction {
         private final LabelRef destination;
 
-        protected JumpOp(Object opcode, CiValue[] outputs, LIRDebugInfo info, CiValue[] inputs, CiValue[] alives, CiValue[] temps, LabelRef destination) {
+        protected JumpOp(Object opcode, Value[] outputs, LIRDebugInfo info, Value[] inputs, Value[] alives, Value[] temps, LabelRef destination) {
             super(opcode, outputs, info, inputs, alives, temps);
             this.destination = destination;
         }
@@ -140,7 +149,7 @@
     }
 
     public static class PhiJumpOp extends JumpOp {
-        public PhiJumpOp(LabelRef destination, CiValue[] phiInputs) {
+        public PhiJumpOp(LabelRef destination, Value[] phiInputs) {
             super("PHI_JUMP", LIRInstruction.NO_OPERANDS, null, LIRInstruction.NO_OPERANDS, phiInputs, LIRInstruction.NO_OPERANDS, destination);
         }
 
@@ -156,7 +165,7 @@
             alives = EMPTY;
         }
 
-        public CiValue[] getPhiInputs() {
+        public Value[] getPhiInputs() {
             return alives;
         }
     }
@@ -174,8 +183,8 @@
      * Marker interface for a LIR operation that moves a value from {@link #getInput()} to {@link #getResult()}.
      */
     public interface MoveOp {
-        CiValue getInput();
-        CiValue getResult();
+        Value getInput();
+        Value getResult();
     }
 
     /**
@@ -191,7 +200,7 @@
      * In particular, it is not the actual method prologue.
      */
     public static final class ParametersOp extends LIRInstruction {
-        public ParametersOp(CiValue[] params) {
+        public ParametersOp(Value[] params) {
             super("PARAMS", params, null, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
         }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ValueUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.lir;
-
-import com.oracle.max.cri.ci.*;
-
-public class ValueUtil extends CiValueUtil {
-
-    public static boolean isVariable(CiValue value) {
-        assert value != null;
-        return value instanceof Variable;
-    }
-
-    public static Variable asVariable(CiValue value) {
-        assert value != null;
-        return (Variable) value;
-    }
-}
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.lir;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 
 /**
  * Represents a value that is yet to be bound to a machine location (such as
- * a {@link CiRegisterValue} or {@link CiStackSlot}) by a register allocator.
+ * a {@link RegisterValue} or {@link StackSlot}) by a register allocator.
  */
-public final class Variable extends CiValue {
+public final class Variable extends Value {
     private static final long serialVersionUID = 4507578431686109809L;
 
     /**
@@ -39,14 +40,14 @@
     /**
      * The type of register that this variable needs to get assigned.
      */
-    public final CiRegister.RegisterFlag flag;
+    public final Register.RegisterFlag flag;
 
     /**
      * Creates a new variable.
      * @param kind
      * @param index
      */
-    public Variable(CiKind kind, int index, CiRegister.RegisterFlag flag) {
+    public Variable(Kind kind, int index, Register.RegisterFlag flag) {
         super(kind);
         assert kind == kind.stackKind() : "Variables can be only created for stack kinds";
         assert index >= 0;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,17 +22,17 @@
  */
 package com.oracle.graal.lir.asm;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIR.Code;
 import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 
 public class TargetMethodAssembler {
 
@@ -47,9 +47,9 @@
     }
 
     public final AbstractAssembler asm;
-    public final CiTargetMethod targetMethod;
-    public final CiTarget target;
-    public final RiRuntime runtime;
+    public final CompilationResult targetMethod;
+    public final TargetDescription target;
+    public final CodeCacheProvider runtime;
     public final FrameMap frameMap;
 
     /**
@@ -66,13 +66,13 @@
     private List<ExceptionInfo> exceptionInfoList;
     private int lastSafepointPos;
 
-    public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, List<Code> stubs) {
+    public TargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, List<Code> stubs) {
         this.target = target;
         this.runtime = runtime;
         this.frameMap = frameMap;
         this.stubs = stubs;
         this.asm = asm;
-        this.targetMethod = new CiTargetMethod();
+        this.targetMethod = new CompilationResult();
         this.frameContext = frameContext;
         // 0 is a valid pc for safepoints in template methods
         this.lastSafepointPos = -1;
@@ -82,19 +82,19 @@
         targetMethod.setFrameSize(frameSize);
     }
 
-    public CiTargetMethod.Mark recordMark(Object id) {
+    public CompilationResult.Mark recordMark(Object id) {
         return targetMethod.recordMark(asm.codeBuffer.position(), id, null);
     }
 
-    public CiTargetMethod.Mark recordMark(Object id, CiTargetMethod.Mark[] references) {
+    public CompilationResult.Mark recordMark(Object id, CompilationResult.Mark[] references) {
         return targetMethod.recordMark(asm.codeBuffer.position(), id, references);
     }
 
     public void blockComment(String s) {
-        targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s));
+        targetMethod.addAnnotation(new CompilationResult.CodeComment(asm.codeBuffer.position(), s));
     }
 
-    public CiTargetMethod finishTargetMethod(Object name, boolean isStub) {
+    public CompilationResult finishTargetMethod(Object name, boolean isStub) {
         // Install code, data and frame size
         targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
 
@@ -108,9 +108,9 @@
 
         Debug.metric("TargetMethods").increment();
         Debug.metric("CodeBytesEmitted").add(targetMethod.targetCodeSize());
-        Debug.metric("SafepointsEmitted").add(targetMethod.safepoints.size());
-        Debug.metric("DataPatches").add(targetMethod.dataReferences.size());
-        Debug.metric("ExceptionHandlersEmitted").add(targetMethod.exceptionHandlers.size());
+        Debug.metric("SafepointsEmitted").add(targetMethod.getSafepoints().size());
+        Debug.metric("DataPatches").add(targetMethod.getDataReferences().size());
+        Debug.metric("ExceptionHandlersEmitted").add(targetMethod.getExceptionHandlers().size());
 
         Debug.log("Finished target method %s, isStub %b", name, isStub);
 /*
@@ -181,14 +181,14 @@
     }
 
     public void recordDirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
-        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        DebugInfo debugInfo = info != null ? info.debugInfo() : null;
         assert lastSafepointPos < posAfter;
         lastSafepointPos = posAfter;
         targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, true);
     }
 
     public void recordIndirectCall(int posBefore, int posAfter, Object callTarget, LIRDebugInfo info) {
-        CiDebugInfo debugInfo = info != null ? info.debugInfo() : null;
+        DebugInfo debugInfo = info != null ? info.debugInfo() : null;
         assert lastSafepointPos < posAfter;
         lastSafepointPos = posAfter;
         targetMethod.recordCall(posBefore, posAfter - posBefore, callTarget, debugInfo, false);
@@ -196,18 +196,18 @@
 
     public void recordSafepoint(int pos, LIRDebugInfo info) {
         // safepoints always need debug info
-        CiDebugInfo debugInfo = info.debugInfo();
+        DebugInfo debugInfo = info.debugInfo();
         assert lastSafepointPos < pos;
         lastSafepointPos = pos;
         targetMethod.recordSafepoint(pos, debugInfo);
     }
 
-    public CiAddress recordDataReferenceInCode(CiConstant data, int alignment) {
+    public Address recordDataReferenceInCode(Constant data, int alignment) {
         assert data != null;
         int pos = asm.codeBuffer.position();
         Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
         targetMethod.recordDataReference(pos, data, alignment);
-        return CiAddress.Placeholder;
+        return Address.Placeholder;
     }
 
     public int lastSafepointPos() {
@@ -219,9 +219,9 @@
      * Returns the integer value of any constants that can be represented by a 32-bit integer value,
      * including long constants that fit into the 32-bit range.
      */
-    public int asIntConst(CiValue value) {
-        assert (value.kind.stackKind() == CiKind.Int || value.kind == CiKind.Jsr || value.kind == CiKind.Long) && isConstant(value);
-        long c = ((CiConstant) value).asLong();
+    public int asIntConst(Value value) {
+        assert (value.kind.stackKind() == Kind.Int || value.kind == Kind.Jsr || value.kind == Kind.Long) && isConstant(value);
+        long c = ((Constant) value).asLong();
         if (!(NumUtil.isInt(c))) {
             throw GraalInternalError.shouldNotReachHere();
         }
@@ -231,65 +231,65 @@
     /**
      * Returns the address of a float constant that is embedded as a data references into the code.
      */
-    public CiAddress asFloatConstRef(CiValue value) {
+    public Address asFloatConstRef(Value value) {
         return asFloatConstRef(value, 4);
     }
 
-    public CiAddress asFloatConstRef(CiValue value, int alignment) {
-        assert value.kind == CiKind.Float && isConstant(value);
-        return recordDataReferenceInCode((CiConstant) value, alignment);
+    public Address asFloatConstRef(Value value, int alignment) {
+        assert value.kind == Kind.Float && isConstant(value);
+        return recordDataReferenceInCode((Constant) value, alignment);
     }
 
     /**
      * Returns the address of a double constant that is embedded as a data references into the code.
      */
-    public CiAddress asDoubleConstRef(CiValue value) {
+    public Address asDoubleConstRef(Value value) {
         return asDoubleConstRef(value, 8);
     }
 
-    public CiAddress asDoubleConstRef(CiValue value, int alignment) {
-        assert value.kind == CiKind.Double && isConstant(value);
-        return recordDataReferenceInCode((CiConstant) value, alignment);
+    public Address asDoubleConstRef(Value value, int alignment) {
+        assert value.kind == Kind.Double && isConstant(value);
+        return recordDataReferenceInCode((Constant) value, alignment);
     }
 
     /**
      * Returns the address of a long constant that is embedded as a data references into the code.
      */
-    public CiAddress asLongConstRef(CiValue value) {
-        assert value.kind == CiKind.Long && isConstant(value);
-        return recordDataReferenceInCode((CiConstant) value, 8);
+    public Address asLongConstRef(Value value) {
+        assert value.kind == Kind.Long && isConstant(value);
+        return recordDataReferenceInCode((Constant) value, 8);
     }
 
-    public CiAddress asIntAddr(CiValue value) {
-        assert value.kind == CiKind.Int;
+    public Address asIntAddr(Value value) {
+        assert value.kind == Kind.Int;
         return asAddress(value);
     }
 
-    public CiAddress asLongAddr(CiValue value) {
-        assert value.kind == CiKind.Long;
+    public Address asLongAddr(Value value) {
+        assert value.kind == Kind.Long;
         return asAddress(value);
     }
 
-    public CiAddress asObjectAddr(CiValue value) {
-        assert value.kind == CiKind.Object;
+    public Address asObjectAddr(Value value) {
+        assert value.kind == Kind.Object;
         return asAddress(value);
     }
 
-    public CiAddress asFloatAddr(CiValue value) {
-        assert value.kind == CiKind.Float;
+    public Address asFloatAddr(Value value) {
+        assert value.kind == Kind.Float;
         return asAddress(value);
     }
 
-    public CiAddress asDoubleAddr(CiValue value) {
-        assert value.kind == CiKind.Double;
+    public Address asDoubleAddr(Value value) {
+        assert value.kind == Kind.Double;
         return asAddress(value);
     }
 
-    public CiAddress asAddress(CiValue value) {
+    public Address asAddress(Value value) {
         if (isStackSlot(value)) {
-            CiStackSlot slot = (CiStackSlot) value;
-            return new CiAddress(slot.kind, frameMap.registerConfig.getFrameRegister().asValue(), frameMap.offsetForStackSlot(slot));
+            StackSlot slot = (StackSlot) value;
+            return new Address(slot.kind, frameMap.registerConfig.getFrameRegister().asValue(), frameMap.offsetForStackSlot(slot));
         }
-        return (CiAddress) value;
+        return (Address) value;
     }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/cfg/Block.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/cfg/Block.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -33,7 +32,7 @@
     protected int id;
 
     protected BeginNode beginNode;
-    protected Node endNode;
+    protected FixedNode endNode;
     protected Loop loop;
     protected double probability;
 
@@ -62,7 +61,7 @@
         return beginNode;
     }
 
-    public Node getEndNode() {
+    public FixedNode getEndNode() {
         return endNode;
     }
 
@@ -122,8 +121,8 @@
         return postdominator;
     }
 
-    private class NodeIterator implements Iterator<Node> {
-        private Node cur;
+    private class NodeIterator implements Iterator<FixedNode> {
+        private FixedNode cur;
 
         public NodeIterator() {
             cur = getBeginNode();
@@ -135,8 +134,8 @@
         }
 
         @Override
-        public Node next() {
-            Node result = cur;
+        public FixedNode next() {
+            FixedNode result = cur;
             if (cur == getEndNode()) {
                 cur = null;
             } else {
@@ -152,10 +151,10 @@
         }
     }
 
-    public Iterable<Node> getNodes() {
-        return new Iterable<Node>() {
+    public Iterable<FixedNode> getNodes() {
+        return new Iterable<FixedNode>() {
             @Override
-            public Iterator<Node> iterator() {
+            public Iterator<FixedNode> iterator() {
                 return new NodeIterator();
             }
         };
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/cfg/ControlFlowGraph.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/cfg/ControlFlowGraph.java	Wed Jun 27 17:35:32 2012 +0200
@@ -68,6 +68,31 @@
         return reversePostOrder[0];
     }
 
+    public Iterable<Block> postOrder() {
+        return new Iterable<Block>() {
+            @Override
+            public Iterator<Block> iterator() {
+                return new Iterator<Block>() {
+                    private int nextIndex = reversePostOrder.length - 1;
+                    @Override
+                    public boolean hasNext() {
+                        return nextIndex >= 0;
+                    }
+
+                    @Override
+                    public Block next() {
+                        return reversePostOrder[nextIndex--];
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException();
+                    }
+                };
+            }
+        };
+    }
+
     public NodeMap<Block> getNodeToBlock() {
         return nodeToBlock;
     }
@@ -93,9 +118,9 @@
 
                 block.beginNode = (BeginNode) node;
                 Node cur = node;
+                Node last;
                 do {
                     assert !cur.isDeleted();
-                    block.endNode = cur;
 
                     assert nodeToBlock.get(cur) == null;
                     nodeToBlock.set(cur, block);
@@ -112,15 +137,11 @@
                         }
                     }
 
-                    Node next = null;
-                    for (Node sux : cur.successors()) {
-                        if (sux != null && !(sux instanceof BeginNode)) {
-                            assert next == null;
-                            next = sux;
-                        }
-                    }
-                    cur = next;
-                } while (cur != null);
+                    last = cur;
+                    cur = cur.successors().first();
+                } while (cur != null && !(cur instanceof BeginNode));
+
+                block.endNode = (FixedNode) last;
             }
         }
 
@@ -304,7 +325,7 @@
     }
 
     private void computePostdominators() {
-        for (Block block : reversePostOrder) {
+        for (Block block : postOrder()) {
             if (block.isLoopEnd()) {
                 // We do not want the loop header registered as the postdominator of the loop end.
                 continue;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,16 @@
  */
 package com.oracle.graal.cri;
 
-import com.oracle.graal.graph.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
 
 public interface CiLoweringTool {
-    GraalRuntime getRuntime();
-    Node getGuardAnchor();
-    Node createGuard(Node condition, RiDeoptReason deoptReason, RiDeoptAction action, long leafGraphId);
+    ExtendedRiRuntime getRuntime();
+    ValueNode getGuardAnchor();
+    ValueNode createNullCheckGuard(ValueNode object, long leafGraphId);
+    ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, long leafGraphId);
+    ValueNode createGuard(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId);
+    Assumptions assumptions();
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/ExtendedRiRuntime.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2011, 2011, 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.cri;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Graal-specific extensions for the runtime interface that must be implemented by the VM.
+ */
+public interface ExtendedRiRuntime extends CodeCacheProvider {
+
+    void lower(Node n, CiLoweringTool tool);
+
+    StructuredGraph intrinsicGraph(ResolvedJavaMethod caller, int bci, ResolvedJavaMethod method, List<? extends Node> parameters);
+
+    CompilationResult compile(ResolvedJavaMethod method, StructuredGraph graph);
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/GraalRuntime.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, 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.cri;
-
-import java.util.*;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-
-/**
- * Graal-specific extensions for the runtime interface that must be implemented by the VM.
- */
-public interface GraalRuntime extends RiRuntime {
-
-    void lower(Node n, CiLoweringTool tool);
-
-    StructuredGraph intrinsicGraph(RiResolvedMethod caller, int bci, RiResolvedMethod method, List<? extends Node> parameters);
-
-    CiTargetMethod compile(RiResolvedMethod method, StructuredGraph graph);
-
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/RiGraphCache.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/RiGraphCache.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,14 @@
  */
 package com.oracle.graal.cri;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ri.*;
 
 
 public interface RiGraphCache {
 
     void put(StructuredGraph graph);
 
-    StructuredGraph get(RiResolvedMethod method);
+    StructuredGraph get(ResolvedJavaMethod method);
 
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java	Wed Jun 27 17:35:32 2012 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -22,49 +22,30 @@
  */
 package com.oracle.graal.nodes;
 
-import java.util.*;
-
 import com.oracle.graal.nodes.type.*;
 
 /**
- * The {@code AbstractStateSplit} class is the abstract base class of all instructions
- * that store an immutable copy of the frame state.
+ * Provides an implementation of {@link StateSplit}.
  */
 public abstract class AbstractStateSplit extends FixedWithNextNode implements StateSplit {
 
     @Input(notDataflow = true) private FrameState stateAfter;
 
-    @Override
     public FrameState stateAfter() {
         return stateAfter;
     }
 
-    @Override
     public void setStateAfter(FrameState x) {
         assert x == null || x.isAlive() : "frame state must be in a graph";
         updateUsages(stateAfter, x);
         stateAfter = x;
     }
 
-    /**
-     * Creates a new state split with the specified value type.
-     * @param kind the type of the value that this instruction produces
-     */
+    public boolean hasSideEffect() {
+        return true;
+    }
+
     public AbstractStateSplit(Stamp stamp) {
         super(stamp);
     }
-
-    @Override
-    public boolean needsStateAfter() {
-        return true;
-    }
-
-    @Override
-    public Map<Object, Object> getDebugProperties() {
-        Map<Object, Object> debugProperties = super.getDebugProperties();
-        if (stateAfter() != null) {
-            debugProperties.put("stateAfter", stateAfter().toString(Verbosity.Debugger));
-        }
-        return debugProperties;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AnchorNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * The {@code AnchorNode} can be used a lower bound for a Guard. It can also be used as an upper bound if no other FixedNode can be used for that purpose.
- */
-public final class AnchorNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable {
-
-    @Input(notDataflow = true) private final NodeInputList<GuardNode> guards = new NodeInputList<>(this);
-
-    public AnchorNode() {
-        super(StampFactory.illegal());
-    }
-
-    public void addGuard(GuardNode x) {
-        guards.add(x);
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (this.usages().size() == 0 && guards.size() == 0) {
-            return null;
-        }
-        return this;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        // Currently, there is nothing to emit since anchors are only a structural element with no execution semantics.
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -31,9 +31,25 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-public class BeginNode extends AbstractStateSplit implements LIRLowerable, Simplifiable, Node.IterableNodeType {
+public class BeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, Node.IterableNodeType {
+    @Input(notDataflow = true) private FrameState stateAfter;
+
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return false;
+    }
+
     public BeginNode() {
-        super(StampFactory.illegal());
+        super(StampFactory.dependency());
     }
 
     public static BeginNode begin(FixedNode with) {
@@ -127,7 +143,7 @@
     }
 
     public NodeIterable<FixedNode> getBlockNodes() {
-        return new NodeIterable<FixedNode>() {
+        return new AbstractNodeIterable<FixedNode>() {
             @Override
             public Iterator<FixedNode> iterator() {
                 return new BlockNodeIterator(BeginNode.this);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,39 @@
+/*
+ * 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;
+
+/**
+ * Base class for {@link BeginNode}s that are associated with a frame state.
+ * TODO (dnsimon) this not needed until {@link BeginNode} no longer implements {@link StateSplit}
+ * which is not possible until loop peeling works without requiring begin nodes to have frames states
+ */
+public abstract class BeginStateSplitNode extends BeginNode implements StateSplit {
+
+    /**
+     * A begin node has no side effect.
+     */
+    @Override
+    public boolean hasSideEffect() {
+        return false;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BooleanNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BooleanNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 
@@ -33,9 +34,17 @@
         super(stamp);
     }
 
-    public BooleanNode(Stamp stamp, Node... dependencies) {
+    public BooleanNode(Stamp stamp, ValueNode... dependencies) {
         super(stamp, dependencies);
     }
 
-    public abstract BooleanNode negate();
+    /**
+     * Tells all usages of this node to negate their effect. For example, IfNodes should switch their true and false successors.
+     */
+    public void negateUsages() {
+        for (Node n : usages().snapshot()) {
+            assert n instanceof Negatable;
+            ((Negatable) n).negate();
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/CallTargetNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,17 +22,17 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public abstract class CallTargetNode extends ValueNode implements LIRLowerable {
+
     @Input protected final NodeInputList<ValueNode> arguments;
 
     public CallTargetNode(ValueNode[] arguments) {
-        super(StampFactory.illegal());
+        super(StampFactory.extension());
         this.arguments = new NodeInputList<>(this, arguments);
     }
 
@@ -40,12 +40,12 @@
         return arguments;
     }
 
-    public abstract RiType returnType();
+    public abstract JavaType returnType();
 
-    public abstract CiKind returnKind();
+    public abstract Kind returnKind();
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        //nop
+        // nop
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.spi.*;
@@ -36,9 +35,9 @@
 @NodeInfo(shortName = "Const")
 public class ConstantNode extends BooleanNode implements LIRLowerable {
 
-    public final CiConstant value;
+    public final Constant value;
 
-    protected ConstantNode(CiConstant value) {
+    protected ConstantNode(Constant value) {
         super(StampFactory.forConstant(value));
         this.value = value;
     }
@@ -47,7 +46,7 @@
      * Constructs a new ConstantNode representing the specified constant.
      * @param value the constant
      */
-    protected ConstantNode(CiConstant value, RiRuntime runtime) {
+    protected ConstantNode(Constant value, MetaAccessProvider runtime) {
         super(StampFactory.forConstant(value, runtime));
         this.value = value;
     }
@@ -65,8 +64,8 @@
         return usages().filter(NodePredicates.isNotA(FrameState.class)).isEmpty();
     }
 
-    public static ConstantNode forCiConstant(CiConstant constant, RiRuntime runtime, Graph graph) {
-        if (constant.kind == CiKind.Object) {
+    public static ConstantNode forConstant(Constant constant, MetaAccessProvider runtime, Graph graph) {
+        if (constant.kind == Kind.Object) {
             return graph.unique(new ConstantNode(constant, runtime));
         } else {
             return graph.unique(new ConstantNode(constant));
@@ -80,7 +79,7 @@
      * @return a node for a double constant
      */
     public static ConstantNode forDouble(double d, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forDouble(d)));
+        return graph.unique(new ConstantNode(Constant.forDouble(d)));
     }
 
     /**
@@ -90,7 +89,7 @@
      * @return a node for a float constant
      */
     public static ConstantNode forFloat(float f, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forFloat(f)));
+        return graph.unique(new ConstantNode(Constant.forFloat(f)));
     }
 
     /**
@@ -100,7 +99,7 @@
      * @return a node for an long constant
      */
     public static ConstantNode forLong(long i, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forLong(i)));
+        return graph.unique(new ConstantNode(Constant.forLong(i)));
     }
 
     /**
@@ -110,7 +109,7 @@
      * @return a node for an integer constant
      */
     public static ConstantNode forInt(int i, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forInt(i)));
+        return graph.unique(new ConstantNode(Constant.forInt(i)));
     }
 
     /**
@@ -120,7 +119,7 @@
      * @return a node representing the boolean
      */
     public static ConstantNode forBoolean(boolean i, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forBoolean(i)));
+        return graph.unique(new ConstantNode(Constant.forBoolean(i)));
     }
 
     /**
@@ -130,7 +129,7 @@
      * @return a node representing the byte
      */
     public static ConstantNode forByte(byte i, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forByte(i)));
+        return graph.unique(new ConstantNode(Constant.forByte(i)));
     }
 
     /**
@@ -140,7 +139,7 @@
      * @return a node representing the char
      */
     public static ConstantNode forChar(char i, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forChar(i)));
+        return graph.unique(new ConstantNode(Constant.forChar(i)));
     }
 
     /**
@@ -150,7 +149,7 @@
      * @return a node representing the short
      */
     public static ConstantNode forShort(short i, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forShort(i)));
+        return graph.unique(new ConstantNode(Constant.forShort(i)));
     }
 
     /**
@@ -160,7 +159,7 @@
      * @return a node representing the address
      */
     public static ConstantNode forJsr(int i, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forJsr(i)));
+        return graph.unique(new ConstantNode(Constant.forJsr(i)));
     }
 
     /**
@@ -169,11 +168,11 @@
      * @param graph
      * @return a node representing the object
      */
-    public static ConstantNode forObject(Object o, RiRuntime runtime, Graph graph) {
-        return graph.unique(new ConstantNode(CiConstant.forObject(o), runtime));
+    public static ConstantNode forObject(Object o, MetaAccessProvider runtime, Graph graph) {
+        return graph.unique(new ConstantNode(Constant.forObject(o), runtime));
     }
 
-    public static ConstantNode forIntegerKind(CiKind kind, long value, Graph graph) {
+    public static ConstantNode forIntegerKind(Kind kind, long value, Graph graph) {
         switch (kind) {
             case Byte:
             case Short:
@@ -186,7 +185,7 @@
         }
     }
 
-    public static ConstantNode forFloatingKind(CiKind kind, double value, Graph graph) {
+    public static ConstantNode forFloatingKind(Kind kind, double value, Graph graph) {
         switch (kind) {
             case Float:
                 return ConstantNode.forFloat((float) value, graph);
@@ -197,7 +196,7 @@
         }
     }
 
-    public static ConstantNode defaultForKind(CiKind kind, Graph graph) {
+    public static ConstantNode defaultForKind(Kind kind, Graph graph) {
         switch(kind) {
             case Boolean:
                 return ConstantNode.forBoolean(false, graph);
@@ -227,9 +226,4 @@
             return super.toString(verbosity);
         }
     }
-
-    @Override
-    public BooleanNode negate() {
-        return ConstantNode.forBoolean(!value.asBoolean(), graph());
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -31,8 +31,8 @@
  * The {@code ControlSplitNode} is a base class for all instructions that split the control flow (ie. have more than one successor).
  */
 public abstract class ControlSplitNode extends FixedNode {
-
     @Successor private final NodeSuccessorList<BeginNode> blockSuccessors;
+    protected double[] branchProbability;
 
     public BeginNode blockSuccessor(int index) {
         return blockSuccessors.get(index);
@@ -46,8 +46,6 @@
         return blockSuccessors.size();
     }
 
-    protected final double[] branchProbability;
-
     public ControlSplitNode(Stamp stamp, BeginNode[] blockSuccessors, double[] branchProbability) {
         super(stamp);
         assert branchProbability.length == blockSuccessors.length;
@@ -63,14 +61,6 @@
         branchProbability[successorIndex] = x;
     }
 
-    /**
-     * Gets the successor corresponding to the default (fall through) case.
-     * @return the default successor
-     */
-    public FixedNode defaultSuccessor() {
-        return blockSuccessor(blockSuccessorCount() - 1);
-    }
-
     public Iterable<BeginNode> blockSuccessors() {
         return new Iterable<BeginNode>() {
             @Override
@@ -105,4 +95,19 @@
         properties.put("branchProbability", str.toString());
         return properties;
     }
+
+    public int blockSuccessorIndex(BeginNode successor) {
+        int idx = blockSuccessors.indexOf(successor);
+        if (idx < 0) {
+            throw new IllegalArgumentException();
+        }
+        return idx;
+    }
+
+    @Override
+    public ControlSplitNode clone(Graph into) {
+        ControlSplitNode csn = (ControlSplitNode) super.clone(into);
+        csn.branchProbability = Arrays.copyOf(branchProbability, branchProbability.length);
+        return csn;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,26 +22,27 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 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 {
 
     private String message;
-    private final RiDeoptAction action;
-    private final RiDeoptReason reason;
+    private final DeoptimizationAction action;
+    private final DeoptimizationReason reason;
     private final long leafGraphId;
 
 
-    public DeoptimizeNode(RiDeoptAction action, RiDeoptReason reason) {
+    public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) {
         this(action, reason, -1);
     }
 
-    public DeoptimizeNode(RiDeoptAction action, RiDeoptReason reason, long leafGraphId) {
-        super(StampFactory.illegal());
+    public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, long leafGraphId) {
+        super(StampFactory.forVoid());
         this.action = action;
         this.reason = reason;
         this.leafGraphId = leafGraphId;
@@ -55,11 +56,11 @@
         return message;
     }
 
-    public RiDeoptAction action() {
+    public DeoptimizationAction action() {
         return action;
     }
 
-    public RiDeoptReason reason() {
+    public DeoptimizationReason reason() {
         return reason;
     }
 
@@ -74,7 +75,7 @@
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void deopt(@ConstantNodeParameter RiDeoptAction action, @ConstantNodeParameter RiDeoptReason reason) {
+    public static void deopt(@ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter DeoptimizationReason reason) {
         throw new UnsupportedOperationException();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DispatchBeginNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * The entry node of an exception dispatcher block.
+ */
+public class DispatchBeginNode extends BeginStateSplitNode {
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EndNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -31,7 +31,7 @@
 public class EndNode extends FixedNode implements Node.IterableNodeType, LIRLowerable {
 
     public EndNode() {
-        super(StampFactory.illegal());
+        super(StampFactory.forVoid());
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,70 +22,84 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.extended.*;
 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, Node.IterableNodeType {
+public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, LIRLowerable, Node.IterableNodeType, Negatable {
 
-    @Input private final NodeInputList<BooleanNode> conditions;
-    private final RiDeoptReason deoptReason;
-    private final RiDeoptAction action;
+    @Input private BooleanNode condition;
+    private final DeoptimizationReason deoptReason;
+    private final DeoptimizationAction action;
+    private boolean negated;
     private final long leafGraphId;
 
-    public FixedGuardNode(BooleanNode condition, RiDeoptReason deoptReason, RiDeoptAction action, long leafGraphId) {
-        super(StampFactory.illegal());
+    public BooleanNode condition() {
+        return condition;
+    }
+
+    public void setCondition(BooleanNode x) {
+        updateUsages(condition, x);
+        condition = x;
+    }
+
+    public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, long leafGraphId) {
+        this(condition, deoptReason, action, false, leafGraphId);
+    }
+
+    public FixedGuardNode(BooleanNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+        super(StampFactory.forVoid());
         this.action = action;
+        this.negated = negated;
         this.leafGraphId = leafGraphId;
-        this.conditions = new NodeInputList<>(this, new BooleanNode[] {condition});
+        this.condition = condition;
         this.deoptReason = deoptReason;
     }
 
     @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name && negated) {
+            return "!" + super.toString(verbosity);
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
-        for (BooleanNode condition : conditions()) {
-            gen.emitGuardCheck(condition, deoptReason, action, leafGraphId);
-        }
-    }
-
-    public void addCondition(BooleanNode x) {
-        conditions.add(x);
-    }
-
-    public NodeInputList<BooleanNode> conditions() {
-        return conditions;
+        gen.emitGuardCheck(condition, deoptReason, action, negated, leafGraphId);
     }
 
     @Override
     public void simplify(SimplifierTool tool) {
-        for (BooleanNode n : conditions.snapshot()) {
-            if (n instanceof ConstantNode) {
-                ConstantNode c = (ConstantNode) n;
-                if (c.asConstant().asBoolean()) {
-                    conditions.remove(n);
-                } else {
-                    FixedNode next = this.next();
-                    if (next != null) {
-                        tool.deleteBranch(next);
-                    }
-                    setNext(graph().add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, deoptReason, leafGraphId)));
-                    return;
+        if (condition instanceof ConstantNode) {
+            ConstantNode c = (ConstantNode) condition;
+            if (c.asConstant().asBoolean() != negated) {
+                ((StructuredGraph) graph()).removeFixed(this);
+            } else {
+                FixedNode next = this.next();
+                if (next != null) {
+                    tool.deleteBranch(next);
                 }
+                setNext(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, deoptReason, leafGraphId)));
+                return;
             }
         }
-        if (conditions.isEmpty()) {
-            ((StructuredGraph) graph()).removeFixed(this);
-        }
     }
 
     @Override
     public void lower(CiLoweringTool tool) {
-        AnchorNode newAnchor = graph().add(new AnchorNode());
-        for (BooleanNode b : conditions) {
-            newAnchor.addGuard((GuardNode) tool.createGuard(b, deoptReason, action, leafGraphId));
-        }
+        ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(tool.createGuard(condition, deoptReason, action, negated, leafGraphId)));
         ((StructuredGraph) graph()).replaceFixedWithFixed(this, newAnchor);
     }
+
+    @Override
+    public Negatable negate() {
+        negated = !negated;
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -32,6 +32,10 @@
         super(stamp);
     }
 
+    public FixedNode(Stamp stamp, ValueNode... dependencies) {
+        super(stamp, dependencies);
+    }
+
     public double probability() {
         return probability;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -41,4 +41,8 @@
     public FixedWithNextNode(Stamp stamp) {
         super(stamp);
     }
+
+    public FixedWithNextNode(Stamp stamp, ValueNode... dependencies) {
+        super(stamp, dependencies);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,8 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.spi.*;
@@ -35,7 +35,26 @@
  * The {@code FrameState} class encapsulates the frame state (i.e. local variables and
  * operand stack) at a particular point in the abstract interpretation.
  */
-public final class FrameState extends Node implements Node.IterableNodeType, LIRLowerable {
+public final class FrameState extends VirtualState implements Node.IterableNodeType, LIRLowerable {
+
+    /**
+     * An instance of this class is an identifier for all nodes that were generated by one specific inlining operation.
+     * It is used to generate the correct debug information for nested locks.
+     */
+    public static final class InliningIdentifier {
+        private final ResolvedJavaMethod method;
+        private final String context;
+
+        public InliningIdentifier(ResolvedJavaMethod method, String context) {
+            this.method = method;
+            this.context = context;
+        }
+
+        @Override
+        public String toString() {
+            return method + "@" + context;
+        }
+    }
 
     protected final int localsSize;
 
@@ -46,6 +65,12 @@
     private boolean duringCall;
 
     /**
+     * This object identifies the concrete inlining operation that produced this frame state.
+     * It is set during inlining, therefore for the outermost frame states of a graph this field is null.
+     */
+    private InliningIdentifier inliningIdentifier;
+
+    /**
      * This BCI should be used for frame states that are built for code with no meaningful BCI.
      */
     public static final int UNKNOWN_BCI = -4;
@@ -74,15 +99,14 @@
 
     @Input private final NodeInputList<ValueNode> values;
 
-    @Input private final NodeInputList<Node> virtualObjectMappings;
+    @Input private final NodeInputList<VirtualObjectState> virtualObjectMappings;
 
     /**
-     * The bytecode index to which this frame state applies. This will be {@code -1}
-     * iff this state is mutable.
+     * The bytecode index to which this frame state applies.
      */
     public final int bci;
 
-    private final RiResolvedMethod method;
+    private final ResolvedJavaMethod method;
 
     /**
      * Creates a {@code FrameState} for the given scope and maximum number of stack and local variables.
@@ -93,20 +117,30 @@
      * @param stackSize size of the stack
      * @param rethrowException if true the VM should re-throw the exception on top of the stack when deopt'ing using this framestate
      */
-    public FrameState(RiResolvedMethod method, int bci, int localsSize, int stackSize, boolean rethrowException, boolean duringCall) {
+    public FrameState(ResolvedJavaMethod method, int bci, List<ValueNode> values, int stackSize, boolean rethrowException, boolean duringCall, InliningIdentifier inliningIdentifier, List<VirtualObjectState> virtualObjectMappings) {
         assert stackSize >= 0;
+        assert (bci >= 0 && method != null) || (bci < 0 && method == null && values.isEmpty());
         this.method = method;
         this.bci = bci;
-        this.localsSize = localsSize;
+        this.localsSize = values.size() - stackSize;
         this.stackSize = stackSize;
-        this.values = new NodeInputList<>(this, localsSize + stackSize);
-        this.virtualObjectMappings = new NodeInputList<>(this);
+        this.values = new NodeInputList<>(this, values);
+        this.virtualObjectMappings = new NodeInputList<>(this, virtualObjectMappings);
         this.rethrowException = rethrowException;
         this.duringCall = duringCall;
+        this.inliningIdentifier = inliningIdentifier;
         assert !rethrowException || stackSize == 1 : "must have exception on top of the stack";
     }
 
-    public FrameState(RiResolvedMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException, boolean duringCall) {
+    /**
+     * Simple constructor used to create marker FrameStates.
+     * @param bci marker bci, needs to be < 0
+     */
+    public FrameState(int bci) {
+        this(null, bci, Collections.<ValueNode>emptyList(), 0, false, false, null, Collections.<VirtualObjectState>emptyList());
+    }
+
+    public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException, boolean duringCall, InliningIdentifier inliningIdentifier) {
         this.method = method;
         this.bci = bci;
         this.localsSize = locals.length;
@@ -124,6 +158,7 @@
         this.virtualObjectMappings = new NodeInputList<>(this);
         this.rethrowException = rethrowException;
         this.duringCall = duringCall;
+        this.inliningIdentifier = inliningIdentifier;
         assert !rethrowException || stackSize == 1 : "must have exception on top of the stack";
     }
 
@@ -140,8 +175,12 @@
         this.outerFrameState = x;
     }
 
-    private void setValueAt(int i, ValueNode x) {
-        values.set(i, x);
+    public InliningIdentifier inliningIdentifier() {
+        return inliningIdentifier;
+    }
+
+    public void setInliningIdentifier(InliningIdentifier inliningIdentifier) {
+        this.inliningIdentifier = inliningIdentifier;
     }
 
     public boolean rethrowException() {
@@ -156,12 +195,11 @@
         this.duringCall = b;
     }
 
-    public RiResolvedMethod method() {
+    public ResolvedJavaMethod method() {
         return method;
     }
 
-    public void addVirtualObjectMapping(Node virtualObject) {
-        assert virtualObject instanceof VirtualObjectFieldNode || virtualObject instanceof PhiNode || virtualObject instanceof ValueProxyNode : virtualObject;
+    public void addVirtualObjectMapping(VirtualObjectState virtualObject) {
         virtualObjectMappings.add(virtualObject);
     }
 
@@ -173,7 +211,7 @@
         return virtualObjectMappings.get(i);
     }
 
-    public Iterable<Node> virtualObjectMappings() {
+    public NodeInputList<VirtualObjectState> virtualObjectMappings() {
         return virtualObjectMappings;
     }
 
@@ -181,7 +219,9 @@
      * Gets a copy of this frame state.
      */
     public FrameState duplicate(int newBci) {
-        return duplicate(newBci, false);
+        FrameState other = graph().add(new FrameState(method, newBci, values, stackSize, rethrowException, duringCall, inliningIdentifier, virtualObjectMappings));
+        other.setOuterFrameState(outerFrameState());
+        return other;
     }
 
     /**
@@ -191,14 +231,21 @@
         return duplicate(bci);
     }
 
-    public FrameState duplicate(int newBci, boolean duplicateOuter) {
-        FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize, rethrowException, duringCall));
-        other.values.setAll(values);
-        other.virtualObjectMappings.setAll(virtualObjectMappings);
+    /**
+     * Duplicates a FrameState, along with a deep copy of all connected VirtualState (outer FrameStates,
+     * VirtualObjectStates, ...).
+     */
+    @Override
+    public FrameState duplicateWithVirtualState() {
         FrameState newOuterFrameState = outerFrameState();
-        if (duplicateOuter && newOuterFrameState != null) {
-            newOuterFrameState = newOuterFrameState.duplicate(newOuterFrameState.bci, duplicateOuter);
+        if (newOuterFrameState != null) {
+            newOuterFrameState = newOuterFrameState.duplicateWithVirtualState();
         }
+        ArrayList<VirtualObjectState> newVirtualMappings = new ArrayList<>(virtualObjectMappings.size());
+        for (VirtualObjectState state : virtualObjectMappings) {
+            newVirtualMappings.add(state.duplicateWithVirtualState());
+        }
+        FrameState other = graph().add(new FrameState(method, bci, values, stackSize, rethrowException, duringCall, inliningIdentifier, newVirtualMappings));
         other.setOuterFrameState(newOuterFrameState);
         return other;
     }
@@ -208,30 +255,19 @@
      * values in pushedValues pushed on the stack. The pushedValues are expected to be in slot encoding: a long
      * or double is followed by a null slot.
      */
-    public FrameState duplicateModified(int newBci, boolean newRethrowException, CiKind popKind, ValueNode... pushedValues) {
-        int popSlots = 0;
-        if (popKind != CiKind.Void) {
+    public FrameState duplicateModified(int newBci, boolean newRethrowException, Kind popKind, ValueNode... pushedValues) {
+        ArrayList<ValueNode> copy = new ArrayList<>(values);
+        if (popKind != Kind.Void) {
             if (stackAt(stackSize() - 1) == null) {
-                popSlots = 2;
-            } else {
-                popSlots = 1;
+                copy.remove(copy.size() - 1);
             }
-            assert stackAt(stackSize() - popSlots).kind().stackKind() == popKind.stackKind() || (stackAt(stackSize() - popSlots) instanceof BoxedVirtualObjectNode && popKind.isObject());
+            ValueNode lastSlot = copy.get(copy.size() - 1);
+            assert lastSlot.kind().stackKind() == popKind.stackKind() || (lastSlot instanceof BoxedVirtualObjectNode && popKind.isObject());
+            copy.remove(copy.size() - 1);
         }
+        Collections.addAll(copy, pushedValues);
 
-        int pushSlots = pushedValues.length;
-        FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize - popSlots + pushSlots, newRethrowException, false));
-        for (int i = 0; i < localsSize; i++) {
-            other.setValueAt(i, localAt(i));
-        }
-        for (int i = 0; i < stackSize - popSlots; i++) {
-            other.setValueAt(localsSize + i, stackAt(i));
-        }
-        int slot = localsSize + stackSize - popSlots;
-        for (int i = 0; i < pushSlots; i++) {
-            other.setValueAt(slot++, pushedValues[i]);
-        }
-        other.virtualObjectMappings.setAll(virtualObjectMappings);
+        FrameState other = graph().add(new FrameState(method, newBci, copy, copy.size() - localsSize, newRethrowException, false, inliningIdentifier, virtualObjectMappings));
         other.setOuterFrameState(outerFrameState());
         return other;
     }
@@ -282,15 +318,15 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        // Nothing to do, frame states are processed as part of the handling of AbstractStateSplit nodes.
+        // Nothing to do, frame states are processed as part of the handling of StateSplit nodes.
     }
 
     private static String toString(FrameState frameState) {
         StringBuilder sb = new StringBuilder();
-        String nl = CiUtil.NEW_LINE;
+        String nl = CodeUtil.NEW_LINE;
         FrameState fs = frameState;
         while (fs != null) {
-            CiUtil.appendLocation(sb, fs.method, fs.bci).append(nl);
+            CodeUtil.appendLocation(sb, fs.method, fs.bci).append(nl);
             sb.append("locals: [");
             for (int i = 0; i < fs.localsSize(); i++) {
                 sb.append(i == 0 ? "" : ", ").append(fs.localAt(i) == null ? "_" : fs.localAt(i).toString(Verbosity.Id));
@@ -321,7 +357,11 @@
         Map<Object, Object> properties = super.getDebugProperties();
         properties.put("bci", bci);
         if (method != null) {
-            properties.put("method", CiUtil.format("%H.%n(%p):%r", method));
+            properties.put("method", CodeUtil.format("%H.%n(%p):%r", method));
+            StackTraceElement ste = method.toStackTraceElement(bci);
+            if (ste.getFileName() != null && ste.getLineNumber() >= 0) {
+                properties.put("source", ste.getFileName() + ":" + ste.getLineNumber());
+            }
         } else {
             properties.put("method", "None");
         }
@@ -344,8 +384,21 @@
     public boolean verify() {
         for (ValueNode value : values) {
             assert assertTrue(value == null || !value.isDeleted(), "frame state must not contain deleted nodes");
-            assert assertTrue(value == null || value instanceof VirtualObjectNode || (value.kind() != CiKind.Void && value.kind() != CiKind.Illegal), "unexpected value: %s", value);
+            assert assertTrue(value == null || value instanceof VirtualObjectNode || (value.kind() != Kind.Void && value.kind() != Kind.Illegal), "unexpected value: %s", value);
         }
         return super.verify();
     }
+
+    @Override
+    public void applyToNonVirtual(NodeClosure< ? super ValueNode> closure) {
+        for (ValueNode value : values.nonNull()) {
+            closure.apply(this, value);
+        }
+        for (VirtualObjectState state : virtualObjectMappings) {
+            state.applyToNonVirtual(closure);
+        }
+        if (outerFrameState() != null) {
+            outerFrameState().applyToNonVirtual(closure);
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,19 +22,32 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.types.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ri.*;
 
-public final class GuardNode extends FloatingNode implements Canonicalizable, LIRLowerable, TypeFeedbackProvider, Node.IterableNodeType {
+/**
+ * A guard is a node that deoptimizes based on a conditional expression. Guards are not attached to a certain frame
+ * state, they can move around freely and will always use the correct frame state when the nodes are scheduled (i.e.,
+ * the last emitted frame state). The node that is guarded has a data dependency on the guard and the guard in turn has
+ * a data dependency on the condition. A guard may only be executed if it is guaranteed that the guarded node is
+ * executed too (if no exceptions are thrown). Therefore, an {@linkplain AnchorNode anchor} is placed after a control
+ * flow split and the guard has a data dependency to the anchor. The anchor is the most distant node that is
+ * post-dominated by the guarded node and the guard can be scheduled anywhere between those two nodes. This ensures
+ * maximum flexibility for the guard node and guarantees that deoptimization occurs only if the control flow would have
+ * reached the guarded node (without taking exceptions into account).
+ */
+public final class GuardNode extends FloatingNode implements Canonicalizable, LIRLowerable, TypeFeedbackProvider, Node.IterableNodeType, Negatable {
 
     @Input private BooleanNode condition;
     @Input(notDataflow = true) private FixedNode anchor;
-    private final RiDeoptReason reason;
-    private final RiDeoptAction action;
+    private final DeoptimizationReason reason;
+    private final DeoptimizationAction action;
+    private boolean negated;
     private final long leafGraphId;
 
     public FixedNode anchor() {
@@ -58,33 +71,47 @@
         condition = x;
     }
 
-    public RiDeoptReason reason() {
+    public boolean negated() {
+        return negated;
+    }
+
+    public DeoptimizationReason reason() {
         return reason;
     }
 
-    public RiDeoptAction action() {
+    public DeoptimizationAction action() {
         return action;
     }
 
-    public GuardNode(BooleanNode condition, FixedNode anchor, RiDeoptReason reason, RiDeoptAction action, long leafGraphId) {
-        super(StampFactory.illegal());
+    public GuardNode(BooleanNode condition, FixedNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated, long leafGraphId) {
+        super(StampFactory.dependency());
         this.condition = condition;
         this.anchor = anchor;
         this.reason = reason;
         this.action = action;
+        this.negated = negated;
         this.leafGraphId = leafGraphId;
     }
 
     @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name && negated) {
+            return "!" + super.toString(verbosity);
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.emitGuardCheck(condition(), reason(), action(), leafGraphId);
+        gen.emitGuardCheck(condition(), reason(), action(), negated(), leafGraphId);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (condition() instanceof ConstantNode) {
             ConstantNode c = (ConstantNode) condition();
-            if (c.asConstant().asBoolean()) {
+            if (c.asConstant().asBoolean() != negated) {
                 if (!dependencies().isEmpty()) {
                     for (Node usage : usages()) {
                         if (usage instanceof ValueNode) {
@@ -105,4 +132,10 @@
             ((ConditionalTypeFeedbackProvider) condition).typeFeedback(tool);
         }
     }
+
+    @Override
+    public Negatable negate() {
+        negated = !negated;
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.types.*;
 import com.oracle.graal.nodes.type.*;
@@ -33,11 +33,10 @@
  * The {@code IfNode} represents a branch that can go one of two directions depending on the outcome of a
  * comparison.
  */
-public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, SplitTypeFeedbackProvider {
+public final class IfNode extends ControlSplitNode implements Simplifiable, LIRLowerable, SplitTypeFeedbackProvider, Negatable {
     public static final int TRUE_EDGE = 0;
     public static final int FALSE_EDGE = 1;
-
-    private static final BeginNode[] EMPTY_IF_SUCCESSORS = new BeginNode[] {null, null};
+    private final long leafGraphId;
 
     @Input private BooleanNode compare;
 
@@ -45,14 +44,19 @@
         return compare;
     }
 
-    public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double takenProbability) {
-        super(StampFactory.illegal(), new BeginNode[] {BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor)}, new double[] {takenProbability, 1 - takenProbability});
-        this.compare = condition;
+    public void setCompare(BooleanNode x) {
+        updateUsages(compare, x);
+        compare = x;
     }
 
-    public IfNode(BooleanNode condition, double probability) {
-        super(StampFactory.illegal(), EMPTY_IF_SUCCESSORS, new double[] {probability, 1 - probability});
+    public IfNode(BooleanNode condition, FixedNode trueSuccessor, FixedNode falseSuccessor, double takenProbability, long leafGraphId) {
+        super(StampFactory.forVoid(), new BeginNode[] {BeginNode.begin(trueSuccessor), BeginNode.begin(falseSuccessor)}, new double[] {takenProbability, 1 - takenProbability});
         this.compare = condition;
+        this.leafGraphId = leafGraphId;
+    }
+
+    public long leafGraphId() {
+        return leafGraphId;
     }
 
     /**
@@ -127,6 +131,7 @@
                     if (!phis.hasNext()) {
                         // empty if construct with no phis: remove it
                         removeEmptyIf(tool);
+                        return;
                     } else {
                         PhiNode singlePhi = phis.next();
                         if (!phis.hasNext()) {
@@ -137,13 +142,14 @@
                             if (trueValue.kind() != falseValue.kind()) {
                                 return;
                             }
-                            if (trueValue.kind() != CiKind.Int && trueValue.kind() != CiKind.Long) {
+                            if (trueValue.kind() != Kind.Int && trueValue.kind() != Kind.Long) {
                                 return;
                             }
                             if (trueValue.isConstant() && falseValue.isConstant()) {
                                 MaterializeNode materialize = MaterializeNode.create(compare(), graph(), trueValue, falseValue);
                                 ((StructuredGraph) graph()).replaceFloating(singlePhi, materialize);
                                 removeEmptyIf(tool);
+                                return;
                             }
                         }
                     }
@@ -188,4 +194,18 @@
             ((ConditionalTypeFeedbackProvider) compare).typeFeedback(blockSuccessor == TRUE_EDGE ? tool : tool.negate());
         }
     }
+
+    @Override
+    public Negatable negate() {
+        BeginNode trueSucc = trueSuccessor();
+        BeginNode falseSucc = falseSuccessor();
+        setTrueSuccessor(null);
+        setFalseSuccessor(null);
+        setTrueSuccessor(falseSucc);
+        setFalseSuccessor(trueSucc);
+        double prop = branchProbability[TRUE_EDGE];
+        branchProbability[TRUE_EDGE] = branchProbability[FALSE_EDGE];
+        branchProbability[FALSE_EDGE] = prop;
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java	Wed Jun 27 17:35:32 2012 +0200
@@ -55,9 +55,12 @@
 
     void setUseForInlining(boolean value);
 
-    boolean megamorph();
+    /**
+     * True if this invocation is almost certainly megamorphic, false when in doubt.
+     */
+    boolean isMegamorphic();
 
-    void setMegamorph(boolean megamorph);
+    void setMegamorphic(boolean value);
 
     long leafGraphId();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,7 +24,8 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -34,12 +35,11 @@
 /**
  * The {@code InvokeNode} represents all kinds of method calls.
  */
-public final class InvokeNode extends AbstractStateSplit implements Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint  {
+public final class InvokeNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint  {
 
     @Input private final MethodCallTargetNode callTarget;
     private final int bci;
-    // megamorph should only be true when the compiler is sure that the call site is megamorph, and false when in doubt
-    private boolean megamorph;
+    private boolean megamorphic;
     private boolean useForInlining;
     private final long leafGraphId;
 
@@ -56,7 +56,7 @@
         this.callTarget = callTarget;
         this.bci = bci;
         this.leafGraphId = leafGraphId;
-        this.megamorph = false;
+        this.megamorphic = false;
         this.useForInlining = true;
     }
 
@@ -65,13 +65,13 @@
     }
 
     @Override
-    public boolean megamorph() {
-        return megamorph;
+    public boolean isMegamorphic() {
+        return megamorphic;
     }
 
     @Override
-    public void setMegamorph(boolean megamorph) {
-        this.megamorph = megamorph;
+    public void setMegamorphic(boolean value) {
+        this.megamorphic = value;
     }
 
     public boolean useForInlining() {
@@ -92,7 +92,7 @@
     public Map<Object, Object> getDebugProperties() {
         Map<Object, Object> debugProperties = super.getDebugProperties();
         if (callTarget != null && callTarget.targetMethod() != null) {
-            debugProperties.put("targetMethod", CiUtil.format("%h.%n(%p)", callTarget.targetMethod()));
+            debugProperties.put("targetMethod", CodeUtil.format("%h.%n(%p)", callTarget.targetMethod()));
         }
         return debugProperties;
     }
@@ -128,13 +128,14 @@
     @Override
     public FrameState stateDuring() {
         FrameState stateAfter = stateAfter();
-        FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind(false));
+        FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind());
         stateDuring.setDuringCall(true);
         return stateDuring;
     }
 
     @Override
     public void intrinsify(Node node) {
+        assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid();
         MethodCallTargetNode call = callTarget;
         FrameState stateAfter = stateAfter();
         if (node instanceof StateSplit) {
@@ -142,13 +143,13 @@
             stateSplit.setStateAfter(stateAfter);
         }
         if (node == null) {
-            assert kind() == CiKind.Void && usages().isEmpty();
+            assert kind() == Kind.Void && usages().isEmpty();
             ((StructuredGraph) graph()).removeFixed(this);
         } else {
             if (node instanceof FixedWithNextNode) {
                 ((StructuredGraph) graph()).replaceFixedWithFixed(this, (FixedWithNextNode) node);
             } else if (node instanceof DeoptimizeNode) {
-                this.replaceAtPredecessors(node);
+                this.replaceAtPredecessor(node);
                 this.replaceAtUsages(null);
                 GraphUtil.killCFG(this);
                 return;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,7 +24,8 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
@@ -39,7 +40,7 @@
     @Input private FrameState stateAfter;
     private final int bci;
     // megamorph should only be true when the compiler is sure that the call site is megamorph, and false when in doubt
-    private boolean megamorph;
+    private boolean megamorphic;
     private boolean useForInlining;
     private final long leafGraphId;
 
@@ -48,17 +49,17 @@
      * @param blockSuccessors
      * @param branchProbability
      */
-    public InvokeWithExceptionNode(MethodCallTargetNode callTarget, BeginNode exceptionEdge, int bci, long leafGraphId) {
+    public InvokeWithExceptionNode(MethodCallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci, long leafGraphId) {
         super(callTarget.returnStamp(), new BeginNode[]{null, exceptionEdge}, new double[]{1.0, 0.0});
         this.bci = bci;
         this.callTarget = callTarget;
         this.leafGraphId = leafGraphId;
-        this.megamorph = true;
+        this.megamorphic = true;
         this.useForInlining = true;
     }
 
-    public BeginNode exceptionEdge() {
-        return blockSuccessor(EXCEPTION_EDGE);
+    public DispatchBeginNode exceptionEdge() {
+        return (DispatchBeginNode) blockSuccessor(EXCEPTION_EDGE);
     }
 
     public void setExceptionEdge(BeginNode x) {
@@ -78,13 +79,13 @@
     }
 
     @Override
-    public boolean megamorph() {
-        return megamorph;
+    public boolean isMegamorphic() {
+        return megamorphic;
     }
 
     @Override
-    public void setMegamorph(boolean megamorph) {
-        this.megamorph = megamorph;
+    public void setMegamorphic(boolean value) {
+        this.megamorphic = value;
     }
 
     @Override
@@ -145,9 +146,13 @@
         this.stateAfter = stateAfter;
     }
 
+    public boolean hasSideEffect() {
+        return true;
+    }
+
     public FrameState stateDuring() {
         FrameState tempStateAfter = stateAfter();
-        FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind(false));
+        FrameState stateDuring = tempStateAfter.duplicateModified(bci(), tempStateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind());
         stateDuring.setDuringCall(true);
         return stateDuring;
     }
@@ -157,7 +162,7 @@
         Map<Object, Object> debugProperties = super.getDebugProperties();
         debugProperties.put("memoryCheckpoint", "true");
         if (callTarget != null && callTarget.targetMethod() != null) {
-            debugProperties.put("targetMethod", CiUtil.format("%h.%n(%p)", callTarget.targetMethod()));
+            debugProperties.put("targetMethod", CodeUtil.format("%h.%n(%p)", callTarget.targetMethod()));
         }
         return debugProperties;
     }
@@ -169,12 +174,8 @@
     }
 
     @Override
-    public boolean needsStateAfter() {
-        return true;
-    }
-
-    @Override
     public void intrinsify(Node node) {
+        assert !(node instanceof ValueNode) || ((ValueNode) node).kind().isVoid() == kind().isVoid();
         MethodCallTargetNode call = callTarget;
         FrameState state = stateAfter();
         killExceptionEdge();
@@ -183,10 +184,10 @@
             stateSplit.setStateAfter(state);
         }
         if (node == null) {
-            assert kind() == CiKind.Void && usages().isEmpty();
+            assert kind() == Kind.Void && usages().isEmpty();
             ((StructuredGraph) graph()).removeSplit(this, NORMAL_EDGE);
         } else if (node instanceof DeoptimizeNode) {
-            this.replaceAtPredecessors(node);
+            this.replaceAtPredecessor(node);
             this.replaceAtUsages(null);
             GraphUtil.killCFG(this);
             return;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.type.*;
@@ -36,10 +35,6 @@
 
     private final int index;
 
-    public LocalNode(CiKind kind, int index) {
-        this(index, StampFactory.forKind(kind));
-    }
-
     public LocalNode(int index, Stamp stamp) {
         super(stamp);
         this.index = index;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -116,7 +116,7 @@
         } else {
             return super.forwardEndIndex(pred);
         }
-        throw ValueUtil.shouldNotReachHere("unknown pred : " + pred);
+        throw ValueNodeUtil.shouldNotReachHere("unknown pred : " + pred);
     }
 
     @Override
@@ -131,7 +131,7 @@
                 return end;
             }
         }
-        throw ValueUtil.shouldNotReachHere();
+        throw ValueNodeUtil.shouldNotReachHere();
     }
 
     @Override
@@ -155,4 +155,8 @@
     public void simplify(SimplifierTool tool) {
         // nothing yet
     }
+
+    public boolean isLoopExit(BeginNode begin) {
+        return begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,7 +24,7 @@
 
 import com.oracle.graal.nodes.spi.*;
 
-public class LoopExitNode extends BeginNode {
+public class LoopExitNode extends BeginStateSplitNode {
     @Input(notDataflow = true) private LoopBeginNode loopBegin;
     public LoopExitNode(LoopBeginNode loop) {
         assert loop != null;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -28,20 +28,16 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
 
 /**
  * Denotes the merging of multiple control-flow paths.
  */
-public class MergeNode extends BeginNode implements Node.IterableNodeType, LIRLowerable {
+public class MergeNode extends BeginStateSplitNode implements Node.IterableNodeType, LIRLowerable {
 
     @Input(notDataflow = true) private final NodeInputList<EndNode> ends = new NodeInputList<>(this);
 
     @Override
-    public boolean needsStateAfter() {
-        return false;
-    }
-
-    @Override
     public void generate(LIRGeneratorTool gen) {
         gen.visitMerge(this);
     }
@@ -85,8 +81,12 @@
         int predIndex = phiPredecessorIndex(pred);
         assert predIndex != -1;
         deleteEnd(pred);
-        for (PhiNode phi : phis()) {
+        for (PhiNode phi : phis().snapshot()) {
+            ValueNode removedValue = phi.valueAt(predIndex);
             phi.removeInput(predIndex);
+            if (removedValue != null && removedValue.isAlive() && removedValue.usages().isEmpty() && GraphUtil.isFloatingNode().apply(removedValue)) {
+                GraphUtil.killWithUnusedFloatingInputs(removedValue);
+            }
         }
     }
 
@@ -177,7 +177,7 @@
                     phi.addInput(newInput);
                 }
                 this.removeEnd(end);
-                end.replaceAtPredecessors(newEnd);
+                end.replaceAtPredecessor(newEnd);
                 end.safeDelete();
                 tool.addToWorkList(newEnd.predecessor()); // ?
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -33,18 +33,41 @@
  * and a variable.
  */
 public final class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType {
+
     public static enum PhiType {
-        Value, // normal value phis
-        Memory, // memory phis
-        Virtual // phis used for VirtualObjectField merges
+        Value(null), // normal value phis
+        Memory(StampFactory.dependency());
+
+        public final Stamp stamp;
+
+        PhiType(Stamp stamp) {
+            this.stamp = stamp;
+        }
     }
 
     @Input(notDataflow = true) private MergeNode merge;
     @Input private final NodeInputList<ValueNode> values = new NodeInputList<>(this);
     private final PhiType type;
 
-    public PhiNode(CiKind kind, MergeNode merge, PhiType type) {
+    /**
+     * Create a value phi ({@link PhiType#Value}) with the specified kind.
+     * @param kind the kind of the value
+     * @param merge the merge that the new phi belongs to
+     */
+    public PhiNode(Kind kind, MergeNode merge) {
         super(StampFactory.forKind(kind));
+        this.type = PhiType.Value;
+        this.merge = merge;
+    }
+
+    /**
+     * Create a non-value phi ({@link PhiType#Memory} or {@link PhiType#Virtual}) with the specified kind.
+     * @param type the type of the new phi
+     * @param merge the merge that the new phi belongs to
+     */
+    public PhiNode(PhiType type, MergeNode merge) {
+        super(type.stamp);
+        assert type.stamp != null : merge + " " + type;
         this.type = type;
         this.merge = merge;
     }
@@ -61,16 +84,19 @@
         return values;
     }
 
+    @Override
     public boolean inferStamp() {
-        Stamp newStamp = StampFactory.or(values());
-        if (stamp().equals(newStamp)) {
+        if (type == PhiType.Value) {
+            return inferPhiStamp();
+        } else {
             return false;
-        } else {
-            setStamp(newStamp);
-            return true;
         }
     }
 
+    public boolean inferPhiStamp() {
+        return updateStamp(StampTool.meet(values()));
+    }
+
     @Override
     public boolean verify() {
         assertTrue(merge() != null, "missing merge");
@@ -93,6 +119,18 @@
         return values.get(i);
     }
 
+    /**
+     * Sets the value at the given index and makes sure that the values list is large enough.
+     * @param i the index at which to set the value
+     * @param x the new phi input value for the given location
+     */
+    public void initializeValueAt(int i, ValueNode x) {
+        while (values().size() <= i) {
+            values.add(null);
+        }
+        values.set(i, x);
+    }
+
     public void setValueAt(int i, ValueNode x) {
         values.set(i, x);
     }
@@ -156,6 +194,19 @@
         return differentValue;
     }
 
+    public ValueNode singleBackValue() {
+        assert merge() instanceof LoopBeginNode;
+        ValueNode differentValue = null;
+        for (ValueNode n : values().subList(merge().forwardEndCount(), values().size())) {
+            if (differentValue == null) {
+                differentValue = n;
+            } else if (differentValue != n) {
+                return null;
+            }
+        }
+        return differentValue;
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         ValueNode singleValue = singleValue();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -30,17 +30,17 @@
 public class PiNode extends FloatingNode implements LIRLowerable {
 
     @Input private ValueNode object;
-    @Input private BeginNode anchor;
+    @Input(notDataflow = true) private final FixedNode anchor;
 
     public ValueNode object() {
         return object;
     }
 
-    public BeginNode anchor() {
+    public FixedNode anchor() {
         return anchor;
     }
 
-    public PiNode(ValueNode object, BeginNode anchor, Stamp stamp) {
+    public PiNode(ValueNode object, FixedNode anchor, Stamp stamp) {
         super(stamp);
         this.object = object;
         this.anchor = anchor;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -37,14 +36,21 @@
 
     /**
      * Constructs a new Return instruction.
+     *
      * @param result the instruction producing the result for this return; {@code null} if this is a void return
      */
     public ReturnNode(ValueNode result) {
-        super(StampFactory.forKind(result == null ? CiKind.Void : result.kind()));
+        super(result == null ? StampFactory.forVoid() : result.stamp());
         this.result = result;
     }
 
     @Override
+    public boolean verify() {
+        assertTrue((result == null && stamp() == StampFactory.forVoid()) || (result != null && kind() == result.kind()), "invalid stamp");
+        return super.verify();
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
         gen.visitReturn(this);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -32,10 +32,9 @@
 public final class SafepointNode extends FixedWithNextNode implements LIRLowerable, Node.IterableNodeType {
 
     public SafepointNode() {
-        super(StampFactory.illegal());
+        super(StampFactory.forVoid());
     }
 
-
     @Override
     public void generate(LIRGeneratorTool gen) {
         gen.visitSafepointNode(this);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,9 +22,11 @@
  */
 package com.oracle.graal.nodes;
 
+import java.util.*;
+
 import com.oracle.graal.graph.*;
 
-public class ScheduledNode extends Node {
+public abstract class ScheduledNode extends Node {
 
     @Successor private ScheduledNode scheduledNext; // the immediate successor of the current node
 
@@ -33,7 +35,20 @@
     }
 
     public void setScheduledNext(ScheduledNode x) {
-        updatePredecessors(scheduledNext, x);
+        updatePredecessor(scheduledNext, x);
         scheduledNext = x;
     }
+
+    @Override
+    public Map<Object, Object> getDebugProperties() {
+        Map<Object, Object> debugProperties = super.getDebugProperties();
+        if (this instanceof StateSplit) {
+            StateSplit stateSplit = (StateSplit) this;
+            if (stateSplit.stateAfter() != null) {
+                debugProperties.put("stateAfter", stateSplit.stateAfter().toString(Verbosity.Debugger));
+            }
+        }
+        return debugProperties;
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * The start node of a graph.
+ */
+public class StartNode extends BeginStateSplitNode {
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StateSplit.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,6 +22,9 @@
  */
 package com.oracle.graal.nodes;
 
+/**
+ * A state split is a node that may have a frame state associated with it.
+ */
 public interface StateSplit {
 
     /**
@@ -35,9 +38,9 @@
     void setStateAfter(FrameState x);
 
     /**
-     * Determines if the caller should create an {@link #stateAfter() after}
-     * frame state for this node if it doesn't already have one.
+     * Determines if this node has a side-effect. Execution of such a node changes
+     * state visible to other threads. These nodes denote boundaries across which deoptimization
+     * points cannot be moved.
      */
-    boolean needsStateAfter();
-
+    boolean hasSideEffect();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 import java.util.concurrent.atomic.*;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
@@ -40,8 +40,8 @@
 
     public static final long INVALID_GRAPH_ID = -1;
     private static final AtomicLong uniqueGraphIds = new AtomicLong();
-    private final BeginNode start;
-    private final RiResolvedMethod method;
+    private final StartNode start;
+    private final ResolvedJavaMethod method;
     private final long graphId;
 
     /**
@@ -58,26 +58,47 @@
         this(name, null);
     }
 
-    public StructuredGraph(String name, RiResolvedMethod method) {
+    public StructuredGraph(String name, ResolvedJavaMethod method) {
         this(name, method, uniqueGraphIds.incrementAndGet());
     }
 
-    private StructuredGraph(String name, RiResolvedMethod method, long graphId) {
+    private StructuredGraph(String name, ResolvedJavaMethod method, long graphId) {
         super(name);
-        this.start = add(new BeginNode());
+        this.start = add(new StartNode());
         this.method = method;
         this.graphId = graphId;
     }
 
-    public StructuredGraph(RiResolvedMethod method) {
+    public StructuredGraph(ResolvedJavaMethod method) {
         this(null, method);
     }
 
-    public BeginNode start() {
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder(getClass().getSimpleName() + ":" + graphId);
+        String sep = "{";
+        if (name != null) {
+            buf.append(sep);
+            buf.append(name);
+            sep = ", ";
+        }
+        if (method != null) {
+            buf.append(sep);
+            buf.append(method);
+            sep = ", ";
+        }
+
+        if (!sep.equals("{")) {
+            buf.append("}");
+        }
+        return buf.toString();
+    }
+
+    public StartNode start() {
         return start;
     }
 
-    public RiResolvedMethod method() {
+    public ResolvedJavaMethod method() {
         return method;
     }
 
@@ -152,7 +173,7 @@
     }
 
     public boolean hasLoops() {
-        return getNodes(LoopBeginNode.class).iterator().hasNext();
+        return getNodes(LoopBeginNode.class).isNotEmpty();
     }
 
     public void removeFloating(FloatingNode node) {
@@ -180,7 +201,7 @@
         assert node.usages().isEmpty() : node + " " + node.usages();
         FixedNode next = node.next();
         node.setNext(null);
-        node.replaceAtPredecessors(next);
+        node.replaceAtPredecessor(next);
         node.safeDelete();
     }
 
@@ -207,7 +228,7 @@
         assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
         FixedNode next = node.next();
         node.setNext(null);
-        node.replaceAtPredecessors(next);
+        node.replaceAtPredecessor(next);
         node.replaceAtUsages(replacement);
         node.safeDelete();
     }
@@ -220,7 +241,7 @@
         for (int i = 0; i < node.blockSuccessorCount(); i++) {
             node.setBlockSuccessor(i, null);
         }
-        node.replaceAtPredecessors(begin);
+        node.replaceAtPredecessor(begin);
         node.safeDelete();
     }
 
@@ -232,15 +253,15 @@
         for (int i = 0; i < node.blockSuccessorCount(); i++) {
             BeginNode successor = node.blockSuccessor(i);
             node.setBlockSuccessor(i, null);
-            if (successor != begin && successor.isAlive()) {
+            if (successor != null && successor != begin && successor.isAlive()) {
                 GraphUtil.killCFG(successor);
             }
         }
         if (begin.isAlive()) {
-            node.replaceAtPredecessors(begin);
+            node.replaceAtPredecessor(begin);
             node.safeDelete();
         } else {
-            assert node.isDeleted();
+            assert node.isDeleted() : node + " " + begin;
         }
     }
 
@@ -272,7 +293,7 @@
         for (int i = 0; i < node.blockSuccessorCount(); i++) {
             node.setBlockSuccessor(i, null);
         }
-        node.replaceAtPredecessors(begin);
+        node.replaceAtPredecessor(begin);
         node.replaceAtUsages(replacement);
         node.safeDelete();
     }
@@ -302,6 +323,7 @@
             reduceTrivialMerge(begin);
         } else { // convert to merge
             MergeNode merge = this.add(new MergeNode());
+            merge.setProbability(begin.probability());
             this.replaceFixedWithFixed(begin, merge);
         }
     }
@@ -328,11 +350,11 @@
         // evacuateGuards
         merge.prepareDelete((FixedNode) singleEnd.predecessor());
         merge.safeDelete();
-        if (stateAfter != null && stateAfter.usages().isEmpty()) {
-            stateAfter.safeDelete();
+        if (stateAfter != null && stateAfter.isAlive() && stateAfter.usages().isEmpty()) {
+            GraphUtil.killWithUnusedFloatingInputs(stateAfter);
         }
         if (sux == null) {
-            singleEnd.replaceAtPredecessors(null);
+            singleEnd.replaceAtPredecessor(null);
             singleEnd.safeDelete();
         } else {
             singleEnd.replaceAndDelete(sux);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -39,13 +40,13 @@
     }
 
     public UnwindNode(ValueNode exception) {
-        super(StampFactory.forKind(CiKind.Object));
-        assert exception == null || exception.kind() == CiKind.Object;
+        super(StampFactory.forVoid());
+        assert exception == null || exception.kind() == Kind.Object;
         this.exception = exception;
     }
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.emitCallToRuntime(CiRuntimeCall.UnwindException, false, gen.operand(exception()));
+        gen.emitCall(RuntimeCall.UnwindException, false, gen.operand(exception()));
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,10 +24,12 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.type.GenericStamp.*;
+import com.oracle.graal.nodes.util.*;
 
 /**
  * This class represents a value within the graph, including local variables, phis, and
@@ -36,14 +38,17 @@
 public abstract class ValueNode extends ScheduledNode implements StampProvider {
 
     /**
-     * The kind of this value. This is {@link CiKind#Void} for instructions that produce no value.
-     * This kind is guaranteed to be a {@linkplain CiKind#stackKind() stack kind}.
+     * The kind of this value. This is {@link Kind#Void} for instructions that produce no value.
+     * This kind is guaranteed to be a {@linkplain Kind#stackKind() stack kind}.
      */
     private Stamp stamp;
 
-    @Input private NodeInputList<Node> dependencies;
+    @Input(notDataflow = true) private NodeInputList<ValueNode> dependencies;
 
-    public NodeInputList<Node> dependencies() {
+    /**
+     * This collection keeps dependencies that should be observed while scheduling (guards, etc.).
+     */
+    public NodeInputList<ValueNode> dependencies() {
         return dependencies;
     }
 
@@ -53,7 +58,13 @@
         assert kind() != null && kind() == kind().stackKind() : kind() + " != " + kind().stackKind();
     }
 
-    public ValueNode(Stamp stamp, Node... dependencies) {
+    public ValueNode(Stamp stamp, ValueNode... dependencies) {
+        this.stamp = stamp;
+        this.dependencies = new NodeInputList<>(this, dependencies);
+        assert kind() != null && kind() == kind().stackKind() : kind() + " != " + kind().stackKind();
+    }
+
+    public ValueNode(Stamp stamp, List<ValueNode> dependencies) {
         this.stamp = stamp;
         this.dependencies = new NodeInputList<>(this, dependencies);
         assert kind() != null && kind() == kind().stackKind() : kind() + " != " + kind().stackKind();
@@ -67,20 +78,59 @@
         this.stamp = stamp;
     }
 
-    public CiKind kind() {
+    /**
+     * Checks if the given stamp is different than the current one ({@code newStamp.equals(oldStamp) == false}). If it
+     * is different then the new stamp will become the current stamp for this node.
+     *
+     * @return true if the stamp has changed, false otherwise.
+     */
+    protected final boolean updateStamp(Stamp newStamp) {
+        if (newStamp.equals(stamp)) {
+            return false;
+        } else {
+            stamp = newStamp;
+            return true;
+        }
+    }
+
+    /**
+     * This method can be overridden by subclasses of {@link ValueNode} if they need to recompute their stamp if their
+     * inputs change. A typical implementation will compute the stamp and pass it to {@link #updateStamp(Stamp)}, whose
+     * return value can be used as the result of this method.
+     *
+     * @return true if the stamp has changed, false otherwise.
+     */
+    public boolean inferStamp() {
+        return false;
+    }
+
+    public Kind kind() {
         return stamp.kind();
     }
 
     /**
      * Checks whether this value is a constant (i.e. it is of type {@link ConstantNode}.
+     *
      * @return {@code true} if this value is a constant
      */
     public final boolean isConstant() {
         return this instanceof ConstantNode;
     }
 
+    private static final NodePredicate IS_CONSTANT = new NodePredicate() {
+        @Override
+        public boolean apply(Node n) {
+            return n instanceof ValueNode && ((ValueNode) n).isConstant();
+        }
+    };
+
+    public static NodePredicate isConstantPredicate() {
+        return IS_CONSTANT;
+    }
+
     /**
      * Checks whether this value represents the null constant.
+     *
      * @return {@code true} if this value represents the null constant
      */
     public final boolean isNullConstant() {
@@ -89,30 +139,44 @@
 
     /**
      * Convert this value to a constant if it is a constant, otherwise return null.
-     * @return the {@link CiConstant} represented by this value if it is a constant; {@code null}
-     * otherwise
+     *
+     * @return the {@link Constant} represented by this value if it is a constant; {@code null} otherwise
      */
-    public final CiConstant asConstant() {
+    public final Constant asConstant() {
         if (this instanceof ConstantNode) {
             return ((ConstantNode) this).value;
         }
         return null;
     }
 
-    /**
-     * Computes the exact type of the result of this node, if possible.
-     * @return the exact type of the result of this node, if it is known; {@code null} otherwise
-     */
-    public final RiResolvedType exactType() {
-        return stamp.exactType();
+    public <T extends Stamp> boolean verifyStamp(Class<T> stampClass) {
+        assert stamp != null;
+        assert stampClass.isInstance(stamp) : this + " (" + GraphUtil.approxSourceLocation(this) + ") has unexpected stamp type: expected " + stampClass.getName() +
+            ", got " + stamp.getClass().getName();
+        return true;
+    }
+
+    public final ObjectStamp objectStamp() {
+        assert verifyStamp(ObjectStamp.class);
+        return (ObjectStamp) stamp;
     }
 
-    /**
-     * Computes the declared type of the result of this node, if possible.
-     * @return the declared type of the result of this node, if it is known; {@code null} otherwise
-     */
-    public final RiResolvedType declaredType() {
-        return stamp.declaredType();
+    public final IntegerStamp integerStamp() {
+        assert verifyStamp(IntegerStamp.class);
+        return (IntegerStamp) stamp;
+    }
+
+    public final FloatStamp floatStamp() {
+        assert verifyStamp(FloatStamp.class);
+        return (FloatStamp) stamp;
+    }
+
+    @Override
+    public boolean verify() {
+        for (ValueNode v : dependencies().nonNull()) {
+            assertTrue(!(v.stamp() instanceof GenericStamp) || ((GenericStamp) v.stamp()).type() == GenericStampType.Dependency, "cannot depend on node with stamp %s", v.stamp());
+        }
+        return super.verify();
     }
 
     @Override
@@ -121,7 +185,7 @@
         if (!dependencies.isEmpty()) {
             StringBuilder str = new StringBuilder();
             for (int i = 0; i < dependencies.size(); i++) {
-                str.append(i == 0 ? "" : ", ").append(dependencies.get(i).toString(Verbosity.Id));
+                str.append(i == 0 ? "" : ", ").append(dependencies.get(i) == null ? "null" : dependencies.get(i).toString(Verbosity.Id));
             }
             properties.put("dependencies", str.toString());
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.Verbosity;
+
+
+public class ValueNodeUtil {
+
+    public static ValueNode assertKind(Kind kind, ValueNode x) {
+        assert x != null && ((x.kind() == kind) || (x.kind() == Kind.Jsr && kind == Kind.Object)) : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.kind());
+        return x;
+    }
+
+    public static RuntimeException shouldNotReachHere(String msg) {
+        throw new InternalError("should not reach here: " + msg);
+    }
+
+    public static RuntimeException shouldNotReachHere() {
+        throw new InternalError("should not reach here");
+    }
+
+    public static ValueNode assertLong(ValueNode x) {
+        assert x != null && (x.kind() == Kind.Long);
+        return x;
+    }
+
+    public static ValueNode assertJsr(ValueNode x) {
+        assert x != null && (x.kind() == Kind.Jsr);
+        return x;
+    }
+
+    public static ValueNode assertInt(ValueNode x) {
+        assert x != null && (x.kind() == Kind.Int);
+        return x;
+    }
+
+    public static ValueNode assertFloat(ValueNode x) {
+        assert x != null && (x.kind() == Kind.Float);
+        return x;
+    }
+
+    public static ValueNode assertObject(ValueNode x) {
+        assert x != null && (x.kind() == Kind.Object);
+        return x;
+    }
+
+    public static ValueNode assertDouble(ValueNode x) {
+        assert x != null && (x.kind() == Kind.Double);
+        return x;
+    }
+
+    public static void assertHigh(ValueNode x) {
+        assert x == null;
+    }
+
+    public static boolean typeMismatch(ValueNode x, ValueNode y) {
+        return y == null || x == null || x.kind() != y.kind();
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <T extends Node> Collection<T> filter(Iterable<Node> nodes, Class<T> clazz) {
+        ArrayList<T> phis = new ArrayList<>();
+        for (Node node : nodes) {
+            if (clazz.isInstance(node)) {
+                phis.add((T) node);
+            }
+        }
+        return phis;
+    }
+
+    /**
+     * Converts a given instruction to a value string. The representation of an node as
+     * a value is formed by concatenating the {@linkplain com.oracle.graal.api.meta.Kind#typeChar character} denoting its
+     * {@linkplain ValueNode#kind kind} and its {@linkplain Node#id()}. For example, {@code "i13"}.
+     *
+     * @param value the instruction to convert to a value string. If {@code value == null}, then "-" is returned.
+     * @return the instruction representation as a string
+     */
+    public static String valueString(ValueNode value) {
+        return (value == null) ? "-" : ("" + value.kind().typeChar + value.toString(Verbosity.Id));
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,17 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.graph.Node;
-import com.oracle.graal.graph.Node.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.ValueNumberable;
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
-
+import com.oracle.graal.nodes.type.*;
 
-
+/**
+ * A value proxy that is inserted in the frame state of a loop exit for any value that is
+ * created inside the loop (i.e. was not live on entry to the loop) and is (potentially)
+ * used after the loop.
+ */
 public class ValueProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable {
     @Input(notDataflow = true) private BeginNode proxyPoint;
     @Input private ValueNode value;
@@ -46,6 +50,16 @@
         return value;
     }
 
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(value.stamp());
+    }
+
+    @Override
+    public Stamp stamp() {
+        return value().stamp();
+    }
+
     public BeginNode proxyPoint() {
         return proxyPoint;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node.Verbosity;
-
-
-public class ValueUtil {
-
-    public static ValueNode assertKind(CiKind kind, ValueNode x) {
-        assert x != null && ((x.kind() == kind) || (x.kind() == CiKind.Jsr && kind == CiKind.Object)) : "kind=" + kind + ", value=" + x + ((x == null) ? "" : ", value.kind=" + x.kind());
-        return x;
-    }
-
-    public static RuntimeException shouldNotReachHere(String msg) {
-        throw new InternalError("should not reach here: " + msg);
-    }
-
-    public static RuntimeException shouldNotReachHere() {
-        throw new InternalError("should not reach here");
-    }
-
-    public static ValueNode assertLong(ValueNode x) {
-        assert x != null && (x.kind() == CiKind.Long);
-        return x;
-    }
-
-    public static ValueNode assertJsr(ValueNode x) {
-        assert x != null && (x.kind() == CiKind.Jsr);
-        return x;
-    }
-
-    public static ValueNode assertInt(ValueNode x) {
-        assert x != null && (x.kind() == CiKind.Int);
-        return x;
-    }
-
-    public static ValueNode assertFloat(ValueNode x) {
-        assert x != null && (x.kind() == CiKind.Float);
-        return x;
-    }
-
-    public static ValueNode assertObject(ValueNode x) {
-        assert x != null && (x.kind() == CiKind.Object);
-        return x;
-    }
-
-    public static ValueNode assertDouble(ValueNode x) {
-        assert x != null && (x.kind() == CiKind.Double);
-        return x;
-    }
-
-    public static void assertHigh(ValueNode x) {
-        assert x == null;
-    }
-
-    public static boolean typeMismatch(ValueNode x, ValueNode y) {
-        return y == null || x == null || x.kind() != y.kind();
-    }
-
-
-    @SuppressWarnings("unchecked")
-    public static <T extends Node> Collection<T> filter(Iterable<Node> nodes, Class<T> clazz) {
-        ArrayList<T> phis = new ArrayList<>();
-        for (Node node : nodes) {
-            if (clazz.isInstance(node)) {
-                phis.add((T) node);
-            }
-        }
-        return phis;
-    }
-
-    /**
-     * Converts a given instruction to a value string. The representation of an node as
-     * a value is formed by concatenating the {@linkplain com.oracle.max.cri.ci.CiKind#typeChar character} denoting its
-     * {@linkplain ValueNode#kind kind} and its {@linkplain Node#id()}. For example, {@code "i13"}.
-     *
-     * @param value the instruction to convert to a value string. If {@code value == null}, then "-" is returned.
-     * @return the instruction representation as a string
-     */
-    public static String valueString(ValueNode value) {
-        return (value == null) ? "-" : ("" + value.kind().typeChar + value.toString(Verbosity.Id));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/VirtualState.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 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;
+
+import com.oracle.graal.graph.*;
+
+/**
+ * Base class for nodes that contain "virtual" state, like FrameState and VirtualObjectState.
+ * Subclasses of this class will be treated in a special way by the scheduler.
+ */
+public abstract class VirtualState extends Node {
+
+    public interface NodeClosure<T extends Node> {
+        void apply(Node usage, T node);
+    }
+
+    public abstract VirtualState duplicateWithVirtualState();
+
+    public abstract void applyToNonVirtual(NodeClosure<? super ValueNode> closure);
+
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,19 +22,25 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "&")
 public final class AndNode extends LogicNode implements Canonicalizable, LIRLowerable {
 
-    public AndNode(CiKind kind, ValueNode x, ValueNode y) {
+    public AndNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.and(x().integerStamp(), y().integerStamp()));
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return x();
@@ -43,14 +49,14 @@
             return graph().unique(new AndNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph());
             }
         } else if (y().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 int c = y().asConstant().asInt();
                 if (c == -1) {
                     return x();
@@ -59,7 +65,7 @@
                     return ConstantNode.forInt(0, graph());
                 }
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 long c = y().asConstant().asLong();
                 if (c == -1) {
                     return x();
@@ -68,6 +74,7 @@
                     return ConstantNode.forLong(0, graph());
                 }
             }
+            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ArithmeticNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ArithmeticNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -39,7 +39,7 @@
      * @param y the second input instruction
      * @param isStrictFP indicates this operation has strict rounding semantics
      */
-    public ArithmeticNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+    public ArithmeticNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
         super(kind, x, y);
         this.isStrictFP = isStrictFP;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,9 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -48,9 +50,140 @@
      * @param x the first input instruction
      * @param y the second input instruction
      */
-    public BinaryNode(CiKind kind, ValueNode x, ValueNode y) {
+    public BinaryNode(Kind kind, ValueNode x, ValueNode y) {
         super(StampFactory.forKind(kind));
         this.x = x;
         this.y = y;
     }
+
+    public enum ReassociateMatch {
+        x,
+        y;
+
+        public ValueNode getValue(BinaryNode binary) {
+            switch(this) {
+                case x:
+                    return binary.x();
+                case y:
+                    return binary.y();
+                default: throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+
+        public ValueNode getOtherValue(BinaryNode binary) {
+            switch(this) {
+                case x:
+                    return binary.y();
+                case y:
+                    return binary.x();
+                default: throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+    }
+
+    public static boolean canTryReassociate(BinaryNode node) {
+        return node instanceof IntegerAddNode || node instanceof IntegerSubNode || node instanceof IntegerMulNode
+                        || node instanceof AndNode || node instanceof OrNode || node instanceof XorNode;
+    }
+
+    public static ReassociateMatch findReassociate(BinaryNode binary, NodePredicate criterion) {
+        boolean resultX = criterion.apply(binary.x());
+        boolean resultY = criterion.apply(binary.y());
+        if (resultX && !resultY) {
+            return ReassociateMatch.x;
+        }
+        if (!resultX && resultY) {
+            return ReassociateMatch.y;
+        }
+        return null;
+    }
+
+    /* In reassociate, complexity comes from the handling of IntegerSub (non commutative) which can be mixed with IntegerAdd.
+     * if first tries to find m1, m2 which match the criterion :
+     * (a o m2) o m1
+     * (m2 o a) o m1
+     * m1 o (a o m2)
+     * m1 o (m2 o a)
+     * It then produces 4 boolean for the -/+ case
+     *  invertA : should the final expression be like *-a (rather than a+*)
+     *  aSub : should the final expression be like a-* (rather than a+*)
+     *  invertM1 : should the final expression contain -m1
+     *  invertM2 : should the final expression contain -m2
+     */
+    /**
+     * Tries to re-associate values which satisfy the criterion.
+     * For example with a constantness criterion : (a + 2) + 1 => a + (1 + 2)<br>
+     * This method accepts only reassociable operations (see {@linkplain #canTryReassociate(BinaryNode)}) such as +, -, *, &, | and ^
+     */
+    public static BinaryNode reassociate(BinaryNode node, NodePredicate criterion) {
+        assert canTryReassociate(node);
+        ReassociateMatch match1 = findReassociate(node, criterion);
+        if (match1 == null) {
+            return node;
+        }
+        ValueNode otherValue = match1.getOtherValue(node);
+        boolean addSub = false;
+        boolean subAdd = false;
+        if (otherValue.getClass() != node.getClass()) {
+            if (node instanceof IntegerAddNode && otherValue instanceof IntegerSubNode) {
+                addSub = true;
+            } else if (node instanceof IntegerSubNode && otherValue instanceof IntegerAddNode) {
+                subAdd = true;
+            } else {
+                return node;
+            }
+        }
+        BinaryNode other = (BinaryNode) otherValue;
+        ReassociateMatch match2 = findReassociate(other, criterion);
+        if (match2 == null) {
+            return node;
+        }
+        boolean invertA = false;
+        boolean aSub =  false;
+        boolean invertM1 = false;
+        boolean invertM2 = false;
+        if (addSub) {
+            invertM2 = match2 == ReassociateMatch.y;
+            invertA = !invertM2;
+        } else if (subAdd) {
+            invertA = invertM2 = match1 == ReassociateMatch.x;
+            invertM1 = !invertM2;
+        } else if (node instanceof IntegerSubNode && other instanceof IntegerSubNode) {
+            invertA = match1 == ReassociateMatch.x ^ match2 == ReassociateMatch.x;
+            aSub = match1 == ReassociateMatch.y && match2 == ReassociateMatch.y;
+            invertM1 = match1 == ReassociateMatch.y && match2 == ReassociateMatch.x;
+            invertM2 = match1 == ReassociateMatch.x && match2 == ReassociateMatch.x;
+        }
+        assert !(invertM1 && invertM2) && !(invertA && aSub);
+        ValueNode m1 = match1.getValue(node);
+        ValueNode m2 = match2.getValue(other);
+        ValueNode a = match2.getOtherValue(other);
+        if (node instanceof IntegerAddNode || node instanceof IntegerSubNode) {
+            BinaryNode associated;
+            if (invertM1) {
+                associated = IntegerArithmeticNode.sub(m2, m1);
+            } else if (invertM2) {
+                associated = IntegerArithmeticNode.sub(m1, m2);
+            } else {
+                associated = IntegerArithmeticNode.add(m1, m2);
+            }
+            if (invertA) {
+                return IntegerArithmeticNode.sub(associated, a);
+            }
+            if (aSub) {
+                return IntegerArithmeticNode.sub(a, associated);
+            }
+            return IntegerArithmeticNode.add(a, associated);
+        } else if (node instanceof IntegerMulNode) {
+            return IntegerArithmeticNode.mul(a, IntegerAddNode.mul(m1, m2));
+        } else if (node instanceof AndNode) {
+            return LogicNode.and(a, LogicNode.and(m1, m2));
+        } else if (node instanceof OrNode) {
+            return LogicNode.or(a, LogicNode.or(m1, m2));
+        } else if (node instanceof XorNode) {
+            return LogicNode.xor(a, LogicNode.xor(m1, m2));
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.spi.types.*;
 import com.oracle.graal.nodes.type.*;
 
 /* TODO (thomaswue/gdub) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node)
@@ -35,14 +35,11 @@
  * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed
  * into variants that do not materialize the value (CompareIf, CompareGuard...)
  */
-public final class CompareNode extends BooleanNode implements Canonicalizable, LIRLowerable, ConditionalTypeFeedbackProvider, TypeCanonicalizable {
+public abstract class CompareNode extends BooleanNode implements Canonicalizable, LIRLowerable {
 
     @Input private ValueNode x;
     @Input private ValueNode y;
 
-    private final Condition condition;
-    private final boolean unorderedIsTrue;
-
     public ValueNode x() {
         return x;
     }
@@ -55,27 +52,11 @@
      * Constructs a new Compare instruction.
      *
      * @param x the instruction producing the first input to the instruction
-     * @param condition the condition (comparison operation)
      * @param y the instruction that produces the second input to this instruction
-     * @param graph
      */
-    public CompareNode(ValueNode x, Condition condition, ValueNode y) {
-        this(x, condition, false, y);
-    }
-
-    /**
-     * Constructs a new Compare instruction.
-     *
-     * @param x the instruction producing the first input to the instruction
-     * @param condition the condition (comparison operation)
-     * @param y the instruction that produces the second input to this instruction
-     * @param graph
-     */
-    public CompareNode(ValueNode x, Condition condition, boolean unorderedIsTrue, ValueNode y) {
-        super(StampFactory.illegal());
+    public CompareNode(ValueNode x, ValueNode y) {
+        super(StampFactory.condition());
         assert (x == null && y == null) || x.kind() == y.kind();
-        this.condition = condition;
-        this.unorderedIsTrue = unorderedIsTrue;
         this.x = x;
         this.y = y;
     }
@@ -85,44 +66,27 @@
      *
      * @return the condition
      */
-    public Condition condition() {
-        return condition;
-    }
+    public abstract Condition condition();
 
     /**
-     * Checks whether unordered inputs mean true or false.
+     * Checks whether unordered inputs mean true or false (only applies to float operations).
      *
      * @return {@code true} if unordered inputs produce true
      */
-    public boolean unorderedIsTrue() {
-        return unorderedIsTrue;
-    }
-
-    @Override
-    public BooleanNode negate() {
-        return graph().unique(new CompareNode(x(), condition.negate(), !unorderedIsTrue, y()));
-    }
+    public abstract boolean unorderedIsTrue();
 
     @Override
     public void generate(LIRGeneratorTool gen) {
     }
 
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name) {
-            return super.toString(Verbosity.Name) + " " + condition.operator;
-        } else {
-            return super.toString(verbosity);
-        }
-    }
 
-    private ValueNode optimizeMaterialize(CiConstant constant, MaterializeNode materializeNode, RiRuntime runtime) {
-        CiConstant trueConstant = materializeNode.trueValue().asConstant();
-        CiConstant falseConstant = materializeNode.falseValue().asConstant();
+    private ValueNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, CodeCacheProvider runtime, Condition cond) {
+        Constant trueConstant = conditionalNode.trueValue().asConstant();
+        Constant falseConstant = conditionalNode.falseValue().asConstant();
 
-        if (falseConstant != null && trueConstant != null) {
-            Boolean trueResult = condition().foldCondition(trueConstant, constant, runtime, unorderedIsTrue());
-            Boolean falseResult = condition().foldCondition(falseConstant, constant, runtime, unorderedIsTrue());
+        if (falseConstant != null && trueConstant != null && runtime != null) {
+            Boolean trueResult = cond.foldCondition(trueConstant, constant, runtime, unorderedIsTrue());
+            Boolean falseResult = cond.foldCondition(falseConstant, constant, runtime, unorderedIsTrue());
 
             if (trueResult != null && falseResult != null) {
                 boolean trueUnboxedResult = trueResult;
@@ -132,10 +96,11 @@
                 } else {
                     if (trueUnboxedResult) {
                         assert falseUnboxedResult == false;
-                        return materializeNode.condition();
+                        return conditionalNode.condition();
                     } else {
                         assert falseUnboxedResult == true;
-                        return materializeNode.condition().negate();
+                        negateUsages();
+                        return conditionalNode.condition();
 
                     }
                 }
@@ -144,162 +109,27 @@
         return this;
     }
 
-    private ValueNode optimizeNormalizeCmp(CiConstant constant, NormalizeCompareNode normalizeNode) {
-        if (constant.kind == CiKind.Int && constant.asInt() == 0) {
-            Condition cond = condition();
-            boolean isLess = cond == Condition.LE || cond == Condition.LT || cond == Condition.BE || cond == Condition.BT;
-            boolean canonUnorderedIsTrue = cond != Condition.EQ && (cond == Condition.NE || !(isLess ^ normalizeNode.isUnorderedLess));
-            CompareNode result = graph().unique(new CompareNode(normalizeNode.x(), cond, canonUnorderedIsTrue, normalizeNode.y()));
-            return result;
-        }
-        return this;
+    protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
+        throw new GraalInternalError("NormalizeCompareNode connected to %s (%s %s %s)", this, constant, normalizeNode, mirrored);
     }
 
-    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (x().isConstant() && !y().isConstant()) { // move constants to the left (y)
-            return graph().unique(new CompareNode(y(), condition.mirror(), unorderedIsTrue(), x()));
-        } else if (x().isConstant() && y().isConstant()) {
-            CiConstant constX = x().asConstant();
-            CiConstant constY = y().asConstant();
-            Boolean result = condition().foldCondition(constX, constY, tool.runtime(), unorderedIsTrue());
-            if (result != null) {
-                return ConstantNode.forBoolean(result, graph());
-            }
-        }
-
-        if (y().isConstant()) {
-            if (x() instanceof MaterializeNode) {
-                return optimizeMaterialize(y().asConstant(), (MaterializeNode) x(), tool.runtime());
-            } else if (x() instanceof NormalizeCompareNode) {
-                return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x());
-            }
+        if (x().isConstant() && y().isConstant() && tool.runtime() != null) {
+            return ConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.runtime(), unorderedIsTrue()), graph());
         }
-
-        if (x() == y() && x().kind() != CiKind.Float && x().kind() != CiKind.Double) {
-            return ConstantNode.forBoolean(condition().check(1, 1), graph());
-        }
-        if ((condition == Condition.NE || condition == Condition.EQ) && x().kind() == CiKind.Object) {
-            ValueNode object = null;
-            if (x().isNullConstant()) {
-                object = y();
-            } else if (y().isNullConstant()) {
-                object = x();
+        if (x().isConstant()) {
+            if (y() instanceof ConditionalNode) {
+                return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.runtime(), condition().mirror());
+            } else if (y() instanceof NormalizeCompareNode) {
+                return optimizeNormalizeCmp(x().asConstant(), (NormalizeCompareNode) y(), true);
             }
-            if (object != null) {
-                return graph().unique(new NullCheckNode(object, condition == Condition.EQ));
-            } else {
-                Stamp xStamp = x.stamp();
-                Stamp yStamp = y.stamp();
-                if (xStamp.alwaysDistinct(yStamp)) {
-                    return ConstantNode.forBoolean(condition == Condition.NE, graph());
-                }
+        } else if (y().isConstant()) {
+            if (x() instanceof ConditionalNode) {
+                return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.runtime(), condition());
+            } else if (x() instanceof NormalizeCompareNode) {
+                return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x(), false);
             }
         }
         return this;
     }
-
-    @Override
-    public void typeFeedback(TypeFeedbackTool tool) {
-        CiKind kind = x().kind();
-        assert y().kind() == kind;
-        if (kind == CiKind.Object) {
-            assert condition == Condition.EQ || condition == Condition.NE;
-            if (y().isConstant() && !x().isConstant()) {
-                tool.addObject(x()).constantBound(condition, y().asConstant());
-            } else if (x().isConstant() && !y().isConstant()) {
-                tool.addObject(y()).constantBound(condition.mirror(), x().asConstant());
-            } else if (!x().isConstant() && !y.isConstant()) {
-                tool.addObject(x()).valueBound(condition, y());
-                tool.addObject(y()).valueBound(condition.mirror(), x());
-            } else {
-                // both are constant, this should be canonicalized...
-            }
-        } else if (kind == CiKind.Int || kind == CiKind.Long) {
-            assert condition != Condition.NOF && condition != Condition.OF;
-            if (y().isConstant() && !x().isConstant()) {
-                tool.addScalar(x()).constantBound(condition, y().asConstant());
-            } else if (x().isConstant() && !y().isConstant()) {
-                tool.addScalar(y()).constantBound(condition.mirror(), x().asConstant());
-            } else if (!x().isConstant() && !y.isConstant()) {
-                tool.addScalar(x()).valueBound(condition, y(), tool.queryScalar(y()));
-                tool.addScalar(y()).valueBound(condition.mirror(), x(), tool.queryScalar(x()));
-            } else {
-                // both are constant, this should be canonicalized...
-            }
-        } else if (kind == CiKind.Float || kind == CiKind.Double) {
-            // nothing yet...
-        }
-    }
-
-    @Override
-    public Result canonical(TypeFeedbackTool tool) {
-        CiKind kind = x().kind();
-        if (kind == CiKind.Int || kind == CiKind.Long) {
-            assert condition != Condition.NOF && condition != Condition.OF;
-            ScalarTypeQuery queryX = tool.queryScalar(x());
-            if (y().isConstant() && !x().isConstant()) {
-                if (queryX.constantBound(condition, y().asConstant())) {
-                    return new Result(ConstantNode.forBoolean(true, graph()), queryX);
-                } else if (queryX.constantBound(condition.negate(), y().asConstant())) {
-                    return new Result(ConstantNode.forBoolean(false, graph()), queryX);
-                }
-            } else {
-                ScalarTypeQuery queryY = tool.queryScalar(y());
-                if (x().isConstant() && !y().isConstant()) {
-                    if (queryY.constantBound(condition.mirror(), x().asConstant())) {
-                        return new Result(ConstantNode.forBoolean(true, graph()), queryY);
-                    } else if (queryY.constantBound(condition.mirror().negate(), x().asConstant())) {
-                        return new Result(ConstantNode.forBoolean(false, graph()), queryY);
-                    }
-                } else if (!x().isConstant() && !y.isConstant()) {
-                    if (condition == Condition.BT || condition == Condition.BE) {
-                        if (queryY.constantBound(Condition.GE, new CiConstant(kind, 0))) {
-                            if (queryX.constantBound(Condition.GE, new CiConstant(kind, 0))) {
-                                if (queryX.valueBound(condition == Condition.BT ? Condition.LT : Condition.LE, y())) {
-                                    return new Result(ConstantNode.forBoolean(true, graph()), queryX, queryY);
-                                }
-                            }
-                        }
-                    }
-
-                    if (queryX.valueBound(condition, y())) {
-                        return new Result(ConstantNode.forBoolean(true, graph()), queryX);
-                    } else if (queryX.valueBound(condition.negate(), y())) {
-                        return new Result(ConstantNode.forBoolean(false, graph()), queryX);
-                    }
-                } else {
-                    // both are constant, this should be canonicalized...
-                }
-            }
-        } else  if (kind == CiKind.Object) {
-            assert condition == Condition.EQ || condition == Condition.NE;
-            ObjectTypeQuery queryX = tool.queryObject(x());
-            if (y().isConstant() && !x().isConstant()) {
-                if (queryX.constantBound(condition, y().asConstant())) {
-                    return new Result(ConstantNode.forBoolean(true, graph()), queryX);
-                } else if (queryX.constantBound(condition.negate(), y().asConstant())) {
-                    return new Result(ConstantNode.forBoolean(false, graph()), queryX);
-                }
-            } else {
-                ObjectTypeQuery queryY = tool.queryObject(y());
-                if (x().isConstant() && !y().isConstant()) {
-                    if (queryY.constantBound(condition.mirror(), x().asConstant())) {
-                        return new Result(ConstantNode.forBoolean(true, graph()), queryY);
-                    } else if (queryY.constantBound(condition.mirror().negate(), x().asConstant())) {
-                        return new Result(ConstantNode.forBoolean(false, graph()), queryY);
-                    }
-                } else if (!x().isConstant() && !y.isConstant()) {
-                    if (queryX.valueBound(condition, y())) {
-                        return new Result(ConstantNode.forBoolean(true, graph()), queryX);
-                    } else if (queryX.valueBound(condition.negate(), y())) {
-                        return new Result(ConstantNode.forBoolean(false, graph()), queryX);
-                    }
-                } else {
-                    // both are constant, this should be canonicalized...
-                }
-            }
-        }
-        return null;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.max.cri.util.*;
 
 /**
@@ -78,17 +79,7 @@
     /**
      * Unsigned less than ("below than").
      */
-    BT("|<|"),
-
-    /**
-     * Operation produced an overflow.
-     */
-    OF("overflow"),
-
-    /**
-     * Operation did not produce an overflow.
-     */
-    NOF("noOverflow");
+    BT("|<|");
 
     public final String operator;
 
@@ -109,7 +100,68 @@
             case AT: return UnsignedMath.aboveThan(left, right);
             case BT: return UnsignedMath.belowThan(left, right);
         }
-        throw new IllegalArgumentException();
+        throw new IllegalArgumentException(this.toString());
+    }
+
+    /**
+     * Given a condition and its negation, this method returns true for one of the two and false for the other one.
+     * This can be used to keep comparisons in a canonical form.
+     * @return true if this condition is considered to be the canonical form, false otherwise.
+     */
+    public boolean isCanonical() {
+        switch (this) {
+            case EQ: return true;
+            case NE: return false;
+            case LT: return true;
+            case LE: return false;
+            case GT: return false;
+            case GE: return false;
+            case BT: return true;
+            case BE: return false;
+            case AT: return false;
+            case AE: return false;
+        }
+        throw new IllegalArgumentException(this.toString());
+    }
+
+    /**
+     * Returns true if the condition needs to be mirrored to get to a canonical condition.
+     * The result of the mirroring operation might still need to be negated to achieve a canonical form.
+     */
+    public boolean canonicalMirror() {
+        switch (this) {
+            case EQ: return false;
+            case NE: return false;
+            case LT: return false;
+            case LE: return true;
+            case GT: return true;
+            case GE: return false;
+            case BT: return false;
+            case BE: return true;
+            case AT: return true;
+            case AE: return false;
+        }
+        throw new IllegalArgumentException(this.toString());
+    }
+
+    /**
+     * Returns true if the condition needs to be negated to get to a canonical condition.
+     * The result of the negation might still need to be mirrored to achieve a canonical form.
+     */
+    public boolean canonicalNegate() {
+        switch (this) {
+            case EQ: return false;
+            case NE: return true;
+            case LT: return false;
+            case LE: return true;
+            case GT: return false;
+            case GE: return true;
+            case BT: return false;
+            case BE: return true;
+            case AT: return false;
+            case AE: return true;
+        }
+        throw new IllegalArgumentException(this.toString());
     }
 
     /**
@@ -128,8 +180,6 @@
             case BE: return AT;
             case AT: return BE;
             case AE: return BT;
-            case OF: return NOF;
-            case NOF: return OF;
         }
         throw new IllegalArgumentException(this.toString());
     }
@@ -149,8 +199,6 @@
             case BE: return false;
             case AT: return other == AE || other == NE;
             case AE: return false;
-            case OF: return false;
-            case NOF: return false;
         }
         throw new IllegalArgumentException(this.toString());
     }
@@ -176,6 +224,13 @@
     }
 
     /**
+     * Returns true if this condition represents an unsigned comparison. EQ and NE are not considered to be unsigned.
+     */
+    public final boolean isUnsigned() {
+        return this == Condition.BT || this == Condition.BE || this == Condition.AT || this == Condition.AE;
+    }
+
+    /**
      * Checks if this conditional operation is commutative.
      * @return {@code true} if this operation is commutative
      */
@@ -189,9 +244,22 @@
      * @param rt the constant on the right side of the comparison
      * @param runtime the RiRuntime (might be needed to compare runtime-specific types)
      * @return {@link Boolean#TRUE} if the comparison is known to be true,
-     * {@link Boolean#FALSE} if the comparison is known to be false, {@code null} otherwise.
+     * {@link Boolean#FALSE} if the comparison is known to be false
      */
-    public Boolean foldCondition(CiConstant lt, CiConstant rt, RiRuntime runtime, boolean unorderedIsTrue) {
+    public boolean foldCondition(Constant lt, Constant rt, CodeCacheProvider runtime) {
+        assert !lt.kind.isFloatOrDouble() && !rt.kind.isFloatOrDouble();
+        return foldCondition(lt, rt, runtime, false);
+    }
+
+    /**
+     * Attempts to fold a comparison between two constants and return the result.
+     * @param lt the constant on the left side of the comparison
+     * @param rt the constant on the right side of the comparison
+     * @param runtime the RiRuntime (might be needed to compare runtime-specific types)
+     * @param unorderedIsTrue true if an undecided float comparison should result in "true"
+     * @return true if the comparison is known to be true, false if the comparison is known to be false
+     */
+    public boolean foldCondition(Constant lt, Constant rt, MetaAccessProvider runtime, boolean unorderedIsTrue) {
         switch (lt.kind) {
             case Boolean:
             case Byte:
@@ -212,8 +280,8 @@
                     case BE: return UnsignedMath.belowOrEqual(x, y);
                     case AT: return UnsignedMath.aboveThan(x, y);
                     case BT: return UnsignedMath.belowThan(x, y);
+                    default: throw new GraalInternalError("expected condition: %s", this);
                 }
-                break;
             }
             case Long: {
                 long x = lt.asLong();
@@ -229,15 +297,15 @@
                     case BE: return UnsignedMath.belowOrEqual(x, y);
                     case AT: return UnsignedMath.aboveThan(x, y);
                     case BT: return UnsignedMath.belowThan(x, y);
+                    default: throw new GraalInternalError("expected condition: %s", this);
                 }
-                break;
             }
             case Object: {
                 switch (this) {
                     case EQ: return runtime.areConstantObjectsEqual(lt, rt);
                     case NE: return !runtime.areConstantObjectsEqual(lt, rt);
+                    default: throw new GraalInternalError("expected condition: %s", this);
                 }
-                break;
             }
             case Float: {
                 float x = lt.asFloat();
@@ -252,6 +320,7 @@
                     case LE: return x <= y;
                     case GT: return x > y;
                     case GE: return x >= y;
+                    default: throw new GraalInternalError("expected condition: %s", this);
                 }
             }
             case Double: {
@@ -267,20 +336,17 @@
                     case LE: return x <= y;
                     case GT: return x > y;
                     case GE: return x >= y;
+                    default: throw new GraalInternalError("expected condition: %s", this);
                 }
             }
+            default: throw new GraalInternalError("expected value kind %s while folding condition: %s", lt.kind, this);
         }
-        assert false : "missed folding of constant operands: " + lt + " " + this + " " + rt;
-        return null;
     }
 
     public Condition join(Condition other) {
         if (other == this) {
             return this;
         }
-        if (this == OF || this == NOF || other == OF || other == NOF) {
-            return null;
-        }
         switch (this) {
             case EQ:
                 if (other == LE || other == GE || other == BE || other == AE) {
@@ -366,9 +432,6 @@
         if (other == this) {
             return this;
         }
-        if (this == OF || this == NOF || other == OF || other == NOF) {
-            return null;
-        }
         switch (this) {
             case EQ:
                 if (other == LE || other == GE || other == BE || other == AE) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -29,7 +30,7 @@
  * The {@code ConditionalNode} class represents a comparison that yields one of two values. Note that these nodes are not
  * built directly from the bytecode but are introduced by canonicalization.
  */
-public class ConditionalNode extends BinaryNode implements Canonicalizable, LIRLowerable {
+public class ConditionalNode extends BinaryNode implements Canonicalizable, LIRLowerable, Negatable {
 
     @Input private BooleanNode condition;
 
@@ -53,6 +54,17 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
+        // this optimizes the case where a value that can only be 0 or 1 is materialized to 0 or 1
+        if (x().isConstant() && y().isConstant() && condition instanceof IntegerEqualsNode) {
+            IntegerEqualsNode equals = (IntegerEqualsNode) condition;
+            if (equals.y().isConstant() && equals.y().asConstant().equals(Constant.INT_0)) {
+                if (equals.x().integerStamp().mask() == 1) {
+                    if (x().asConstant().equals(Constant.INT_0) && y().asConstant().equals(Constant.INT_1)) {
+                        return equals.x();
+                    }
+                }
+            }
+        }
         if (condition instanceof ConstantNode) {
             ConstantNode c = (ConstantNode) condition;
             if (c.asConstant().asBoolean()) {
@@ -72,4 +84,11 @@
     public void generate(LIRGeneratorTool generator) {
         generator.emitConditional(this);
     }
+
+    @Override
+    public Negatable negate() {
+        ConditionalNode replacement = graph().unique(new ConditionalNode(condition, falseValue(), trueValue()));
+        ((StructuredGraph) graph()).replaceFloating(this, replacement);
+        return replacement;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import static com.oracle.max.cri.ci.CiKind.*;
+import static com.oracle.graal.api.meta.Kind.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -55,10 +55,10 @@
         MOV_F2I(Float, Int),
         MOV_D2L(Double, Long);
 
-        public final CiKind from;
-        public final CiKind to;
+        public final Kind from;
+        public final Kind to;
 
-        private Op(CiKind from, CiKind to) {
+        private Op(Kind from, Kind to) {
             this.from = from;
             this.to = to;
         }
@@ -89,7 +89,7 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (value instanceof ConstantNode) {
-            CiConstant c = ((ConstantNode) value).asConstant();
+            Constant c = ((ConstantNode) value).asConstant();
             switch (opcode) {
                 case I2L: return ConstantNode.forLong(c.asInt(), graph());
                 case L2I: return ConstantNode.forInt((int) c.asLong(), graph());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,7 +30,7 @@
 @NodeInfo(shortName = "+")
 public final class FloatAddNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public FloatAddNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+    public FloatAddNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
         super(kind, x, y, isStrictFP);
     }
 
@@ -40,20 +40,20 @@
             return graph().unique(new FloatAddNode(kind(), y(), x(), isStrictFP()));
         }
         if (x().isConstant()) {
-            if (kind() == CiKind.Float) {
+            if (kind() == Kind.Float) {
                 return ConstantNode.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph());
             } else {
-                assert kind() == CiKind.Double;
+                assert kind() == Kind.Double;
                 return ConstantNode.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph());
             }
         } else if (y().isConstant()) {
-            if (kind() == CiKind.Float) {
+            if (kind() == Kind.Float) {
                 float c = y().asConstant().asFloat();
                 if (c == 0.0f) {
                     return x();
                 }
             } else {
-                assert kind() == CiKind.Double;
+                assert kind() == Kind.Double;
                 double c = y().asConstant().asDouble();
                 if (c == 0.0) {
                     return x();
@@ -65,10 +65,10 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        CiValue op1 = gen.operand(x());
-        CiValue op2 = gen.operand(y());
+        Value op1 = gen.operand(x());
+        Value op2 = gen.operand(y());
         if (!y().isConstant() && !livesLonger(this, y(), gen)) {
-            CiValue op = op1;
+            Value op = op1;
             op1 = op2;
             op2 = op;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatArithmeticNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 
 public abstract class FloatArithmeticNode extends ArithmeticNode {
 
-    public FloatArithmeticNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+    public FloatArithmeticNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
         super(kind, x, y, isStrictFP);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,19 +30,19 @@
 @NodeInfo(shortName = "/")
 public final class FloatDivNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public FloatDivNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+    public FloatDivNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
         super(kind, x, y, isStrictFP);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == CiKind.Float) {
+            if (kind() == Kind.Float) {
                 if (y().asConstant().asFloat() != 0) {
                     return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph());
                 }
             } else {
-                assert kind() == CiKind.Double;
+                assert kind() == Kind.Double;
                 if (y().asConstant().asDouble() != 0) {
                     return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph());
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2011, 2011, 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.calc;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+
+@NodeInfo(shortName = "==")
+public final class FloatEqualsNode extends CompareNode {
+
+    /**
+     * Constructs a new floating point equality comparison node.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param y the instruction that produces the second input to this instruction
+     */
+    public FloatEqualsNode(ValueNode x, ValueNode y) {
+        super(x, y);
+        assert x.kind().isFloatOrDouble();
+        assert y.kind().isFloatOrDouble();
+    }
+
+    @Override
+    public Condition condition() {
+        return Condition.EQ;
+    }
+
+    @Override
+    public boolean unorderedIsTrue() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011, 2011, 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.calc;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "<")
+public final class FloatLessThanNode extends CompareNode {
+
+    private final boolean unorderedIsTrue;
+
+    /**
+     * Constructs a new floating point comparison node.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param y the instruction that produces the second input to this instruction
+     * @param unorderedIsTrue whether a comparison that is undecided (involving NaNs, etc.) leads to a "true" result
+     */
+    public FloatLessThanNode(ValueNode x, ValueNode y, boolean unorderedIsTrue) {
+        super(x, y);
+        assert x.kind().isFloatOrDouble();
+        assert y.kind().isFloatOrDouble();
+        this.unorderedIsTrue = unorderedIsTrue;
+    }
+
+    @Override
+    public Condition condition() {
+        return Condition.LT;
+    }
+
+    @Override
+    public boolean unorderedIsTrue() {
+        return unorderedIsTrue;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y() && !unorderedIsTrue()) {
+            return ConstantNode.forBoolean(false, graph());
+        }
+        return super.canonical(tool);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,7 +30,7 @@
 @NodeInfo(shortName = "*")
 public final class FloatMulNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public FloatMulNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+    public FloatMulNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
         super(kind, x, y, isStrictFP);
     }
 
@@ -40,10 +40,10 @@
             return graph().unique(new FloatMulNode(kind(), y(), x(), isStrictFP()));
         }
         if (x().isConstant()) {
-            if (kind() == CiKind.Float) {
+            if (kind() == Kind.Float) {
                 return ConstantNode.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph());
             } else {
-                assert kind() == CiKind.Double;
+                assert kind() == Kind.Double;
                 return ConstantNode.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph());
             }
         }
@@ -52,10 +52,10 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        CiValue op1 = gen.operand(x());
-        CiValue op2 = gen.operand(y());
+        Value op1 = gen.operand(x());
+        Value op2 = gen.operand(y());
         if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
-            CiValue op = op1;
+            Value op = op1;
             op1 = op2;
             op2 = op;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,17 +30,17 @@
 @NodeInfo(shortName = "%")
 public final class FloatRemNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public FloatRemNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+    public FloatRemNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
         super(kind, x, y, isStrictFP);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == CiKind.Float) {
+            if (kind() == Kind.Float) {
                 return ConstantNode.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph());
             } else {
-                assert kind() == CiKind.Double;
+                assert kind() == Kind.Double;
                 return ConstantNode.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph());
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,7 +30,7 @@
 @NodeInfo(shortName = "-")
 public final class FloatSubNode extends FloatArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public FloatSubNode(CiKind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
+    public FloatSubNode(Kind kind, ValueNode x, ValueNode y, boolean isStrictFP) {
         super(kind, x, y, isStrictFP);
     }
 
@@ -40,21 +40,21 @@
             return ConstantNode.forFloatingKind(kind(), 0.0f, graph());
         }
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == CiKind.Float) {
+            if (kind() == Kind.Float) {
                 return ConstantNode.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph());
             } else {
-                assert kind() == CiKind.Double;
+                assert kind() == Kind.Double;
                 return ConstantNode.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph());
             }
         } else if (y().isConstant()) {
-            if (kind() == CiKind.Float) {
+            if (kind() == Kind.Float) {
                 float c = y().asConstant().asFloat();
                 if (c == 0.0f) {
                     return x();
                 }
                 return graph().unique(new FloatAddNode(kind(), x(), ConstantNode.forFloat(-c, graph()), isStrictFP()));
             } else {
-                assert kind() == CiKind.Double;
+                assert kind() == Kind.Double;
                 double c = y().asConstant().asDouble();
                 if (c == 0.0) {
                     return x();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatingNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import java.util.*;
+
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
@@ -32,7 +34,11 @@
         super(stamp);
     }
 
-    public FloatingNode(Stamp stamp, Node... dependencies) {
+    public FloatingNode(Stamp stamp, ValueNode... dependencies) {
+        super(stamp, dependencies);
+    }
+
+    public FloatingNode(Stamp stamp, List<ValueNode> dependencies) {
         super(stamp, dependencies);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,50 +22,64 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.types.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "+")
 public class IntegerAddNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable, TypeFeedbackProvider {
 
-    public IntegerAddNode(CiKind kind, ValueNode x, ValueNode y) {
+    public IntegerAddNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.add(x().integerStamp(), y().integerStamp()));
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
             return graph().unique(new IntegerAddNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph());
             }
         } else if (y().isConstant()) {
-            if (kind() == CiKind.Int) {
-                int c = y().asConstant().asInt();
-                if (c == 0) {
-                    return x();
-                }
-            } else {
-                assert kind() == CiKind.Long;
-                long c = y().asConstant().asLong();
-                if (c == 0) {
-                    return x();
+            long c = y().asConstant().asLong();
+            if (c == 0) {
+                return x();
+            }
+            // canonicalize expressions like "(a + 1) + 2"
+            BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
+            if (reassociated != this) {
+                return reassociated;
+            }
+            if (c < 0) {
+                if (kind() == Kind.Int) {
+                    return IntegerArithmeticNode.sub(x(), ConstantNode.forInt((int) -c, graph()));
+                } else {
+                    assert kind() == Kind.Long;
+                    return IntegerArithmeticNode.sub(x(), ConstantNode.forLong(-c, graph()));
                 }
             }
         }
+        if (x() instanceof NegateNode) {
+            return IntegerArithmeticNode.sub(y(), ((NegateNode) x()).x());
+        }
         return this;
     }
 
     public static boolean isIntegerAddition(ValueNode result, ValueNode a, ValueNode b) {
-        CiKind kind = result.kind();
+        Kind kind = result.kind();
         if (kind != a.kind() || kind != b.kind() || !(kind.isInt() || kind.isLong())) {
             return false;
         }
@@ -84,11 +98,11 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        CiValue op1 = gen.operand(x());
+        Value op1 = gen.operand(x());
         assert op1 != null : x() + ", this=" + this;
-        CiValue op2 = gen.operand(y());
+        Value op2 = gen.operand(y());
         if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
-            CiValue op = op1;
+            Value op = op1;
             op1 = op2;
             op2 = op;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerArithmeticNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,16 +22,16 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
 
 public abstract class IntegerArithmeticNode extends ArithmeticNode {
 
-    public IntegerArithmeticNode(CiKind kind, ValueNode x, ValueNode y) {
+    public IntegerArithmeticNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y, false);
-        assert kind == CiKind.Int || kind == CiKind.Long;
+        assert kind == Kind.Int || kind == Kind.Long;
     }
 
     public static IntegerAddNode add(ValueNode v1, ValueNode v2) {
@@ -39,11 +39,11 @@
         Graph graph = v1.graph();
         switch(v1.kind()) {
             case Int:
-                return graph.unique(new IntegerAddNode(CiKind.Int, v1, v2));
+                return graph.unique(new IntegerAddNode(Kind.Int, v1, v2));
             case Long:
-                return graph.unique(new IntegerAddNode(CiKind.Long, v1, v2));
+                return graph.unique(new IntegerAddNode(Kind.Long, v1, v2));
             default:
-                throw ValueUtil.shouldNotReachHere();
+                throw ValueNodeUtil.shouldNotReachHere();
         }
     }
 
@@ -52,11 +52,37 @@
         Graph graph = v1.graph();
         switch(v1.kind()) {
             case Int:
-                return graph.unique(new IntegerMulNode(CiKind.Int, v1, v2));
+                return graph.unique(new IntegerMulNode(Kind.Int, v1, v2));
+            case Long:
+                return graph.unique(new IntegerMulNode(Kind.Long, v1, v2));
+            default:
+                throw ValueNodeUtil.shouldNotReachHere();
+        }
+    }
+
+    public static IntegerSubNode sub(ValueNode v1, ValueNode v2) {
+        assert v1.kind() == v2.kind() && v1.graph() == v2.graph();
+        Graph graph = v1.graph();
+        switch(v1.kind()) {
+            case Int:
+                return graph.unique(new IntegerSubNode(Kind.Int, v1, v2));
             case Long:
-                return graph.unique(new IntegerMulNode(CiKind.Long, v1, v2));
+                return graph.unique(new IntegerSubNode(Kind.Long, v1, v2));
             default:
-                throw ValueUtil.shouldNotReachHere();
+                throw ValueNodeUtil.shouldNotReachHere();
+        }
+    }
+
+    public static IntegerDivNode div(ValueNode v1, ValueNode v2) {
+        assert v1.kind() == v2.kind() && v1.graph() == v2.graph();
+        Graph graph = v1.graph();
+        switch(v1.kind()) {
+            case Int:
+                return graph.unique(new IntegerDivNode(Kind.Int, v1, v2));
+            case Long:
+                return graph.unique(new IntegerDivNode(Kind.Long, v1, v2));
+            default:
+                throw ValueNodeUtil.shouldNotReachHere();
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011, 2011, 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+@NodeInfo(shortName = "|<|")
+public final class IntegerBelowThanNode extends CompareNode {
+
+    /**
+     * Constructs a new unsigned integer comparison node.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param y the instruction that produces the second input to this instruction
+     */
+    public IntegerBelowThanNode(ValueNode x, ValueNode y) {
+        super(x, y);
+        assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object;
+        assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object;
+    }
+
+    @Override
+    public Condition condition() {
+        return Condition.BT;
+    }
+
+    @Override
+    public boolean unorderedIsTrue() {
+        return false;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forBoolean(false, graph());
+        } else {
+            IntegerStamp xStamp = x().integerStamp();
+            IntegerStamp yStamp = y().integerStamp();
+            if (yStamp.lowerBound() >= 0 && yStamp.upperBound() >= 0) {
+                if (xStamp.lowerBound() >= 0 && xStamp.upperBound() < yStamp.lowerBound()) {
+                    return ConstantNode.forBoolean(true, graph());
+                } else if (xStamp.upperBound() < 0 || xStamp.lowerBound() >= yStamp.upperBound()) {
+                    return ConstantNode.forBoolean(false, graph());
+                }
+            }
+        }
+
+        return super.canonical(tool);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,29 +22,36 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "/")
 public final class IntegerDivNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public IntegerDivNode(CiKind kind, ValueNode x, ValueNode y) {
+    public IntegerDivNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.div(x().integerStamp(), y().integerStamp()));
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
             long yConst = y().asConstant().asLong();
             if (yConst == 0) {
                 return this; // this will trap, can not canonicalize
             }
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() / (int) yConst, graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() / yConst, graph());
             }
         } else if (y().isConstant()) {
@@ -52,6 +59,33 @@
             if (c == 1) {
                 return x();
             }
+            if (c == -1) {
+                return graph().unique(new NegateNode(x()));
+            }
+            long abs = Math.abs(c);
+            if (CodeUtil.isPowerOf2(abs)) {
+                ValueNode dividend = x();
+                IntegerStamp stampX = x().integerStamp();
+                int log2 = CodeUtil.log2(abs);
+                // no rounding if dividend is negative or if its low bits are always 0
+                if (stampX.lowerBound() < 0 || (stampX.mask() & (abs - 1)) != 0) {
+                    int bits;
+                    if (kind().isInt()) {
+                        bits = 32;
+                    } else {
+                        assert kind().isLong();
+                        bits = 64;
+                    }
+                    RightShiftNode sign = graph().unique(new RightShiftNode(kind(), x(), ConstantNode.forInt(bits - 1, graph())));
+                    UnsignedRightShiftNode round = graph().unique(new UnsignedRightShiftNode(kind(), sign, ConstantNode.forInt(bits - log2, graph())));
+                    dividend = IntegerArithmeticNode.add(dividend, round);
+                }
+                RightShiftNode shift = graph().unique(new RightShiftNode(kind(), dividend, ConstantNode.forInt(log2, graph())));
+                if (c < 0) {
+                    return graph().unique(new NegateNode(shift));
+                }
+                return shift;
+            }
         }
         return this;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 2011, 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "==")
+public final class IntegerEqualsNode extends CompareNode {
+
+    /**
+     * Constructs a new integer equality comparison node.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param y the instruction that produces the second input to this instruction
+     */
+    public IntegerEqualsNode(ValueNode x, ValueNode y) {
+        super(x, y);
+        assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object;
+        assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object;
+    }
+
+    @Override
+    public Condition condition() {
+        return Condition.EQ;
+    }
+
+    @Override
+    public boolean unorderedIsTrue() {
+        return false;
+    }
+
+    @Override
+    protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
+        if (constant.kind == Kind.Int && constant.asInt() == 0) {
+            ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x();
+            ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y();
+
+            if (normalizeNode.x().kind().isFloatOrDouble()) {
+                return graph().unique(new FloatEqualsNode(a, b));
+            } else {
+                return graph().unique(new IntegerEqualsNode(a, b));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forBoolean(true, graph());
+        } else if (x().integerStamp().alwaysDistinct(y().integerStamp())) {
+            return ConstantNode.forBoolean(false, graph());
+        }
+        return super.canonical(tool);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011, 2011, 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "<")
+public final class IntegerLessThanNode extends CompareNode {
+
+    /**
+     * Constructs a new integer comparison node.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param y the instruction that produces the second input to this instruction
+     */
+    public IntegerLessThanNode(ValueNode x, ValueNode y) {
+        super(x, y);
+        assert !x.kind().isFloatOrDouble() && x.kind() != Kind.Object;
+        assert !y.kind().isFloatOrDouble() && y.kind() != Kind.Object;
+    }
+
+    @Override
+    public Condition condition() {
+        return Condition.LT;
+    }
+
+    @Override
+    public boolean unorderedIsTrue() {
+        return false;
+    }
+
+    @Override
+    protected ValueNode optimizeNormalizeCmp(Constant constant, NormalizeCompareNode normalizeNode, boolean mirrored) {
+        assert condition() == Condition.LT;
+        if (constant.kind == Kind.Int && constant.asInt() == 0) {
+            ValueNode a = mirrored ? normalizeNode.y() : normalizeNode.x();
+            ValueNode b = mirrored ? normalizeNode.x() : normalizeNode.y();
+
+            if (normalizeNode.x().kind().isFloatOrDouble()) {
+                return graph().unique(new FloatLessThanNode(a, b, mirrored ^ normalizeNode.isUnorderedLess));
+            } else {
+                return graph().unique(new IntegerLessThanNode(a, b));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forBoolean(false, graph());
+        } else if (x().integerStamp().upperBound() < y().integerStamp().lowerBound()) {
+            return ConstantNode.forBoolean(true, graph());
+        } else if (x().integerStamp().lowerBound() >= y().integerStamp().upperBound()) {
+            return ConstantNode.forBoolean(false, graph());
+        }
+        if (x().integerStamp().lowerBound() >= 0 && y().integerStamp().lowerBound() >= 0) {
+            return graph().unique(new IntegerBelowThanNode(x(), y()));
+        }
+        return super.canonical(tool);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,7 +31,7 @@
 @NodeInfo(shortName = "*")
 public final class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public IntegerMulNode(CiKind kind, ValueNode x, ValueNode y) {
+    public IntegerMulNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
@@ -40,10 +41,10 @@
             return graph().unique(new IntegerMulNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph());
             }
         } else if (y().isConstant()) {
@@ -54,19 +55,27 @@
             if (c == 0) {
                 return ConstantNode.defaultForKind(kind(), graph());
             }
-            if (c > 0 && CiUtil.isPowerOf2(c)) {
-                return graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(CiUtil.log2(c), graph())));
+            long abs = Math.abs(c);
+            if (abs > 0 && CodeUtil.isPowerOf2(abs)) {
+                LeftShiftNode shift = graph().unique(new LeftShiftNode(kind(), x(), ConstantNode.forInt(CodeUtil.log2(abs), graph())));
+                if (c < 0) {
+                    return graph().unique(new NegateNode(shift));
+                } else {
+                    return shift;
+                }
             }
+            // canonicalize expressions like "(a * 1) * 2"
+            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
         return this;
     }
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        CiValue op1 = gen.operand(x());
-        CiValue op2 = gen.operand(y());
+        Value op1 = gen.operand(x());
+        Value op2 = gen.operand(y());
         if (!y().isConstant() && !FloatAddNode.livesLonger(this, y(), gen)) {
-            CiValue op = op1;
+            Value op = op1;
             op1 = op2;
             op2 = op;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,7 +31,7 @@
 @NodeInfo(shortName = "%")
 public final class IntegerRemNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public IntegerRemNode(CiKind kind, ValueNode x, ValueNode y) {
+    public IntegerRemNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
@@ -41,16 +42,18 @@
             if (yConst == 0) {
                 return this; // this will trap, can not canonicalize
             }
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() % (int) yConst, graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() % yConst, graph());
             }
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 1 || c == -1) {
                 return ConstantNode.forIntegerKind(kind(), 0, graph());
+            } else if (c > 0 && CodeUtil.isPowerOf2(c) && x().integerStamp().lowerBound() >= 0) {
+                return graph().unique(new AndNode(kind(), x(), ConstantNode.forIntegerKind(kind(), c - 1, graph())));
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,28 +22,34 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "-")
 public final class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
 
-    public IntegerSubNode(CiKind kind, ValueNode x, ValueNode y) {
+    public IntegerSubNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.sub(x().integerStamp(), y().integerStamp()));
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return ConstantNode.forIntegerKind(kind(), 0, graph());
         }
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph());
             }
         } else if (y().isConstant()) {
@@ -51,17 +57,24 @@
             if (c == 0) {
                 return x();
             }
-            if (kind() == CiKind.Int) {
-                return graph().unique(new IntegerAddNode(kind(), x(), ConstantNode.forInt((int) -c, graph())));
-            } else {
-                assert kind() == CiKind.Long;
-                return graph().unique(new IntegerAddNode(kind(), x(), ConstantNode.forLong(-c, graph())));
+            BinaryNode reassociated = BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
+            if (reassociated != this) {
+                return reassociated;
+            }
+            if (c < 0) {
+                if (kind() == Kind.Int) {
+                    return IntegerArithmeticNode.add(x(), ConstantNode.forInt((int) -c, graph()));
+                } else {
+                    assert kind() == Kind.Long;
+                    return IntegerArithmeticNode.add(x(), ConstantNode.forLong(-c, graph()));
+                }
             }
         } else if (x().isConstant()) {
             long c = x().asConstant().asLong();
             if (c == 0) {
                 return graph().unique(new NegateNode(y()));
             }
+           return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
         return this;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009, 2011, 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * An IsNullNode will be true if the supplied value is null, and false if it is non-null.
+ */
+public final class IsNullNode extends BooleanNode implements Canonicalizable, LIRLowerable {
+
+    @Input private ValueNode object;
+
+    public ValueNode object() {
+        return object;
+    }
+
+    /**
+     * Constructs a new IsNullNode instruction.
+     *
+     * @param object the instruction producing the object to check against null
+     */
+    public IsNullNode(ValueNode object) {
+        super(StampFactory.condition());
+        assert object.kind() == Kind.Object : object.kind();
+        this.object = object;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        // Nothing to do.
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(object() != null, "is null input must not be null");
+        assertTrue(object().kind().isObject(), "is null input must be an object");
+        return super.verify();
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        Constant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == Kind.Object;
+            return ConstantNode.forBoolean(constant.isNull(), graph());
+        }
+        if (object.objectStamp().nonNull()) {
+            return ConstantNode.forBoolean(false, graph());
+        }
+        return this;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,36 +22,42 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "<<")
 public final class LeftShiftNode extends ShiftNode implements Canonicalizable, LIRLowerable {
 
-    public LeftShiftNode(CiKind kind, ValueNode x, ValueNode y) {
+    public LeftShiftNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.leftShift(x().integerStamp(), y().integerStamp()));
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (y().isConstant()) {
             int amount = y().asConstant().asInt();
             int originalAmout = amount;
             int mask;
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 mask = 0x1f;
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 mask = 0x3f;
             }
             amount &= mask;
             if (x().isConstant()) {
-                if (kind() == CiKind.Int) {
+                if (kind() == Kind.Int) {
                     return ConstantNode.forInt(x().asConstant().asInt() << amount, graph());
                 } else {
-                    assert kind() == CiKind.Long;
+                    assert kind() == Kind.Long;
                     return ConstantNode.forLong(x().asConstant().asLong() << amount, graph());
                 }
             }
@@ -69,10 +75,10 @@
                         }
                         return graph().unique(new LeftShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
                     } else if ((other instanceof RightShiftNode || other instanceof UnsignedRightShiftNode) && otherAmount == amount) {
-                        if (kind() == CiKind.Long) {
+                        if (kind() == Kind.Long) {
                             return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forLong(-1L << amount, graph())));
                         } else {
-                            assert kind() == CiKind.Int;
+                            assert kind() == Kind.Int;
                             return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forInt(-1 << amount, graph())));
                         }
                     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LogicNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LogicNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -35,7 +36,47 @@
      * @param x the first input into this node
      * @param y the second input into this node
      */
-    public LogicNode(CiKind kind, ValueNode x, ValueNode y) {
+    public LogicNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
+        assert kind == Kind.Int || kind == Kind.Long;
+    }
+
+    public static LogicNode and(ValueNode v1, ValueNode v2) {
+        assert v1.kind() == v2.kind() && v1.graph() == v2.graph();
+        Graph graph = v1.graph();
+        switch(v1.kind()) {
+            case Int:
+                return graph.unique(new AndNode(Kind.Int, v1, v2));
+            case Long:
+                return graph.unique(new AndNode(Kind.Long, v1, v2));
+            default:
+                throw ValueNodeUtil.shouldNotReachHere();
+        }
+    }
+
+    public static LogicNode or(ValueNode v1, ValueNode v2) {
+        assert v1.kind() == v2.kind() && v1.graph() == v2.graph();
+        Graph graph = v1.graph();
+        switch(v1.kind()) {
+            case Int:
+                return graph.unique(new OrNode(Kind.Int, v1, v2));
+            case Long:
+                return graph.unique(new OrNode(Kind.Long, v1, v2));
+            default:
+                throw ValueNodeUtil.shouldNotReachHere();
+        }
+    }
+
+    public static LogicNode xor(ValueNode v1, ValueNode v2) {
+        assert v1.kind() == v2.kind() && v1.graph() == v2.graph();
+        Graph graph = v1.graph();
+        switch(v1.kind()) {
+            case Int:
+                return graph.unique(new XorNode(Kind.Int, v1, v2));
+            case Long:
+                return graph.unique(new XorNode(Kind.Long, v1, v2));
+            default:
+                throw ValueNodeUtil.shouldNotReachHere();
+        }
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -31,20 +31,24 @@
  */
 public final class NegateNode extends FloatingNode implements Canonicalizable, LIRLowerable {
 
-    @Input
-    private ValueNode x;
+    @Input private ValueNode x;
 
     public ValueNode x() {
         return x;
     }
 
+    @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.negate(x().stamp()));
+    }
+
     /**
-     * Creates new NegateOp instance.
+     * Creates new NegateNode instance.
      *
      * @param x the instruction producing the value that is input to this instruction
      */
     public NegateNode(ValueNode x) {
-        super(StampFactory.forKind(x.kind()));
+        super(StampTool.negate(x.stamp()));
         this.x = x;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NormalizeCompareNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,14 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
 /**
- * Returns -1, 0, or 1 if either x < y, x == y, or x > y.
+ * Returns -1, 0, or 1 if either x < y, x == y, or x > y. If the comparison is undecided (one of the inputs is NaN), the
+ * result is 1 if isUnorderedLess is false and -1 if isUnorderedLess is true.
  */
 public final class NormalizeCompareNode extends BinaryNode implements Lowerable {
     public final boolean isUnorderedLess;
@@ -40,7 +41,7 @@
      * @param isUnorderedLess true when an unordered floating point comparison is interpreted as less, false when greater.
      */
     public NormalizeCompareNode(ValueNode x, ValueNode y, boolean isUnorderedLess) {
-        super(CiKind.Int, x, y);
+        super(Kind.Int, x, y);
         this.isUnorderedLess = isUnorderedLess;
     }
 
@@ -48,10 +49,17 @@
     public void lower(CiLoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) graph();
 
-        CompareNode equalComp = graph.unique(new CompareNode(x(), Condition.EQ, false, y()));
+        BooleanNode equalComp;
+        BooleanNode lessComp;
+        if (x().kind().isFloatOrDouble()) {
+            equalComp = graph.unique(new FloatEqualsNode(x(), y()));
+            lessComp = graph.unique(new FloatLessThanNode(x(), y(), isUnorderedLess));
+        } else {
+            equalComp = graph.unique(new IntegerEqualsNode(x(), y()));
+            lessComp = graph.unique(new IntegerLessThanNode(x(), y()));
+        }
+
         MaterializeNode equalValue = MaterializeNode.create(equalComp, graph, ConstantNode.forInt(0, graph), ConstantNode.forInt(1, graph));
-
-        CompareNode lessComp = graph.unique(new CompareNode(x(), Condition.LT, isUnorderedLess, y()));
         MaterializeNode value =  MaterializeNode.create(lessComp, graph, ConstantNode.forInt(-1, graph), equalValue);
 
         graph.replaceFloating(this, value);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NullCheckNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.calc;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.spi.types.*;
-import com.oracle.graal.nodes.type.*;
-
-public final class NullCheckNode extends BooleanNode implements Canonicalizable, LIRLowerable, ConditionalTypeFeedbackProvider, TypeCanonicalizable {
-
-    @Input private ValueNode object;
-    public final boolean expectedNull;
-
-    public ValueNode object() {
-        return object;
-    }
-
-    /**
-     * Constructs a new NullCheck instruction.
-     *
-     * @param object the instruction producing the object to check against null
-     * @param expectedNull True when this node checks that the value is null, false when this node checks for non-null
-     */
-    public NullCheckNode(ValueNode object, boolean expectedNull) {
-        super(StampFactory.illegal());
-        assert object.kind() == CiKind.Object : object.kind();
-        this.object = object;
-        this.expectedNull = expectedNull;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        // Nothing to do.
-    }
-
-    @Override
-    public boolean verify() {
-        assertTrue(object().kind().isObject(), "null check input must be an object");
-        return super.verify();
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        CiConstant constant = object().asConstant();
-        if (constant != null) {
-            assert constant.kind == CiKind.Object;
-            return ConstantNode.forBoolean(constant.isNull() == expectedNull, graph());
-        }
-        if (object.stamp().nonNull()) {
-            return ConstantNode.forBoolean(!expectedNull, graph());
-        }
-        return this;
-    }
-
-    @Override
-    public BooleanNode negate() {
-        return graph().unique(new NullCheckNode(object(), !expectedNull));
-    }
-
-    @Override
-    public void typeFeedback(TypeFeedbackTool tool) {
-        Condition expectedCondition = expectedNull ? Condition.EQ : Condition.NE;
-        tool.addObject(object()).constantBound(expectedCondition, CiConstant.NULL_OBJECT);
-    }
-
-    @Override
-    public Result canonical(TypeFeedbackTool tool) {
-        Condition expectedCondition = expectedNull ? Condition.EQ : Condition.NE;
-        ObjectTypeQuery query = tool.queryObject(object());
-        if (query.constantBound(expectedCondition, CiConstant.NULL_OBJECT)) {
-            return new Result(ConstantNode.forBoolean(true, graph()), query);
-        } else if (query.constantBound(expectedCondition.negate(), CiConstant.NULL_OBJECT)) {
-            return new Result(ConstantNode.forBoolean(false, graph()), query);
-        }
-        return null;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2011, 2011, 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.calc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+@NodeInfo(shortName = "==")
+public final class ObjectEqualsNode extends CompareNode {
+
+    /**
+     * Constructs a new object equality comparison node.
+     *
+     * @param x the instruction producing the first input to the instruction
+     * @param y the instruction that produces the second input to this instruction
+     */
+    public ObjectEqualsNode(ValueNode x, ValueNode y) {
+        super(x, y);
+        assert x.kind() == Kind.Object;
+        assert y.kind() == Kind.Object;
+    }
+
+    @Override
+    public Condition condition() {
+        return Condition.EQ;
+    }
+
+    @Override
+    public boolean unorderedIsTrue() {
+        return false;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (x() == y()) {
+            return ConstantNode.forBoolean(true, graph());
+        }
+
+        if (x().isNullConstant()) {
+            return graph().unique(new IsNullNode(y()));
+        } else if (y().isNullConstant()) {
+            return graph().unique(new IsNullNode(x()));
+        }
+        if (x().stamp().alwaysDistinct(y().stamp())) {
+            return ConstantNode.forBoolean(false, graph());
+        }
+
+        return super.canonical(tool);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,19 +22,25 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "|")
 public final class OrNode extends LogicNode implements Canonicalizable, LIRLowerable {
 
-    public OrNode(CiKind kind, ValueNode x, ValueNode y) {
+    public OrNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.or(x().integerStamp(), y().integerStamp()));
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return x();
@@ -43,14 +49,14 @@
             return graph().unique(new OrNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph());
             }
         } else if (y().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 int c = y().asConstant().asInt();
                 if (c == -1) {
                     return ConstantNode.forInt(-1, graph());
@@ -59,7 +65,7 @@
                     return x();
                 }
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 long c = y().asConstant().asLong();
                 if (c == -1) {
                     return ConstantNode.forLong(-1, graph());
@@ -68,6 +74,7 @@
                     return x();
                 }
             }
+            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,28 +30,31 @@
 @NodeInfo(shortName = ">>")
 public final class RightShiftNode extends ShiftNode implements Canonicalizable, LIRLowerable {
 
-    public RightShiftNode(CiKind kind, ValueNode x, ValueNode y) {
+    public RightShiftNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
+        if (x().integerStamp().lowerBound() >= 0) {
+            return graph().unique(new UnsignedRightShiftNode(kind(), x(), y()));
+        }
         if (y().isConstant()) {
             int amount = y().asConstant().asInt();
             int originalAmout = amount;
             int mask;
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 mask = 0x1f;
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 mask = 0x3f;
             }
             amount &= mask;
             if (x().isConstant()) {
-                if (kind() == CiKind.Int) {
+                if (kind() == Kind.Int) {
                     return ConstantNode.forInt(x().asConstant().asInt() >> amount, graph());
                 } else {
-                    assert kind() == CiKind.Long;
+                    assert kind() == Kind.Long;
                     return ConstantNode.forLong(x().asConstant().asLong() >> amount, graph());
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ShiftNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -35,7 +35,7 @@
      * @param x the first input value
      * @param s the second input value
      */
-    public ShiftNode(CiKind kind, ValueNode x, ValueNode s) {
+    public ShiftNode(Kind kind, ValueNode x, ValueNode s) {
         super(kind, x, s);
         // TODO (cwimmer) Why check for null here - what is a shift with no left operand?
         assert x == null || x.kind() == kind;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,36 +22,42 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = ">>>")
 public final class UnsignedRightShiftNode extends ShiftNode implements Canonicalizable, LIRLowerable {
 
-    public UnsignedRightShiftNode(CiKind kind, ValueNode x, ValueNode y) {
+    public UnsignedRightShiftNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
     @Override
+    public boolean inferStamp() {
+        return updateStamp(StampTool.unsignedRightShift(x().integerStamp(), y().integerStamp()));
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (y().isConstant()) {
             int amount = y().asConstant().asInt();
             int originalAmout = amount;
             int mask;
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 mask = 0x1f;
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 mask = 0x3f;
             }
             amount &= mask;
             if (x().isConstant()) {
-                if (kind() == CiKind.Int) {
+                if (kind() == Kind.Int) {
                     return ConstantNode.forInt(x().asConstant().asInt() >>> amount, graph());
                 } else {
-                    assert kind() == CiKind.Long;
+                    assert kind() == Kind.Long;
                     return ConstantNode.forLong(x().asConstant().asLong() >>> amount, graph());
                 }
             }
@@ -69,10 +75,10 @@
                         }
                         return graph().unique(new UnsignedRightShiftNode(kind(), other.x(), ConstantNode.forInt(total, graph())));
                     } else if (other instanceof LeftShiftNode && otherAmount == amount) {
-                        if (kind() == CiKind.Long) {
+                        if (kind() == Kind.Long) {
                             return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forLong(-1L >>> amount, graph())));
                         } else {
-                            assert kind() == CiKind.Int;
+                            assert kind() == Kind.Int;
                             return graph().unique(new AndNode(kind(), other.x(), ConstantNode.forInt(-1 >>> amount, graph())));
                         }
                     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -30,7 +30,7 @@
 @NodeInfo(shortName = "^")
 public final class XorNode extends LogicNode implements Canonicalizable, LIRLowerable {
 
-    public XorNode(CiKind kind, ValueNode x, ValueNode y) {
+    public XorNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
     }
 
@@ -43,25 +43,26 @@
             return graph().unique(new XorNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 return ConstantNode.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph());
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 return ConstantNode.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph());
             }
         } else if (y().isConstant()) {
-            if (kind() == CiKind.Int) {
+            if (kind() == Kind.Int) {
                 int c = y().asConstant().asInt();
                 if (c == 0) {
                     return x();
                 }
             } else {
-                assert kind() == CiKind.Long;
+                assert kind() == Kind.Long;
                 long c = y().asConstant().asLong();
                 if (c == 0) {
                     return x();
                 }
             }
+            return BinaryNode.reassociate(this, ValueNode.isConstantPredicate());
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractCallNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractCallNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,7 +26,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
-public abstract class AbstractCallNode extends AbstractStateSplit implements MemoryCheckpoint {
+public abstract class AbstractCallNode extends AbstractStateSplit implements StateSplit, MemoryCheckpoint {
 
     @Input
     protected final NodeInputList<ValueNode> arguments;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,10 +25,9 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
-public abstract class AccessNode extends AbstractStateSplit implements Access {
+public abstract class AccessNode extends FixedWithNextNode implements Access {
 
     @Input private ValueNode object;
-    @Input private GuardNode guard;
     @Input private LocationNode location;
     private boolean nullCheck;
 
@@ -36,15 +35,6 @@
         return object;
     }
 
-    public GuardNode guard() {
-        return guard;
-    }
-
-    public void setGuard(GuardNode x) {
-        updateUsages(guard, x);
-        guard = x;
-    }
-
     public LocationNode location() {
         return location;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,27 +22,26 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.java.MethodCallTargetNode.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.type.*;
 
 
-public final class BoxNode extends AbstractStateSplit implements Node.IterableNodeType {
+public final class BoxNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType {
 
     @Input private ValueNode source;
     private int bci;
-    private CiKind sourceKind;
+    private Kind sourceKind;
 
-    public BoxNode(ValueNode value, RiResolvedType type, CiKind sourceKind, int bci) {
+    public BoxNode(ValueNode value, ResolvedJavaType type, Kind sourceKind, int bci) {
         super(StampFactory.exactNonNull(type));
         this.source = value;
         this.bci = bci;
         this.sourceKind = sourceKind;
-        assert value.kind() != CiKind.Object : "can only box from primitive type";
+        assert value.kind() != Kind.Object : "can only box from primitive type";
     }
 
     public ValueNode source() {
@@ -50,12 +49,12 @@
     }
 
 
-    public CiKind getSourceKind() {
+    public Kind getSourceKind() {
         return sourceKind;
     }
 
     public void expand(BoxingMethodPool pool) {
-        RiResolvedMethod boxingMethod = pool.getBoxingMethod(sourceKind);
+        ResolvedJavaMethod boxingMethod = pool.getBoxingMethod(sourceKind);
         MethodCallTargetNode callTarget = graph().add(new MethodCallTargetNode(InvokeKind.Static, boxingMethod, new ValueNode[]{source}, boxingMethod.signature().returnType(boxingMethod.holder())));
         InvokeNode invokeNode = graph().add(new InvokeNode(callTarget, bci, -1));
         invokeNode.setProbability(this.probability());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,32 +24,32 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 
 public class BoxingMethodPool {
 
-    private final Set<RiMethod> specialMethods = new HashSet<>();
-    private final RiRuntime runtime;
-    private final RiResolvedMethod[] boxingMethods = new RiResolvedMethod[CiKind.values().length];
-    private final RiResolvedMethod[] unboxingMethods = new RiResolvedMethod[CiKind.values().length];
-    private final RiResolvedField[] boxFields = new RiResolvedField[CiKind.values().length];
+    private final Set<JavaMethod> specialMethods = new HashSet<>();
+    private final CodeCacheProvider runtime;
+    private final ResolvedJavaMethod[] boxingMethods = new ResolvedJavaMethod[Kind.values().length];
+    private final ResolvedJavaMethod[] unboxingMethods = new ResolvedJavaMethod[Kind.values().length];
+    private final ResolvedJavaField[] boxFields = new ResolvedJavaField[Kind.values().length];
 
-    public BoxingMethodPool(RiRuntime runtime) {
+    public BoxingMethodPool(CodeCacheProvider runtime) {
         this.runtime = runtime;
         initialize();
     }
 
     private void initialize() {
         try {
-            initialize(CiKind.Boolean, Boolean.class, "booleanValue");
-            initialize(CiKind.Byte, Byte.class, "byteValue");
-            initialize(CiKind.Char, Character.class, "charValue");
-            initialize(CiKind.Short, Short.class, "shortValue");
-            initialize(CiKind.Int, Integer.class, "intValue");
-            initialize(CiKind.Long, Long.class, "longValue");
-            initialize(CiKind.Float, Float.class, "floatValue");
-            initialize(CiKind.Double, Double.class, "doubleValue");
+            initialize(Kind.Boolean, Boolean.class, "booleanValue");
+            initialize(Kind.Byte, Byte.class, "byteValue");
+            initialize(Kind.Char, Character.class, "charValue");
+            initialize(Kind.Short, Short.class, "shortValue");
+            initialize(Kind.Int, Integer.class, "intValue");
+            initialize(Kind.Long, Long.class, "longValue");
+            initialize(Kind.Float, Float.class, "floatValue");
+            initialize(Kind.Double, Double.class, "doubleValue");
         } catch (SecurityException e) {
             throw new RuntimeException(e);
         } catch (NoSuchMethodException e) {
@@ -57,46 +57,46 @@
         }
     }
 
-    private void initialize(CiKind kind, Class<?> type, String unboxMethod) throws SecurityException, NoSuchMethodException {
+    private void initialize(Kind kind, Class<?> type, String unboxMethod) throws SecurityException, NoSuchMethodException {
 
         // Get boxing method from runtime.
-        RiResolvedMethod boxingMethod = runtime.getRiMethod(type.getDeclaredMethod("valueOf", kind.toJavaClass()));
+        ResolvedJavaMethod boxingMethod = runtime.getResolvedJavaMethod(type.getDeclaredMethod("valueOf", kind.toJavaClass()));
         specialMethods.add(boxingMethod);
         boxingMethods[kind.ordinal()] = boxingMethod;
 
         // Get unboxing method from runtime.
-        RiResolvedMethod unboxingMethod = runtime.getRiMethod(type.getDeclaredMethod(unboxMethod));
+        ResolvedJavaMethod unboxingMethod = runtime.getResolvedJavaMethod(type.getDeclaredMethod(unboxMethod));
         unboxingMethods[kind.ordinal()] = unboxingMethod;
         specialMethods.add(unboxingMethod);
 
         // Get the field that contains the boxed value.
-        RiResolvedField[] fields = runtime.getType(type).declaredFields();
-        RiResolvedField boxField = fields[0];
-        assert fields.length == 1 && boxField.kind(false) == kind;
+        ResolvedJavaField[] fields = runtime.getResolvedJavaType(type).declaredFields();
+        ResolvedJavaField boxField = fields[0];
+        assert fields.length == 1 && boxField.kind() == kind;
         boxFields[kind.ordinal()] = boxField;
     }
 
-    public boolean isSpecialMethod(RiResolvedMethod method) {
+    public boolean isSpecialMethod(ResolvedJavaMethod method) {
         return specialMethods.contains(method);
     }
 
-    public boolean isBoxingMethod(RiResolvedMethod method) {
-        return isSpecialMethod(method) && method.signature().returnKind(false) == CiKind.Object;
+    public boolean isBoxingMethod(ResolvedJavaMethod method) {
+        return isSpecialMethod(method) && method.signature().returnKind() == Kind.Object;
     }
 
-    public boolean isUnboxingMethod(RiResolvedMethod method) {
-        return isSpecialMethod(method) && method.signature().returnKind(false) != CiKind.Object;
+    public boolean isUnboxingMethod(ResolvedJavaMethod method) {
+        return isSpecialMethod(method) && method.signature().returnKind() != Kind.Object;
     }
 
-    public RiResolvedMethod getBoxingMethod(CiKind kind) {
+    public ResolvedJavaMethod getBoxingMethod(Kind kind) {
         return boxingMethods[kind.ordinal()];
     }
 
-    public RiResolvedMethod getUnboxingMethod(CiKind kind) {
+    public ResolvedJavaMethod getUnboxingMethod(Kind kind) {
         return unboxingMethods[kind.ordinal()];
     }
 
-    public RiResolvedField getBoxField(CiKind kind) {
+    public ResolvedJavaField getBoxField(Kind kind) {
         return boxFields[kind.ordinal()];
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.graph.*;
+import java.util.*;
+
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.type.*;
@@ -30,7 +31,6 @@
 public abstract class FloatingAccessNode extends FloatingNode implements Access {
 
     @Input private ValueNode object;
-    @Input private GuardNode guard;
     @Input private LocationNode location;
     private boolean nullCheck;
 
@@ -38,15 +38,6 @@
         return object;
     }
 
-    public GuardNode guard() {
-        return guard;
-    }
-
-    public void setGuard(GuardNode x) {
-        updateUsages(guard, x);
-        guard = x;
-    }
-
     public LocationNode location() {
         return location;
     }
@@ -59,17 +50,21 @@
         this.nullCheck = check;
     }
 
-    public FloatingAccessNode(ValueNode object, GuardNode guard, LocationNode location, Stamp stamp) {
+    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp) {
         super(stamp);
         this.object = object;
-        this.guard = guard;
         this.location = location;
     }
 
-    public FloatingAccessNode(ValueNode object, GuardNode guard, LocationNode location, Stamp stamp, Node... dependencies) {
+    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, ValueNode... dependencies) {
         super(stamp, dependencies);
         this.object = object;
-        this.guard = guard;
+        this.location = location;
+    }
+
+    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, List<ValueNode> dependencies) {
+        super(stamp, dependencies);
+        this.object = object;
         this.location = location;
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,18 +22,35 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-
+/**
+ * A floating read of a value from memory specified in terms of an object base and an object relative location.
+ * This node does not null check the object.
+ */
 public final class FloatingReadNode extends FloatingAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable {
 
-    public FloatingReadNode(ValueNode object, GuardNode guard, LocationNode location, Stamp stamp, Node... dependencies) {
-        super(object, guard, location, stamp, dependencies);
+    @Input private Node lastLocationAccess;
+
+    public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, ValueNode... dependencies) {
+        super(object, location, stamp, dependencies);
+        this.lastLocationAccess = lastLocationAccess;
+    }
+
+    public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, List<ValueNode> dependencies) {
+        super(object, location, stamp, dependencies);
+        this.lastLocationAccess = lastLocationAccess;
+    }
+
+    public Node lastLocationAccess() {
+        return lastLocationAccess;
     }
 
     @Override
@@ -43,15 +60,15 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (object() != null && object().isConstant() && object().kind() == CiKind.Object) {
+        CodeCacheProvider runtime = tool.runtime();
+        if (runtime != null && object() != null && object().isConstant() && object().kind() == Kind.Object) {
             if (this.location() == LocationNode.FINAL_LOCATION && location().getClass() == LocationNode.class) {
                 Object value = object().asConstant().asObject();
                 long displacement = location().displacement();
-                CiKind kind = location().kind();
-                RiRuntime runtime = tool.runtime();
-                CiConstant constant = kind.readUnsafeConstant(value, displacement);
+                Kind kind = location().kind();
+                Constant constant = kind.readUnsafeConstant(value, displacement);
                 if (constant != null) {
-                    return ConstantNode.forCiConstant(constant, runtime, graph());
+                    return ConstantNode.forConstant(constant, runtime, graph());
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,20 +22,30 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
+/**
+ * Extension of a {@linkplain LocationNode location} to include a scaled index or an additional offset.
+ */
 public final class IndexedLocationNode extends LocationNode implements LIRLowerable, Canonicalizable {
+
+    /**
+     * An offset or index depending on whether {@link #indexScalingEnabled} is true or false respectively.
+     */
     @Input private ValueNode index;
-    private boolean indexScalingEnabled;
+    private final boolean indexScalingEnabled;
 
+    /**
+     * Gets the index or offset of this location.
+     */
     public ValueNode index() {
         return index;
     }
 
-    public static Object getArrayLocation(CiKind elementKind) {
+    public static Object getArrayLocation(Kind elementKind) {
         return elementKind;
     }
 
@@ -46,22 +56,11 @@
         return indexScalingEnabled;
     }
 
-    /**
-     * Enables or disables scaling of the index by the value kind's size. Has no effect if the index input is not used.
-     */
-    public void setIndexScalingEnabled(boolean enable) {
-        this.indexScalingEnabled = enable;
-    }
-
-    public static IndexedLocationNode create(Object identity, CiKind kind, int displacement, ValueNode index, Graph graph) {
-        return create(identity, kind, displacement, index, graph, true);
-    }
-
-    public static IndexedLocationNode create(Object identity, CiKind kind, int displacement, ValueNode index, Graph graph, boolean indexScalingEnabled) {
+    public static IndexedLocationNode create(Object identity, Kind kind, int displacement, ValueNode index, Graph graph, boolean indexScalingEnabled) {
         return graph.unique(new IndexedLocationNode(identity, kind, index, displacement, indexScalingEnabled));
     }
 
-    private IndexedLocationNode(Object identity, CiKind kind, ValueNode index, int displacement, boolean indexScalingEnabled) {
+    private IndexedLocationNode(Object identity, Kind kind, ValueNode index, int displacement, boolean indexScalingEnabled) {
         super(identity, kind, displacement);
         this.index = index;
         this.indexScalingEnabled = indexScalingEnabled;
@@ -69,10 +68,13 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        CiConstant constantIndex = index.asConstant();
-        if (constantIndex != null && constantIndex.kind.stackKind().isInt()) {
-            long constantIndexLong = constantIndex.asInt();
-            if (indexScalingEnabled && tool.target() != null) {
+        Constant constantIndex = index.asConstant();
+        if (constantIndex != null) {
+            long constantIndexLong = constantIndex.asLong();
+            if (indexScalingEnabled) {
+                if (tool.target() == null) {
+                    return this;
+                }
                 constantIndexLong *= tool.target().sizeInBytes(getValueKind());
             }
             constantIndexLong += displacement();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2009, 2011, 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.extended;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+
+/**
+ * The {@code IntegerSwitchNode} represents a switch on integer keys, with a sorted array of key values.
+ * The actual implementation of the switch will be decided by the backend.
+ */
+public final class IntegerSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable {
+
+    private final int[] keys;
+
+    /**
+     * Constructs a integer switch instruction. The keyProbabilities and keySuccessors array contain key.length + 1
+     * entries, the last entry describes the default (fall through) case.
+     *
+     * @param value the instruction producing the value being switched on
+     * @param successors the list of successors
+     * @param keys the sorted list of keys
+     * @param keyProbabilities the probabilities of the keys
+     * @param keySuccessor the successor index for each key
+     */
+    public IntegerSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
+        super(value, successors, successorProbabilites(successors.length, keySuccessors, keyProbabilities), keySuccessors, keyProbabilities);
+        assert keySuccessors.length == keys.length + 1;
+        assert keySuccessors.length == keyProbabilities.length;
+        this.keys = keys;
+    }
+
+    /**
+     * Constructs a integer switch instruction. The keyProbabilities and keySuccessors array contain key.length + 1
+     * entries, the last entry describes the default (fall through) case.
+     *
+     * @param value the instruction producing the value being switched on
+     * @param successorCount the number of successors
+     * @param keys the sorted list of keys
+     * @param keyProbabilities the probabilities of the keys
+     * @param keySuccessor the successor index for each key
+     */
+    public IntegerSwitchNode(ValueNode value, int successorCount, int[] keys, double[] keyProbabilities, int[] keySuccessors) {
+        this(value, new BeginNode[successorCount], keys, keyProbabilities, keySuccessors);
+    }
+
+    /**
+     * Gets the key at the specified index.
+     * @param i the index
+     * @return the key at that index
+     */
+    @Override
+    public Constant keyAt(int i) {
+        return Constant.forInt(keys[i]);
+    }
+
+    @Override
+    public int keyCount() {
+        return keys.length;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitSwitch(this);
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (value() instanceof ConstantNode) {
+            int constant = value().asConstant().asInt();
+
+            int survivingEdge = keySuccessorIndex(keyCount());
+            for (int i = 0; i < keyCount(); i++) {
+                if (keys[i] == constant) {
+                    survivingEdge = keySuccessorIndex(i);
+                }
+            }
+            for (int i = 0; i < blockSuccessorCount(); i++) {
+                if (i != survivingEdge) {
+                    tool.deleteBranch(blockSuccessor(i));
+                }
+            }
+            tool.addToWorkList(blockSuccessor(survivingEdge));
+            ((StructuredGraph) graph()).removeSplitPropagate(this, survivingEdge);
+        }
+        if (value() != null) {
+            IntegerStamp stamp = value().integerStamp();
+            if (!stamp.isUnrestricted()) {
+                int validKeys = 0;
+                for (int i = 0; i < keyCount(); i++) {
+                    if (stamp.contains(keys[i])) {
+                        validKeys++;
+                    }
+                }
+                if (validKeys == 0) {
+                    tool.addToWorkList(defaultSuccessor());
+                    ((StructuredGraph) graph()).removeSplitPropagate(this, defaultSuccessorIndex());
+                } else if (validKeys != keys.length) {
+                    ArrayList<BeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
+                    int[] newKeys = new int[validKeys];
+                    int[] newKeySuccessors = new int [validKeys + 1];
+                    double[] newKeyProbabilities = new double[validKeys + 1];
+                    double totalProbability = 0;
+                    int current = 0;
+                    for (int i = 0; i < keyCount() + 1; i++) {
+                        if (i == keyCount() || stamp.contains(keys[i])) {
+                            int index = newSuccessors.indexOf(keySuccessor(i));
+                            if (index == -1) {
+                                index = newSuccessors.size();
+                                newSuccessors.add(keySuccessor(i));
+                            }
+                            newKeySuccessors[current] = index;
+                            if (i < keyCount()) {
+                                newKeys[current] = keys[i];
+                            }
+                            newKeyProbabilities[current] = keyProbability(i);
+                            totalProbability += keyProbability(i);
+                            current++;
+                        }
+                    }
+                    if (totalProbability > 0) {
+                        for (int i = 0; i < current; i++) {
+                            newKeyProbabilities[i] /= totalProbability;
+                        }
+                    }
+
+                    for (int i = 0; i < blockSuccessorCount(); i++) {
+                        BeginNode successor = blockSuccessor(i);
+                        if (!newSuccessors.contains(successor)) {
+                            tool.deleteBranch(successor);
+                        }
+                        setBlockSuccessor(i, null);
+                    }
+
+                    BeginNode[] successorsArray = newSuccessors.toArray(new BeginNode[newSuccessors.size()]);
+                    IntegerSwitchNode newSwitch = graph().add(new IntegerSwitchNode(value(), successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
+                    ((FixedWithNextNode) predecessor()).setNext(newSwitch);
+                    GraphUtil.killWithUnusedFloatingInputs(this);
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,17 +22,21 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ValueNumberable;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
+/**
+ * A location for a memory access in terms of the kind of value accessed and the displacement
+ * (in bytes) from a base object or address.
+ */
 public class LocationNode extends FloatingNode implements LIRLowerable, ValueNumberable {
 
     private int displacement;
-    private CiKind valueKind;
+    private Kind valueKind;
     private Object locationIdentity;
 
     public static final Object ANY_LOCATION = new Object() {
@@ -48,7 +52,7 @@
         }
     };
 
-    public static Object getArrayLocation(CiKind elementKind) {
+    public static Object getArrayLocation(Kind elementKind) {
         return elementKind;
     }
 
@@ -56,19 +60,19 @@
         return displacement;
     }
 
-    public static LocationNode create(Object identity, CiKind kind, int displacement, Graph graph) {
+    public static LocationNode create(Object identity, Kind kind, int displacement, Graph graph) {
         return graph.unique(new LocationNode(identity, kind, displacement));
     }
 
-    protected LocationNode(Object identity, CiKind kind, int displacement) {
-        super(StampFactory.illegal());
-        assert kind != CiKind.Illegal && kind != CiKind.Void;
+    protected LocationNode(Object identity, Kind kind, int displacement) {
+        super(StampFactory.extension());
+        assert kind != Kind.Illegal && kind != Kind.Void;
         this.displacement = displacement;
         this.valueKind = kind;
         this.locationIdentity = identity;
     }
 
-    public CiKind getValueKind() {
+    public Kind getValueKind() {
         return valueKind;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LookupSwitchNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.extended;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * The {@code LookupSwitchNode} represents a lookup switch bytecode, which has a sorted
- * array of key values.
- */
-public final class LookupSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable {
-
-    private final int[] keys;
-
-    /**
-     * Constructs a new LookupSwitch instruction.
-     * @param value the instruction producing the value being switched on
-     * @param successors the list of successors
-     * @param keys the list of keys, sorted
-     */
-    public LookupSwitchNode(ValueNode value, BeginNode[] successors, int[] keys, double[] probability) {
-        super(value, successors, probability);
-        assert successors.length == keys.length + 1;
-        this.keys = keys;
-    }
-
-    public LookupSwitchNode(ValueNode value, int[] keys, double[] switchProbability) {
-        this(value, new BeginNode[switchProbability.length], keys, switchProbability);
-    }
-
-    /**
-     * Gets the key at the specified index.
-     * @param i the index
-     * @return the key at that index
-     */
-    public int keyAt(int i) {
-        return keys[i];
-    }
-
-    public int keysLength() {
-        return keys.length;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        gen.emitLookupSwitch(this);
-    }
-
-    @Override
-    public void simplify(SimplifierTool tool) {
-        if (value() instanceof ConstantNode) {
-            ConstantNode constant = (ConstantNode) value();
-            int value = constant.value.asInt();
-
-            BeginNode remainingSux = (BeginNode) defaultSuccessor();
-            int remainingSuxIndex = blockSuccessorCount() - 1;
-            for (int i = 0; i < keys.length; i++) {
-                if (value == keys[i]) {
-                    remainingSux = blockSuccessor(i);
-                    remainingSuxIndex = i;
-                    break;
-                }
-            }
-
-            for (int i = 0; i < blockSuccessorCount(); i++) {
-                BeginNode sux = blockSuccessor(i);
-                if (sux != remainingSux) {
-                    tool.deleteBranch(sux);
-                }
-            }
-
-            tool.addToWorkList(remainingSux);
-            ((StructuredGraph) graph()).removeSplit(this, remainingSuxIndex);
-        }
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -30,7 +30,7 @@
 /**
  * Creates a memory barrier.
  */
-public class MembarNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+public class MembarNode extends AbstractStateSplit implements StateSplit, LIRLowerable, MemoryCheckpoint {
 
     private final int barriers;
 
@@ -38,7 +38,7 @@
      * @param barriers a mask of the barrier constants defined in {@link MemoryBarriers}
      */
     public MembarNode(int barriers) {
-        super(StampFactory.illegal());
+        super(StampFactory.forVoid());
         this.barriers = barriers;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadHubNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadHubNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,16 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 // TODO (chaeubl) this should be a FloatingNode but Lowering is not possible in that case
-public final class ReadHubNode extends FixedWithNextNode implements Lowerable {
+public final class ReadHubNode extends FixedWithNextNode implements Lowerable, Canonicalizable {
     @Input private ValueNode object;
 
     public ValueNode object() {
@@ -44,4 +47,29 @@
     public void lower(CiLoweringTool tool) {
         tool.getRuntime().lower(this, tool);
     }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        CodeCacheProvider runtime = tool.runtime();
+        if (runtime != null) {
+            ObjectStamp stamp = object.objectStamp();
+
+            ResolvedJavaType exactType;
+            if (stamp.isExactType()) {
+                exactType = stamp.type();
+            } else if (stamp.type() != null && tool.assumptions() != null) {
+                exactType = stamp.type().uniqueConcreteSubtype();
+                if (exactType != null) {
+                    tool.assumptions().recordConcreteSubtype(stamp.type(), exactType);
+                }
+            } else {
+                exactType = null;
+            }
+
+            if (exactType != null) {
+                return ConstantNode.forConstant(exactType.getEncoding(Representation.ObjectHub), runtime, graph());
+            }
+        }
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -43,15 +43,15 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (object() != null && object().isConstant() && object().kind() == CiKind.Object) {
+        CodeCacheProvider runtime = tool.runtime();
+        if (runtime != null && object() != null && object().isConstant() && object().kind() == Kind.Object) {
             if (location() == LocationNode.FINAL_LOCATION && location().getClass() == LocationNode.class) {
                 Object value = object().asConstant().asObject();
                 long displacement = location().displacement();
-                CiKind kind = location().kind();
-                RiRuntime runtime = tool.runtime();
-                CiConstant constant = kind.readUnsafeConstant(value, displacement);
+                Kind kind = location().kind();
+                Constant constant = kind.readUnsafeConstant(value, displacement);
                 if (constant != null) {
-                    return ConstantNode.forCiConstant(constant, runtime, graph());
+                    return ConstantNode.forConstant(constant, runtime, graph());
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/RuntimeCallNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,30 +22,31 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public final class RuntimeCallNode extends AbstractCallNode implements LIRLowerable {
 
-    private final CiRuntimeCall call;
+    private final RuntimeCall call;
 
-    public CiRuntimeCall call() {
+    public RuntimeCall call() {
         return call;
     }
 
-    public RuntimeCallNode(CiRuntimeCall call) {
+    public RuntimeCallNode(RuntimeCall call) {
         this(call, new ValueNode[0]);
     }
 
-    public RuntimeCallNode(CiRuntimeCall call, ValueNode arg1) {
-        this(call, new ValueNode[] {arg1});
+    public RuntimeCallNode(RuntimeCall call, ValueNode... arguments) {
+        super(StampFactory.forKind(call.resultKind), arguments);
+        this.call = call;
     }
 
-    public RuntimeCallNode(CiRuntimeCall call, ValueNode[] arguments) {
-        super(StampFactory.forKind(call.resultKind), arguments);
-        this.call = call;
+    @Override
+    public boolean hasSideEffect() {
+        return call.hasSideEffect();
     }
 
     @Override
@@ -53,16 +54,24 @@
         gen.emitRuntimeCall(this);
     }
 
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(verbosity) + "#" + call;
+        }
+        return super.toString(verbosity);
+    }
+
     // specialized on return type (instead of public static <T> T performCall) until boxing/unboxing is sorted out in intrinsification
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static <S> double performCall(@ConstantNodeParameter CiRuntimeCall call, S arg1) {
+    public static <S> double callDouble(@ConstantNodeParameter RuntimeCall call, S arg1) {
         throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static long performCall(@ConstantNodeParameter CiRuntimeCall call) {
+    public static long callLong(@ConstantNodeParameter RuntimeCall call) {
         throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeAccessNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeAccessNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,8 +25,11 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
-
-public abstract class SafeAccessNode extends AbstractStateSplit {
+/**
+ * An analog to {@link AccessNode} with the additional semantics of null-checking
+ * the receiver object before the access.
+ */
+public abstract class SafeAccessNode extends FixedWithNextNode {
 
     @Input private ValueNode object;
     @Input private LocationNode location;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,11 +24,8 @@
 
 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.graal.nodes.type.*;
-import com.oracle.max.cri.ri.*;
-
 
 public class SafeReadNode extends SafeAccessNode implements Lowerable {
 
@@ -40,9 +37,9 @@
     @Override
     public void lower(CiLoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) graph();
-        GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID);
+        ValueNode guard = tool.createNullCheckGuard(object(), leafGraphId());
         ReadNode read = graph.add(new ReadNode(object(), location(), stamp()));
-        read.setGuard(guard);
+        read.dependencies().add(guard);
 
         graph.replaceFixedWithFixed(this, read);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,19 +24,30 @@
 
 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.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ri.*;
 
-
-public class SafeWriteNode extends SafeAccessNode implements Lowerable{
+public class SafeWriteNode extends SafeAccessNode implements StateSplit, Lowerable {
 
     @Input private ValueNode value;
+    @Input(notDataflow = true) private FrameState stateAfter;
+
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return true;
+    }
 
     public SafeWriteNode(ValueNode object, ValueNode value, LocationNode location, long leafGraphId) {
-        super(object, location, StampFactory.forKind(CiKind.Void), leafGraphId);
+        super(object, location, StampFactory.forVoid(), leafGraphId);
         this.value = value;
     }
 
@@ -47,9 +58,9 @@
     @Override
     public void lower(CiLoweringTool tool) {
         StructuredGraph graph = (StructuredGraph) graph();
-        GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID);
+        ValueNode guard = tool.createNullCheckGuard(object(), leafGraphId());
         WriteNode write = graph.add(new WriteNode(object(), value(), location()));
-        write.setGuard(guard);
+        write.dependencies().add(guard);
         graph.replaceFixedWithFixed(this, write);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -31,6 +33,8 @@
 public abstract class SwitchNode extends ControlSplitNode {
 
     @Input private ValueNode value;
+    private final double[] keyProbabilities;
+    private final int[] keySuccessors;
 
     public ValueNode value() {
         return value;
@@ -42,16 +46,72 @@
      * @param successors the list of successors of this switch
      * @param stateAfter the state after the switch
      */
-    public SwitchNode(ValueNode value, BeginNode[] successors, double[] probability) {
-        super(StampFactory.illegal(), successors, probability);
+    public SwitchNode(ValueNode value, BeginNode[] successors, double[] successorProbabilities, int[] keySuccessors, double[] keyProbabilities) {
+        super(StampFactory.forVoid(), successors, successorProbabilities);
+        assert keySuccessors.length == keyProbabilities.length;
         this.value = value;
+        this.keySuccessors = keySuccessors;
+        this.keyProbabilities = keyProbabilities;
+    }
+
+    /**
+     * The number of distinct keys in this switch.
+     */
+    public abstract int keyCount();
+
+    /**
+     * The key at the specified position, encoded in a Constant.
+     */
+    public abstract Constant keyAt(int i);
+
+    /**
+     * Returns the index of the successor belonging to the key at the specified index.
+     */
+    public int keySuccessorIndex(int i) {
+        return keySuccessors[i];
+    }
+
+    /**
+     * Returns the successor for the key at the given index.
+     */
+    public BeginNode keySuccessor(int i) {
+        return blockSuccessor(keySuccessors[i]);
     }
 
     /**
-     * Gets the number of cases that this switch covers (excluding the default case).
-     * @return the number of cases
+     * Returns the probability of the key at the given index.
+     */
+    public double keyProbability(int i) {
+        return keyProbabilities[i];
+    }
+
+    /**
+     * Returns the index of the default (fall through) successor of this switch.
+     */
+    public int defaultSuccessorIndex() {
+        return keySuccessors[keySuccessors.length - 1];
+    }
+
+    /**
+     * Gets the successor corresponding to the default (fall through) case.
+     * @return the default successor
      */
-    public int numberOfCases() {
-        return blockSuccessorCount() - 1;
+    public BeginNode defaultSuccessor() {
+        if (defaultSuccessorIndex() == -1) {
+            throw new GraalInternalError("unexpected");
+        }
+        return defaultSuccessorIndex() == -1 ? null : blockSuccessor(defaultSuccessorIndex());
+    }
+
+    /**
+     * Helper function that sums up the probabilities of all keys that lead to a specific successor.
+     * @return an array of size successorCount with the accumulated probability for each successor.
+     */
+    public static double[] successorProbabilites(int successorCount, int[] keySuccessors, double[] keyProbabilities) {
+        double[] probability = new double[successorCount];
+        for (int i = 0; i < keySuccessors.length; i++) {
+            probability[keySuccessors[i]] += keyProbabilities[i];
+        }
+        return probability;
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/TableSwitchNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.extended;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * The {@code TableSwitchNode} represents a table switch.
- */
-public final class TableSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable {
-
-    private final int lowKey;
-
-    /**
-     * Constructs a new TableSwitch instruction.
-     * @param value the instruction producing the value being switched on
-     * @param successors the list of successors
-     * @param lowKey the lowest integer key in the table
-     */
-    public TableSwitchNode(ValueNode value, BeginNode[] successors, int lowKey, double[] probability) {
-        super(value, successors, probability);
-        this.lowKey = lowKey;
-    }
-
-    public TableSwitchNode(ValueNode value, int lowKey, double[] switchProbability) {
-        this(value, new BeginNode[switchProbability.length], lowKey, switchProbability);
-    }
-
-    /**
-     * Gets the lowest key in the table switch (inclusive).
-     * @return the low key
-     */
-    public int lowKey() {
-        return lowKey;
-    }
-
-    /**
-     * Gets the highest key in the table switch (exclusive).
-     * @return the high key
-     */
-    public int highKey() {
-        return lowKey + numberOfCases();
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        gen.emitTableSwitch(this);
-    }
-
-    @Override
-    public void simplify(SimplifierTool tool) {
-        if (value() instanceof ConstantNode) {
-            ConstantNode constant = (ConstantNode) value();
-            int value = constant.value.asInt();
-
-            int remainingSuxIndex;
-            if (value >= lowKey() && value <= highKey()) {
-                remainingSuxIndex = value - lowKey();
-            } else {
-                remainingSuxIndex = blockSuccessorCount() - 1;
-            }
-
-            BeginNode remainingSux = blockSuccessor(remainingSuxIndex);
-            for (int i = 0; i < blockSuccessorCount(); i++) {
-                BeginNode sux = blockSuccessor(i);
-                if (sux != remainingSux) {
-                    tool.deleteBranch(sux);
-                }
-            }
-
-            tool.addToWorkList(remainingSux);
-            ((StructuredGraph) graph()).removeSplit(this, remainingSuxIndex);
-        }
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -34,27 +33,27 @@
 public final class UnboxNode extends FixedWithNextNode implements Node.IterableNodeType, Canonicalizable {
 
     @Input private ValueNode source;
-    private CiKind destinationKind;
+    private Kind destinationKind;
 
-    public UnboxNode(CiKind kind, ValueNode source) {
+    public UnboxNode(Kind kind, ValueNode source) {
         super(StampFactory.forKind(kind));
         this.source = source;
         this.destinationKind = kind;
-        assert kind != CiKind.Object : "can only unbox to primitive";
-        assert source.kind() == CiKind.Object : "can only unbox objects";
+        assert kind != Kind.Object : "can only unbox to primitive";
+        assert source.kind() == Kind.Object : "can only unbox objects";
     }
 
     public ValueNode source() {
         return source;
     }
 
-    public CiKind destinationKind() {
+    public Kind destinationKind() {
         return destinationKind;
     }
 
     public void expand(BoxingMethodPool pool) {
-        RiResolvedField field = pool.getBoxField(kind());
-        LoadFieldNode loadField = graph().add(new LoadFieldNode(source, field));
+        ResolvedJavaField field = pool.getBoxField(kind());
+        LoadFieldNode loadField = graph().add(new LoadFieldNode(source, field, StructuredGraph.INVALID_GRAPH_ID));
         loadField.setProbability(probability());
         ((StructuredGraph) graph()).replaceFixedWithFixed(this, loadField);
     }
@@ -62,7 +61,7 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (source.isConstant()) {
-            CiConstant constant = source.asConstant();
+            Constant constant = source.asConstant();
             Object o = constant.asObject();
             if (o != null) {
                 switch (destinationKind) {
@@ -83,7 +82,7 @@
                     case Double:
                         return ConstantNode.forDouble((Long) o, graph());
                     default:
-                        ValueUtil.shouldNotReachHere();
+                        ValueNodeUtil.shouldNotReachHere();
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.cri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -32,32 +31,58 @@
 /**
  * The {@code UnsafeCastNode} produces the same value as its input, but with a different type.
  */
-public final class UnsafeCastNode extends FloatingNode implements Canonicalizable, Lowerable {
+public final class UnsafeCastNode extends FloatingNode implements Canonicalizable, LIRLowerable {
 
     @Input private ValueNode object;
-    private RiResolvedType toType;
+    private ResolvedJavaType toType;
 
     public ValueNode object() {
         return object;
     }
 
-    public UnsafeCastNode(ValueNode object, RiResolvedType toType) {
-        super(StampFactory.declared(toType));
+    public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
+        super(toType.kind().isObject() ? new ObjectStamp(toType, exactType, nonNull) : StampFactory.forKind(toType.kind()));
+        this.object = object;
+        this.toType = toType;
+    }
+
+    public UnsafeCastNode(ValueNode object, ResolvedJavaType toType) {
+        super(toType.kind().isObject() ? StampFactory.declared(toType, object.stamp().nonNull()) : StampFactory.forKind(toType.kind()));
         this.object = object;
         this.toType = toType;
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (object != null && object.declaredType() != null && object.declaredType().isSubtypeOf(toType)) {
-            return object;
+        if (object != null) {
+            if (object.kind().isObject()) {
+                if (object.objectStamp().type() != null && object.objectStamp().type().isSubtypeOf(toType)) {
+                    if (!isNarrower(objectStamp(), object.objectStamp())) {
+                        return object;
+                    }
+                }
+            } else if (object.kind() == kind()) {
+                // Removes redundant casts introduced by WordTypeRewriterPhase
+                return object;
+            }
         }
         return this;
     }
 
-    @Override
-    public void lower(CiLoweringTool tool) {
-        ((StructuredGraph) graph()).replaceFloating(this, object);
+    /**
+     * Determines if one object stamp is narrower than another in terms of nullness and exactness.
+     *
+     * @return true if x is definitely non-null and y's nullness is unknown OR
+     *                  x's type is exact and the exactness of y's type is unknown
+     */
+    private static boolean isNarrower(ObjectStamp x, ObjectStamp y) {
+        if (x.nonNull() && !y.nonNull()) {
+            return true;
+        }
+        if (x.isExactType() && !y.isExactType()) {
+            return true;
+        }
+        return false;
     }
 
     @SuppressWarnings("unused")
@@ -65,4 +90,17 @@
     public static <T> T cast(Object object, @ConstantNodeParameter Class<?> toType) {
         throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
     }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static <T> T cast(Object object, @ConstantNodeParameter Class<?> toType, @ConstantNodeParameter boolean exactType, @ConstantNodeParameter boolean nonNull) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        Value result = generator.newVariable(kind());
+        generator.emitMove(generator.operand(object), result);
+        generator.setResult(this, result);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -31,12 +31,12 @@
 /**
  * Load of a value from a location specified as an offset relative to an object.
  */
-public class UnsafeLoadNode extends AbstractStateSplit implements Lowerable {
+public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
     private final int displacement;
-    private final CiKind loadKind;
+    private final Kind loadKind;
 
     public ValueNode object() {
         return object;
@@ -50,7 +50,15 @@
         return offset;
     }
 
-    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, CiKind kind) {
+    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) {
+        super(nonNull ? StampFactory.objectNonNull() : StampFactory.object());
+        this.object = object;
+        this.displacement = displacement;
+        this.offset = offset;
+        this.loadKind = Kind.Object;
+    }
+
+    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, Kind kind) {
         super(StampFactory.forKind(kind.stackKind()));
         this.object = object;
         this.displacement = displacement;
@@ -58,7 +66,7 @@
         this.loadKind = kind;
     }
 
-    public CiKind loadKind() {
+    public Kind loadKind() {
         return loadKind;
     }
 
@@ -69,7 +77,13 @@
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter CiKind kind) {
+    public static <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    public static Object loadObject(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter boolean nonNull) {
         throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,26 +22,41 @@
  */
 package com.oracle.graal.nodes.extended;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ci.*;
 
 /**
  * Store of a value at a location specified as an offset relative to an object.
  */
-public class UnsafeStoreNode extends AbstractStateSplit implements Lowerable {
+public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
     @Input private ValueNode value;
     private final int displacement;
-    private final CiKind storeKind;
+    private final Kind storeKind;
+    @Input(notDataflow = true) private FrameState stateAfter;
+
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
 
-    public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, CiKind kind) {
-        super(StampFactory.illegal());
-        assert kind != CiKind.Void && kind != CiKind.Illegal;
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return true;
+    }
+
+    public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind kind) {
+        super(StampFactory.forVoid());
+        assert kind != Kind.Void && kind != Kind.Illegal;
         this.object = object;
         this.displacement = displacement;
         this.offset = offset;
@@ -65,11 +80,18 @@
         return value;
     }
 
-    public CiKind storeKind() {
+    public Kind storeKind() {
         return storeKind;
     }
 
     @Override
+    public boolean verify() {
+        assertTrue(storeKind != null, "UnsafeStoreNode must have a store kind");
+        assertTrue(object != null, "UnsafeStoreNode should have an object");
+        return super.verify();
+    }
+
+    @Override
     public void lower(CiLoweringTool tool) {
         tool.getRuntime().lower(this, tool);
     }
@@ -77,55 +99,55 @@
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, boolean value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, boolean value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, byte value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, byte value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, char value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, char value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, double value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, double value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, float value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, float value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, int value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, int value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, short value, @ConstantNodeParameter CiKind kind) {
+    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, short value, @ConstantNodeParameter Kind kind) {
         throw new UnsupportedOperationException();
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,9 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
+import static com.oracle.graal.graph.iterators.NodePredicates.*;
+
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -32,18 +34,10 @@
 /**
  * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph.
  */
-
 public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType {
 
-    @Input private ValueNode object;
-
-    public ValueNode object() {
-        return object;
-    }
-
-    public ValueAnchorNode(ValueNode object) {
-        super(StampFactory.illegal());
-        this.object = object;
+    public ValueAnchorNode(ValueNode... values) {
+        super(StampFactory.forVoid(), values);
     }
 
     @Override
@@ -51,22 +45,42 @@
         // Nothing to emit, since this node is used for structural purposes only.
     }
 
+    public void addAnchoredNode(ValueNode value) {
+        if (!this.dependencies().contains(value)) {
+            this.dependencies().add(value);
+        }
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (object == null) {
-            return null;
-        }
-        if (object instanceof ConstantNode) {
-            return null;
+        if (this.predecessor() instanceof ValueAnchorNode) {
+            ValueAnchorNode previousAnchor = (ValueAnchorNode) this.predecessor();
+            if (previousAnchor.usages().isEmpty()) { // avoid creating cycles
+                // transfer values and remove
+                for (ValueNode node : dependencies().nonNull().distinct()) {
+                    previousAnchor.addAnchoredNode(node);
+                }
+                return previousAnchor;
+            }
         }
-        if (object instanceof IntegerDivNode || object instanceof IntegerRemNode) {
-            if (((ArithmeticNode) object).y().isConstant()) {
-                CiConstant  constant = ((ArithmeticNode) object).y().asConstant();
-                assert constant.kind == object.kind() : constant.kind + " != " + object.kind();
-                if (constant.asLong() != 0) {
-                    return null;
+        for (Node node : dependencies().nonNull().and(isNotA(BeginNode.class))) {
+            if (node instanceof ConstantNode) {
+                continue;
+            }
+            if (node instanceof IntegerDivNode || node instanceof IntegerRemNode) {
+                ArithmeticNode arithmeticNode = (ArithmeticNode) node;
+                if (arithmeticNode.y().isConstant()) {
+                    Constant constant = arithmeticNode.y().asConstant();
+                    assert constant.kind == arithmeticNode.kind() : constant.kind + " != " + arithmeticNode.kind();
+                    if (constant.asLong() != 0) {
+                        continue;
+                    }
                 }
             }
+            return this; // still necessary
+        }
+        if (usages().isEmpty()) {
+            return null; // no node which require an anchor found
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -27,10 +27,10 @@
 import com.oracle.graal.nodes.type.*;
 
 
-public final class WriteMemoryCheckpointNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+public final class WriteMemoryCheckpointNode extends AbstractStateSplit implements StateSplit, LIRLowerable, MemoryCheckpoint {
 
     public WriteMemoryCheckpointNode() {
-        this(StampFactory.illegal());
+        this(StampFactory.forVoid());
     }
 
     public WriteMemoryCheckpointNode(Stamp stamp) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,21 +22,35 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 
-public final class WriteNode extends AccessNode implements LIRLowerable {
+public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable {
     @Input private ValueNode value;
+    @Input(notDataflow = true) private FrameState stateAfter;
+
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return true;
+    }
 
     public ValueNode value() {
         return value;
     }
 
     public WriteNode(ValueNode object, ValueNode value, LocationNode location) {
-        super(object, location, StampFactory.forKind(CiKind.Void));
+        super(object, location, StampFactory.forVoid());
         this.value = value;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessArrayNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -28,7 +28,7 @@
 /**
  * This the base class of all array operations.
  */
-public abstract class AccessArrayNode extends AbstractStateSplit {
+public abstract class AccessArrayNode extends FixedWithNextNode {
 
     @Input private ValueNode array;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,8 +25,8 @@
 import java.lang.reflect.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -35,11 +35,12 @@
 /**
  * The base class of all instructions that access fields.
  */
-public abstract class AccessFieldNode extends AbstractStateSplit implements Lowerable {
+public abstract class AccessFieldNode extends FixedWithNextNode implements Lowerable {
 
     @Input private ValueNode object;
 
-    protected final RiResolvedField field;
+    protected final ResolvedJavaField field;
+    private final long leafGraphId;
 
     public ValueNode object() {
         return object;
@@ -52,10 +53,11 @@
      * @param field the compiler interface representation of the field
      * @param graph
      */
-    public AccessFieldNode(Stamp stamp, ValueNode object, RiResolvedField field) {
+    public AccessFieldNode(Stamp stamp, ValueNode object, ResolvedJavaField field, long leafGraphId) {
         super(stamp);
         this.object = object;
         this.field = field;
+        this.leafGraphId = leafGraphId;
         assert field.holder().isInitialized();
     }
 
@@ -63,10 +65,14 @@
      * Gets the compiler interface field for this field access.
      * @return the compiler interface field for this field access
      */
-    public RiResolvedField field() {
+    public ResolvedJavaField field() {
         return field;
     }
 
+    public long leafGraphId() {
+        return leafGraphId;
+    }
+
     /**
      * Checks whether this field access is an access to a static field.
      * @return {@code true} if this field access is to a static field
@@ -91,7 +97,22 @@
     @Override
     public Map<Object, Object> getDebugProperties() {
         Map<Object, Object> debugProperties = super.getDebugProperties();
-        debugProperties.put("field", CiUtil.format("%h.%n", field));
+        debugProperties.put("field", CodeUtil.format("%h.%n", field));
         return debugProperties;
     }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name) {
+            return super.toString(verbosity) + "#" + field.name();
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
+    public boolean verify() {
+        assertTrue(object != null, "Access object can not be null");
+        return super.verify();
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.types.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ci.*;
 
 /**
  * The {@code AccessIndexedNode} class is the base class of instructions that read or write
@@ -35,30 +35,23 @@
 public abstract class AccessIndexedNode extends AccessArrayNode implements TypeFeedbackProvider {
 
     @Input private ValueNode index;
-    @Input private ValueNode length;
-    private final CiKind elementType;
+    private final Kind elementType;
     private final long leafGraphId;
 
     public ValueNode index() {
         return index;
     }
 
-    public ValueNode length() {
-        return length;
-    }
-
     /**
      * Create an new AccessIndexedNode.
      * @param kind the result kind of the access
      * @param array the instruction producing the array
      * @param index the instruction producing the index
-     * @param length the instruction producing the length
      * @param elementKind the type of the elements of the array
      */
-    protected AccessIndexedNode(Stamp stamp, ValueNode array, ValueNode index, ValueNode length, CiKind elementKind, long leafGraphId) {
+    protected AccessIndexedNode(Stamp stamp, ValueNode array, ValueNode index, Kind elementKind, long leafGraphId) {
         super(stamp, array);
         this.index = index;
-        this.length = length;
         this.elementType = elementKind;
         this.leafGraphId = leafGraphId;
     }
@@ -67,7 +60,7 @@
      * Gets the element type of the array.
      * @return the element type
      */
-    public CiKind elementKind() {
+    public Kind elementKind() {
         return elementType;
     }
 
@@ -77,7 +70,6 @@
 
     @Override
     public void typeFeedback(TypeFeedbackTool tool) {
-        tool.addScalar(index()).constantBound(Condition.GE, CiConstant.INT_0);
-        tool.addScalar(index()).valueBound(Condition.LT, length, tool.queryScalar(length));
+        tool.addScalar(index()).constantBound(Condition.GE, Constant.INT_0);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
@@ -43,7 +42,7 @@
  * {@link MonitorEnterNode}. Optimization phases are free to throw {@link CiBailout} if they detect such cases.
  * Otherwise, they are detected during LIR construction.
  */
-public abstract class AccessMonitorNode extends AbstractStateSplit implements MemoryCheckpoint {
+public abstract class AccessMonitorNode extends AbstractStateSplit implements StateSplit, MemoryCheckpoint {
 
     @Input private ValueNode object;
     private boolean eliminated;
@@ -66,7 +65,7 @@
      * @param object the instruction producing the object
      */
     public AccessMonitorNode(ValueNode object) {
-        super(StampFactory.illegal());
+        super(StampFactory.forVoid());
         this.object = object;
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -52,11 +52,10 @@
             assert length != null;
             return length;
         }
-        CiConstant constantValue = null;
-        if (array().isConstant() && !array().isNullConstant()) {
-            constantValue = array().asConstant();
+        CodeCacheProvider runtime = tool.runtime();
+        if (runtime != null && array().isConstant() && !array().isNullConstant()) {
+            Constant constantValue = array().asConstant();
             if (constantValue != null && constantValue.isNonNull()) {
-                RiRuntime runtime = tool.runtime();
                 return ConstantNode.forInt(runtime.getArrayLength(constantValue), graph());
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,57 +22,46 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.cri.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.types.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 
 /**
- * The {@code CheckCastNode} represents a {@link Bytecodes#CHECKCAST}.
- *
- * The {@link #targetClass()} of a CheckCastNode can be null for array store checks!
+ * Implements a type check that results in a {@link ClassCastException} if it fails.
  */
-public final class CheckCastNode extends TypeCheckNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, TypeFeedbackProvider, TypeCanonicalizable {
+public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Lowerable, Node.IterableNodeType, TypeFeedbackProvider, TypeCanonicalizable {
 
-    @Input(notDataflow = true) protected final FixedNode anchor;
-    protected final boolean emitCode;
-
-    public FixedNode anchor() {
-        return anchor;
-    }
-
-    public boolean emitCode() {
-        return emitCode;
-    }
+    @Input private ValueNode object;
+    @Input private ValueNode targetClassInstruction;
+    private final ResolvedJavaType targetClass;
+    private final JavaTypeProfile profile;
 
     /**
      * Creates a new CheckCast instruction.
-     *
      * @param targetClassInstruction the instruction which produces the class which is being cast to
      * @param targetClass the class being cast to
      * @param object the instruction producing the object
      */
-    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object) {
-        this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false);
-    }
-
-    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, boolean emitCode) {
-        this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false, emitCode);
+    public CheckCastNode(ValueNode targetClassInstruction, ResolvedJavaType targetClass, ValueNode object) {
+        this(targetClassInstruction, targetClass, object, null);
     }
 
-    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact) {
-        this(anchor, targetClassInstruction, targetClass, object, hints, hintsExact, true);
+    public CheckCastNode(ValueNode targetClassInstruction, ResolvedJavaType targetClass, ValueNode object, JavaTypeProfile profile) {
+        super(targetClass == null ? StampFactory.forKind(Kind.Object) : StampFactory.declared(targetClass));
+        this.targetClassInstruction = targetClassInstruction;
+        this.targetClass = targetClass;
+        this.object = object;
+        this.profile = profile;
     }
 
-    private CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, boolean emitCode) {
-        super(targetClassInstruction, targetClass, object, hints, hintsExact, targetClass == null ? StampFactory.forKind(CiKind.Object) : StampFactory.declared(targetClass));
-        this.anchor = anchor;
-        this.emitCode = emitCode;
+    @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
     }
 
     @Override
@@ -82,43 +71,26 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        RiResolvedType objectDeclaredType = object().declaredType();
-        RiResolvedType targetClass = targetClass();
-        if (objectDeclaredType != null && targetClass != null && objectDeclaredType.isSubtypeOf(targetClass)) {
-            freeAnchor();
-            return object();
-        }
-        CiConstant constant = object().asConstant();
-        if (constant != null) {
-            assert constant.kind == CiKind.Object;
-            if (constant.isNull()) {
-                freeAnchor();
+        assert object() != null : this;
+
+        if (targetClass != null) {
+            ResolvedJavaType objectType = object().objectStamp().type();
+            if (objectType != null && objectType.isSubtypeOf(targetClass)) {
+                // we don't have to check for null types here because they will also pass the checkcast.
                 return object();
             }
         }
 
-        if (tool.assumptions() != null && hints() != null && targetClass() != null) {
-            if (!hintsExact() && hints().length == 1 && hints()[0] == targetClass().uniqueConcreteSubtype()) {
-                tool.assumptions().recordConcreteSubtype(targetClass(), hints()[0]);
-                return graph().unique(new CheckCastNode(anchor, targetClassInstruction(), targetClass(), object(), hints(), true));
+        Constant constant = object().asConstant();
+        if (constant != null) {
+            assert constant.kind == Kind.Object;
+            if (constant.isNull()) {
+                return object();
             }
         }
         return this;
     }
 
-    // TODO (thomaswue): Find a better way to handle anchors.
-    private void freeAnchor() {
-        ValueAnchorNode anchorUsage = usages().filter(ValueAnchorNode.class).first();
-        if (anchorUsage != null) {
-            anchorUsage.replaceFirstInput(this, null);
-        }
-    }
-
-    @Override
-    public BooleanNode negate() {
-        throw new Error("A CheckCast does not produce a boolean value, so it should actually not be a subclass of BooleanNode");
-    }
-
     @Override
     public void typeFeedback(TypeFeedbackTool tool) {
         if (targetClass() != null) {
@@ -129,7 +101,7 @@
     @Override
     public Result canonical(TypeFeedbackTool tool) {
         ObjectTypeQuery query = tool.queryObject(object());
-        if (query.constantBound(Condition.EQ, CiConstant.NULL_OBJECT)) {
+        if (query.constantBound(Condition.EQ, Constant.NULL_OBJECT)) {
             return new Result(object(), query);
         } else if (targetClass() != null) {
             if (query.declaredType(targetClass())) {
@@ -138,4 +110,27 @@
         }
         return null;
     }
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public ValueNode targetClassInstruction() {
+        return targetClassInstruction;
+    }
+
+    /**
+     * Gets the target class, i.e. the class being cast to, or the class being tested against.
+     * This may be null in the case where the type being tested is dynamically loaded such as
+     * when checking an object array store.
+     *
+     * @return the target class or null if not known
+     */
+    public ResolvedJavaType targetClass() {
+        return targetClass;
+    }
+
+    public JavaTypeProfile profile() {
+        return profile;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,18 +22,18 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ci.*;
 
 /**
  * Represents an atomic compare-and-swap operation
  * The result is a boolean that contains whether the value matched the expected value.
  */
-public class CompareAndSwapNode extends AbstractStateSplit implements LIRLowerable, Lowerable, MemoryCheckpoint {
+public class CompareAndSwapNode extends AbstractStateSplit implements StateSplit, LIRLowerable, Lowerable, MemoryCheckpoint {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
@@ -62,7 +62,7 @@
     }
 
     public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) {
-        super(StampFactory.forKind(CiKind.Boolean.stackKind()));
+        super(StampFactory.forKind(Kind.Boolean.stackKind()));
         assert expected.kind() == newValue.kind();
         this.object = object;
         this.offset = offset;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,22 +22,22 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ci.*;
 
 /**
  * The {@code ExceptionObject} instruction represents the incoming exception object to an exception handler.
  */
-public class ExceptionObjectNode extends AbstractStateSplit implements LIRLowerable, MemoryCheckpoint {
+public class ExceptionObjectNode extends AbstractStateSplit implements StateSplit, LIRLowerable, MemoryCheckpoint {
 
     /**
      * Constructs a new ExceptionObject instruction.
      */
-    public ExceptionObjectNode() {
-        super(StampFactory.forKind(CiKind.Object));
+    public ExceptionObjectNode(MetaAccessProvider runtime) {
+        super(StampFactory.declared(runtime.getResolvedJavaType(Throwable.class)));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -33,13 +32,12 @@
 /**
  * The {@code InstanceOfNode} represents an instanceof test.
  */
-public final class InstanceOfNode extends TypeCheckNode implements Canonicalizable, LIRLowerable, ConditionalTypeFeedbackProvider, TypeCanonicalizable {
-
-    private final boolean negated;
+public final class InstanceOfNode extends BooleanNode implements Canonicalizable, LIRLowerable, ConditionalTypeFeedbackProvider, TypeCanonicalizable {
 
-    public boolean negated() {
-        return negated;
-    }
+    @Input private ValueNode object;
+    @Input private ValueNode targetClassInstruction;
+    private final ResolvedJavaType targetClass;
+    private final JavaTypeProfile profile;
 
     /**
      * Constructs a new InstanceOfNode.
@@ -48,13 +46,16 @@
      * @param targetClass the class which is the target of the instanceof check
      * @param object the instruction producing the object input to this instruction
      */
-    public InstanceOfNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, boolean negated) {
-        this(targetClassInstruction, targetClass, object, EMPTY_HINTS, false, negated);
+    public InstanceOfNode(ValueNode targetClassInstruction, ResolvedJavaType targetClass, ValueNode object) {
+        this(targetClassInstruction, targetClass, object, null);
     }
 
-    public InstanceOfNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, boolean negated) {
-        super(targetClassInstruction, targetClass, object, hints, hintsExact, StampFactory.illegal());
-        this.negated = negated;
+    public InstanceOfNode(ValueNode targetClassInstruction, ResolvedJavaType targetClass, ValueNode object, JavaTypeProfile profile) {
+        super(StampFactory.condition());
+        this.targetClassInstruction = targetClassInstruction;
+        this.targetClass = targetClass;
+        this.object = object;
+        this.profile = profile;
         assert targetClass != null;
     }
 
@@ -65,64 +66,96 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         assert object() != null : this;
-        RiResolvedType exact = object().exactType();
-        if (exact != null) {
-            boolean result = exact.isSubtypeOf(targetClass());
-            if (result != negated) {
-                // The instanceof check reduces to a null check.
-                return graph().unique(new NullCheckNode(object(), false));
+
+        ObjectStamp stamp = object().objectStamp();
+        ResolvedJavaType type = stamp.type();
+
+        if (stamp.isExactType()) {
+            boolean subType = type.isSubtypeOf(targetClass());
+
+            if (subType) {
+                if (stamp.nonNull()) {
+                    // the instanceOf matches, so return true
+                    return ConstantNode.forBoolean(true, graph());
+                } else {
+                    // the instanceof matches if the object is non-null, so return true depending on the null-ness.
+                    negateUsages();
+                    return graph().unique(new IsNullNode(object()));
+                }
             } else {
-                // The instanceof check can never succeed.
+                // since this type check failed for an exact type we know that it can never succeed at run time.
+                // we also don't care about null values, since they will also make the check fail.
                 return ConstantNode.forBoolean(false, graph());
             }
+        } else if (type != null) {
+            boolean subType = type.isSubtypeOf(targetClass());
+
+            if (subType) {
+                if (stamp.nonNull()) {
+                    // the instanceOf matches, so return true
+                    return ConstantNode.forBoolean(true, graph());
+                } else {
+                    // the instanceof matches if the object is non-null, so return true depending on the null-ness.
+                    negateUsages();
+                    return graph().unique(new IsNullNode(object()));
+                }
+            } else {
+                // since the subtype comparison was only performed on a declared type we don't really know if it might be true at run time...
+            }
         }
-        CiConstant constant = object().asConstant();
+
+        Constant constant = object().asConstant();
         if (constant != null) {
-            assert constant.kind == CiKind.Object;
+            assert constant.kind == Kind.Object;
             if (constant.isNull()) {
-                return ConstantNode.forBoolean(negated, graph());
+                return ConstantNode.forBoolean(false, graph());
             } else {
-                assert false : "non-null constants are always expected to provide an exactType";
-            }
-        }
-        if (tool.assumptions() != null && hints() != null && targetClass() != null) {
-            if (!hintsExact() && hints().length == 1 && hints()[0] == targetClass().uniqueConcreteSubtype()) {
-                tool.assumptions().recordConcreteSubtype(targetClass(), hints()[0]);
-                return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hints(), true, negated));
+                assert false : "non-null constants are always expected to provide an exact type";
             }
         }
         return this;
     }
 
     @Override
-    public BooleanNode negate() {
-        return graph().unique(new InstanceOfNode(targetClassInstruction(), targetClass(), object(), hints(), hintsExact(), !negated));
-    }
-
-    @Override
     public void typeFeedback(TypeFeedbackTool tool) {
-        if (negated) {
-            tool.addObject(object()).notDeclaredType(targetClass(), true);
-        } else {
-            tool.addObject(object()).declaredType(targetClass(), true);
-        }
+        tool.addObject(object()).declaredType(targetClass(), true);
     }
 
     @Override
     public Result canonical(TypeFeedbackTool tool) {
         ObjectTypeQuery query = tool.queryObject(object());
-        if (query.constantBound(Condition.EQ, CiConstant.NULL_OBJECT)) {
-            return new Result(ConstantNode.forBoolean(negated, graph()), query);
+        if (query.constantBound(Condition.EQ, Constant.NULL_OBJECT)) {
+            return new Result(ConstantNode.forBoolean(false, graph()), query);
         } else if (targetClass() != null) {
             if (query.notDeclaredType(targetClass())) {
-                return new Result(ConstantNode.forBoolean(negated, graph()), query);
+                return new Result(ConstantNode.forBoolean(false, graph()), query);
             }
-            if (query.constantBound(Condition.NE, CiConstant.NULL_OBJECT)) {
+            if (query.constantBound(Condition.NE, Constant.NULL_OBJECT)) {
                 if (query.declaredType(targetClass())) {
-                    return new Result(ConstantNode.forBoolean(!negated, graph()), query);
+                    return new Result(ConstantNode.forBoolean(true, graph()), query);
                 }
             }
         }
         return null;
     }
+
+    public ValueNode object() {
+        return object;
+    }
+
+    public ValueNode targetClassInstruction() {
+        return targetClassInstruction;
+    }
+
+    /**
+     * Gets the target class, i.e. the class being cast to, or the class being tested against.
+     * @return the target class
+     */
+    public ResolvedJavaType targetClass() {
+        return targetClass;
+    }
+
+    public JavaTypeProfile profile() {
+        return profile;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/IsTypeNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/IsTypeNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,10 +22,8 @@
  */
 package com.oracle.graal.nodes.java;
 
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -34,7 +32,7 @@
 public final class IsTypeNode extends BooleanNode implements Canonicalizable, LIRLowerable {
 
     @Input private ValueNode objectClass;
-    private final RiResolvedType type;
+    private final ResolvedJavaType type;
 
     public ValueNode objectClass() {
         return objectClass;
@@ -46,14 +44,14 @@
      * @param object the instruction producing the object to check against the given type
      * @param type the type for this check
      */
-    public IsTypeNode(ValueNode objectClass, RiResolvedType type) {
-        super(StampFactory.illegal());
-        assert objectClass == null || objectClass.kind() == CiKind.Object;
+    public IsTypeNode(ValueNode objectClass, ResolvedJavaType type) {
+        super(StampFactory.condition());
+        assert objectClass == null || objectClass.kind() == Kind.Object;
         this.type = type;
         this.objectClass = objectClass;
     }
 
-    public RiResolvedType type() {
+    public ResolvedJavaType type() {
         return type;
     }
 
@@ -63,24 +61,20 @@
     }
 
     @Override
-    public Map<Object, Object> getDebugProperties() {
-        Map<Object, Object> properties = super.getDebugProperties();
-        properties.put("type", type);
-        return properties;
-    }
-
-    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        RiResolvedType exactType = objectClass() instanceof ReadHubNode ? ((ReadHubNode) objectClass()).object().exactType() : null;
-        if (exactType != null) {
-            return ConstantNode.forBoolean(exactType == type(), graph());
+        if (objectClass().isConstant()) {
+            Constant constant = objectClass().asConstant();
+            Constant typeHub = type.getEncoding(Representation.ObjectHub);
+            assert constant.kind == typeHub.kind;
+            return ConstantNode.forBoolean(tool.runtime().areConstantObjectsEqual(constant, typeHub), graph());
         }
-        // constants return the correct exactType, so they are handled by the code above
+        // TODO(ls) since a ReadHubNode with an exactType should canonicalize itself to a constant this should actually never happen, maybe turn into an assertion?
+        if (objectClass() instanceof ReadHubNode) {
+            ObjectStamp stamp = ((ReadHubNode) objectClass()).object().objectStamp();
+            if (stamp.isExactType()) {
+                return ConstantNode.forBoolean(stamp.type() == type(), graph());
+            }
+        }
         return this;
     }
-
-    @Override
-    public BooleanNode negate() {
-        throw new Error("unimplemented");
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -40,35 +40,32 @@
      * @param object the receiver object
      * @param field the compiler interface field
      */
-    public LoadFieldNode(ValueNode object, RiResolvedField field) {
-        super(createStamp(field), object, field);
+    public LoadFieldNode(ValueNode object, ResolvedJavaField field, long leafGraphId) {
+        super(createStamp(field), object, field, leafGraphId);
     }
 
-    private static Stamp createStamp(RiResolvedField field) {
-        CiKind kind = field.kind(false);
-        if (kind == CiKind.Object && field.type() instanceof RiResolvedType) {
-            RiResolvedType resolvedType = (RiResolvedType) field.type();
-            return StampFactory.declared(resolvedType);
+    private static Stamp createStamp(ResolvedJavaField field) {
+        Kind kind = field.kind();
+        if (kind == Kind.Object && field.type() instanceof ResolvedJavaType) {
+            return StampFactory.declared((ResolvedJavaType) field.type());
         } else {
             return StampFactory.forKind(kind);
         }
     }
 
     @Override
-    public boolean needsStateAfter() {
-        return false;
-    }
-
-    @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        CiConstant constant = null;
-        if (isStatic()) {
-            constant = field().constantValue(null);
-        } else if (object().isConstant() && !object().isNullConstant()) {
-            constant = field().constantValue(object().asConstant());
-        }
-        if (constant != null) {
-            return ConstantNode.forCiConstant(constant, tool.runtime(), graph());
+        CodeCacheProvider runtime = tool.runtime();
+        if (runtime != null) {
+            Constant constant = null;
+            if (isStatic()) {
+                constant = field().constantValue(null);
+            } else if (object().isConstant() && !object().isNullConstant()) {
+                constant = field().constantValue(object().asConstant());
+            }
+            if (constant != null) {
+                return ConstantNode.forConstant(constant, runtime, graph());
+            }
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,10 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -32,34 +35,46 @@
 /**
  * The {@code LoadIndexedNode} represents a read from an element of an array.
  */
-public final class LoadIndexedNode extends AccessIndexedNode implements Lowerable, Node.IterableNodeType {
+public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Lowerable, Node.IterableNodeType {
 
     /**
      * Creates a new LoadIndexedNode.
      * @param array the instruction producing the array
      * @param index the instruction producing the index
-     * @param length the instruction producing the length
      * @param elementKind the element type
      */
-    public LoadIndexedNode(ValueNode array, ValueNode index, ValueNode length, CiKind elementKind, long leafGraphId) {
-        super(createStamp(array, elementKind), array, index, length, elementKind, leafGraphId);
+    public LoadIndexedNode(ValueNode array, ValueNode index, Kind elementKind, long leafGraphId) {
+        super(createStamp(array, elementKind), array, index, elementKind, leafGraphId);
     }
 
-    private static Stamp createStamp(ValueNode array, CiKind kind) {
-        if (kind == CiKind.Object && array.declaredType() != null) {
-            return StampFactory.declared(array.declaredType().componentType());
+    private static Stamp createStamp(ValueNode array, Kind kind) {
+        if (kind == Kind.Object && array.objectStamp().type() != null) {
+            return StampFactory.declared(array.objectStamp().type().componentType());
         } else {
             return StampFactory.forKind(kind);
         }
     }
 
     @Override
-    public boolean needsStateAfter() {
-        return false;
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
     }
 
     @Override
-    public void lower(CiLoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+    public ValueNode canonical(CanonicalizerTool tool) {
+        CodeCacheProvider runtime = tool.runtime();
+        if (runtime != null && index().isConstant() && array().isConstant() && !array().isNullConstant()) {
+            Constant arrayConst = array().asConstant();
+            if (tool.isImmutable(arrayConst)) {
+                int index = index().asConstant().asInt();
+                Object array = arrayConst.asObject();
+                int length = Array.getLength(array);
+                if (index >= 0 && index < length) {
+                    return ConstantNode.forConstant(elementKind().readUnsafeConstant(array,
+                                    elementKind().arrayBaseOffset() + index * elementKind().arrayIndexScale()), runtime, graph());
+                }
+            }
+        }
+        return this;
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -37,14 +36,14 @@
         Virtual
     }
 
-    private final RiType returnType;
-    private RiResolvedMethod targetMethod;
+    private final JavaType returnType;
+    private ResolvedJavaMethod targetMethod;
     private InvokeKind invokeKind;
 
     /**
      * @param arguments
      */
-    public MethodCallTargetNode(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] arguments, RiType returnType) {
+    public MethodCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType) {
         super(arguments);
         this.invokeKind = invokeKind;
         this.returnType = returnType;
@@ -52,7 +51,7 @@
     }
 
     @Override
-    public RiType returnType() {
+    public JavaType returnType() {
         return returnType;
     }
 
@@ -60,7 +59,7 @@
      * Gets the target method for this invocation instruction.
      * @return the target method
      */
-    public RiResolvedMethod targetMethod() {
+    public ResolvedJavaMethod targetMethod() {
         return targetMethod;
     }
 
@@ -72,7 +71,7 @@
         this.invokeKind = kind;
     }
 
-    public void setTargetMethod(RiResolvedMethod method) {
+    public void setTargetMethod(ResolvedJavaMethod method) {
         targetMethod = method;
     }
 
@@ -94,8 +93,8 @@
     }
 
     @Override
-    public CiKind returnKind() {
-        return targetMethod().signature().returnKind(false);
+    public Kind returnKind() {
+        return targetMethod().signature().returnKind();
     }
 
     public Invoke invoke() {
@@ -125,9 +124,9 @@
     public ValueNode canonical(CanonicalizerTool tool) {
         if (!isStatic()) {
             ValueNode receiver = receiver();
-            if (receiver != null && receiver.exactType() != null) {
+            if (receiver != null && receiver.objectStamp().isExactType()) {
                 if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
-                    RiResolvedMethod method = receiver.exactType().resolveMethodImpl(targetMethod);
+                    ResolvedJavaMethod method = receiver.objectStamp().type().resolveMethodImpl(targetMethod);
                     if (method != null) {
                         invokeKind = InvokeKind.Special;
                         targetMethod = method;
@@ -139,9 +138,9 @@
     }
 
     public Stamp returnStamp() {
-        CiKind returnKind = targetMethod.signature().returnKind(false);
-        if (returnKind == CiKind.Object && returnType instanceof RiResolvedType) {
-            return StampFactory.declared((RiResolvedType) returnType);
+        Kind returnKind = targetMethod.signature().returnKind();
+        if (returnKind == Kind.Object && returnType instanceof ResolvedJavaType) {
+            return StampFactory.declared((ResolvedJavaType) returnType);
         } else {
             return StampFactory.forKind(returnKind);
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,7 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -75,12 +74,12 @@
      * Gets the element type of the array.
      * @return the element type of the array
      */
-    public abstract RiResolvedType elementType();
+    public abstract ResolvedJavaType elementType();
 
     @Override
     public void typeFeedback(TypeFeedbackTool tool) {
-        assert length.kind() == CiKind.Int;
-        tool.addScalar(length).constantBound(Condition.GE, CiConstant.INT_0);
+        assert length.kind() == Kind.Int;
+        tool.addScalar(length).constantBound(Condition.GE, Constant.INT_0);
     }
 
     public EscapeOp getEscapeOp() {
@@ -92,7 +91,7 @@
         @Override
         public boolean canAnalyze(Node node) {
             NewArrayNode x = (NewArrayNode) node;
-            CiConstant length = x.dimension(0).asConstant();
+            Constant length = x.dimension(0).asConstant();
             return length != null && length.asInt() >= 0 && length.asInt() < MaximumEscapeAnalysisArrayLength;
         }
 
@@ -103,7 +102,7 @@
             EscapeField[] fields = new EscapeField[length];
             for (int i = 0; i < length; i++) {
                 Integer representation = i;
-                fields[i] = new EscapeField("[" + i + "]", representation, ((NewArrayNode) node).elementType());
+                fields[i] = new EscapeField(Integer.toString(i), representation, ((NewArrayNode) node).elementType());
             }
             return fields;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,7 +24,8 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.cri.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -34,15 +35,15 @@
 /**
  * The {@code NewInstanceNode} represents the allocation of an instance class object.
  */
-public final class NewInstanceNode extends FixedWithNextNode implements EscapeAnalyzable, LIRLowerable, Node.IterableNodeType {
+public final class NewInstanceNode extends FixedWithNextNode implements EscapeAnalyzable, Lowerable, LIRLowerable, Node.IterableNodeType {
 
-    private final RiResolvedType instanceClass;
+    private final ResolvedJavaType instanceClass;
 
     /**
      * Constructs a NewInstanceNode.
      * @param type the class being allocated
      */
-    public NewInstanceNode(RiResolvedType type) {
+    public NewInstanceNode(ResolvedJavaType type) {
         super(StampFactory.exactNonNull(type));
         this.instanceClass = type;
     }
@@ -51,11 +52,16 @@
      * Gets the instance class being allocated by this node.
      * @return the instance class allocated
      */
-    public RiResolvedType instanceClass() {
+    public ResolvedJavaType instanceClass() {
         return instanceClass;
     }
 
     @Override
+    public void lower(CiLoweringTool tool) {
+        tool.getRuntime().lower(this, tool);
+    }
+
+    @Override
     public void generate(LIRGeneratorTool gen) {
         gen.visitNewInstance(this);
     }
@@ -78,12 +84,12 @@
             return true;
         }
 
-        private void fillEscapeFields(RiResolvedType type, List<EscapeField> escapeFields) {
+        private void fillEscapeFields(ResolvedJavaType type, List<EscapeField> escapeFields) {
             if (type != null) {
                 fillEscapeFields(type.superType(), escapeFields);
-                RiField[] declaredFields = type.declaredFields();
+                JavaField[] declaredFields = type.declaredFields();
                 assert declaredFields != null : "the runtime must specify the declared fields of that type";
-                for (RiField field : declaredFields) {
+                for (JavaField field : declaredFields) {
                     escapeFields.add(new EscapeField(field.name(), field, field.type()));
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -38,7 +37,7 @@
 public final class NewMultiArrayNode extends FixedWithNextNode implements LIRLowerable, TypeFeedbackProvider {
 
     @Input private final NodeInputList<ValueNode> dimensions;
-    private final RiResolvedType type;
+    private final ResolvedJavaType type;
 
     public ValueNode dimension(int index) {
         return dimensions.get(index);
@@ -55,7 +54,7 @@
      * @param cpi the constant pool index for resolution
      * @param riConstantPool the constant pool for resolution
      */
-    public NewMultiArrayNode(RiResolvedType type, ValueNode[] dimensions) {
+    public NewMultiArrayNode(ResolvedJavaType type, ValueNode[] dimensions) {
         super(StampFactory.exactNonNull(type));
         this.type = type;
         this.dimensions = new NodeInputList<>(this, dimensions);
@@ -67,15 +66,15 @@
         gen.visitNewMultiArray(this);
     }
 
-    public RiResolvedType type() {
+    public ResolvedJavaType type() {
         return type;
     }
 
     @Override
     public void typeFeedback(TypeFeedbackTool tool) {
         for (ValueNode length : dimensions) {
-            assert length.kind() == CiKind.Int;
-            tool.addScalar(length).constantBound(Condition.GE, CiConstant.INT_0);
+            assert length.kind() == Kind.Int;
+            tool.addScalar(length).constantBound(Condition.GE, Constant.INT_0);
         }
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewObjectArrayNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewObjectArrayNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -33,21 +33,20 @@
  */
 public final class NewObjectArrayNode extends NewArrayNode implements LIRLowerable, Node.IterableNodeType {
 
-    private final RiResolvedType elementClass;
+    private final ResolvedJavaType elementClass;
 
     /**
      * Constructs a new NewObjectArrayNode.
      * @param elementClass the class of elements in this array
      * @param length the node producing the length of the array
-     * @param graph
      */
-    public NewObjectArrayNode(RiResolvedType elementClass, ValueNode length) {
+    public NewObjectArrayNode(ResolvedJavaType elementClass, ValueNode length) {
         super(StampFactory.exactNonNull(elementClass.arrayOf()), length);
         this.elementClass = elementClass;
     }
 
     @Override
-    public RiResolvedType elementType() {
+    public ResolvedJavaType elementType() {
         return elementClass;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewTypeArrayNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewTypeArrayNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -32,15 +32,15 @@
  */
 public final class NewTypeArrayNode extends NewArrayNode implements LIRLowerable {
 
-    private final RiResolvedType elementType;
+    private final ResolvedJavaType elementType;
 
-    public NewTypeArrayNode(ValueNode length, RiResolvedType elementType) {
+    public NewTypeArrayNode(ValueNode length, ResolvedJavaType elementType) {
         super(StampFactory.exactNonNull(elementType.arrayOf()), length);
         this.elementType = elementType;
     }
 
     @Override
-    public RiResolvedType elementType() {
+    public ResolvedJavaType elementType() {
         return elementType;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -31,7 +30,7 @@
 /**
  * This node is used to perform the finalizer registration at the end of the java.lang.Object constructor.
  */
-public final class RegisterFinalizerNode extends AbstractStateSplit implements Canonicalizable, LIRLowerable {
+public final class RegisterFinalizerNode extends AbstractStateSplit implements StateSplit, Canonicalizable, LIRLowerable {
 
     @Input private ValueNode object;
 
@@ -40,33 +39,26 @@
     }
 
     public RegisterFinalizerNode(ValueNode object) {
-        super(StampFactory.illegal());
+        super(StampFactory.forVoid());
         this.object = object;
     }
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.emitCallToRuntime(CiRuntimeCall.RegisterFinalizer, true, gen.operand(object()));
+        gen.emitCall(RuntimeCall.RegisterFinalizer, true, gen.operand(object()));
     }
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        RiResolvedType declaredType = object.declaredType();
-        RiResolvedType exactType = object.exactType();
-        if (exactType == null && declaredType != null) {
-            exactType = declaredType.exactType();
-        }
+        ObjectStamp stamp = object.objectStamp();
 
         boolean needsCheck = true;
-        if (exactType != null) {
-            // we have an exact type
-            needsCheck = exactType.hasFinalizer();
-        } else {
+        if (stamp.isExactType()) {
+            needsCheck = stamp.type().hasFinalizer();
+        } else if (stamp.type() != null && !stamp.type().hasFinalizableSubclass()) {
             // if either the declared type of receiver or the holder can be assumed to have no finalizers
-            if (declaredType != null && !declaredType.hasFinalizableSubclass()) {
-                if (tool.assumptions() != null && tool.assumptions().recordNoFinalizableSubclassAssumption(declaredType)) {
-                    needsCheck = false;
-                }
+            if (tool.assumptions() != null && tool.assumptions().recordNoFinalizableSubclassAssumption(stamp.type())) {
+                needsCheck = false;
             }
         }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,16 +22,31 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.max.cri.ri.*;
 
 /**
  * The {@code StoreFieldNode} represents a write to a static or instance field.
  */
-public final class StoreFieldNode extends AccessFieldNode {
+public final class StoreFieldNode extends AccessFieldNode implements StateSplit {
 
     @Input private ValueNode value;
+    @Input(notDataflow = true) private FrameState stateAfter;
+
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return true;
+    }
 
     public ValueNode value() {
         return value;
@@ -43,8 +58,8 @@
      * @param field the compiler interface field
      * @param value the node representing the value to store to the field
      */
-    public StoreFieldNode(ValueNode object, RiResolvedField field, ValueNode value) {
-        super(StampFactory.illegal(), object, field);
+    public StoreFieldNode(ValueNode object, ResolvedJavaField field, ValueNode value, long leafGraphId) {
+        super(StampFactory.forVoid(), object, field, leafGraphId);
         this.value = value;
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.cri.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -31,9 +31,24 @@
 /**
  * The {@code StoreIndexedNode} represents a write to an array element.
  */
-public final class StoreIndexedNode extends AccessIndexedNode implements Lowerable {
+public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable {
 
     @Input private ValueNode value;
+    @Input(notDataflow = true) private FrameState stateAfter;
+
+    public FrameState stateAfter() {
+        return stateAfter;
+    }
+
+    public void setStateAfter(FrameState x) {
+        assert x == null || x.isAlive() : "frame state must be in a graph";
+        updateUsages(stateAfter, x);
+        stateAfter = x;
+    }
+
+    public boolean hasSideEffect() {
+        return true;
+    }
 
     public ValueNode value() {
         return value;
@@ -43,12 +58,11 @@
      * Creates a new StoreIndexedNode.
      * @param array the node producing the array
      * @param index the node producing the index
-     * @param length the node producing the length
      * @param elementKind the element type
      * @param value the value to store into the array
      */
-    public StoreIndexedNode(ValueNode array, ValueNode index, ValueNode length, CiKind elementKind, ValueNode value, long leafGraphId) {
-        super(StampFactory.illegal(), array, index, length, elementKind, leafGraphId);
+    public StoreIndexedNode(ValueNode array, ValueNode index, Kind elementKind, ValueNode value, long leafGraphId) {
+        super(StampFactory.forVoid(), array, index, elementKind, leafGraphId);
         this.value = value;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.java;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.type.*;
-
-/**
- * The {@code TypeCheckNode} is the base class of casts and instanceof tests.
- */
-public abstract class TypeCheckNode extends BooleanNode {
-
-    protected static final RiResolvedType[] EMPTY_HINTS = new RiResolvedType[0];
-    @Input private ValueNode object;
-    @Input private ValueNode targetClassInstruction;
-    private final RiResolvedType targetClass;
-    private final RiResolvedType[] hints;
-    private final boolean hintsExact;
-
-    /**
-     * Creates a new TypeCheckNode.
-     * @param targetClassInstruction the instruction which produces the class which is being cast to or checked against
-     * @param targetClass the class that is being casted to or checked against
-     * @param object the node which produces the object
-     * @param kind the result type of this node
-     */
-    public TypeCheckNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, Stamp stamp) {
-        super(stamp);
-        this.targetClassInstruction = targetClassInstruction;
-        this.targetClass = targetClass;
-        this.object = object;
-        this.hints = hints;
-        this.hintsExact = hintsExact;
-    }
-
-    public ValueNode object() {
-        return object;
-    }
-
-    public ValueNode targetClassInstruction() {
-        return targetClassInstruction;
-    }
-
-    /**
-     * Gets the target class, i.e. the class being cast to, or the class being tested against.
-     * @return the target class
-     */
-    public RiResolvedType targetClass() {
-        return targetClass;
-    }
-
-    public RiResolvedType[] hints() {
-        return hints;
-    }
-
-    public boolean hintsExact() {
-        return hintsExact;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2009, 2011, 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.java;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+
+/**
+ * The {@code TypeSwitchNode} performs a lookup based on the type of the input value.
+ * The type comparison is an exact type comparison, not an instanceof.
+ */
+public final class TypeSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable {
+
+    private final ResolvedJavaType[] keys;
+
+    /**
+     * Constructs a type switch instruction. The keyProbabilities and keySuccessors array contain key.length + 1
+     * entries, the last entry describes the default (fall through) case.
+     *
+     * @param value the instruction producing the value being switched on
+     * @param successors the list of successors
+     * @param keys the list of types
+     * @param keyProbabilities the probabilities of the keys
+     * @param keySuccessor the successor index for each key
+     */
+    public TypeSwitchNode(ValueNode value, BeginNode[] successors, double[] successorProbabilities, ResolvedJavaType[] keys, double[] keyProbabilities, int[] keySuccessors) {
+        super(value, successors, successorProbabilities, keySuccessors, keyProbabilities);
+        assert successors.length == keys.length + 1;
+        assert successors.length == keyProbabilities.length;
+        this.keys = keys;
+    }
+
+    @Override
+    public int keyCount() {
+        return keys.length;
+    }
+
+    @Override
+    public Constant keyAt(int i) {
+        return keys[i].getEncoding(Representation.ObjectHub);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool gen) {
+        gen.emitSwitch(this);
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (value() instanceof ConstantNode) {
+            Constant constant = value().asConstant();
+
+            int survivingEdge = keySuccessorIndex(keyCount());
+            for (int i = 0; i < keyCount(); i++) {
+                Constant typeHub = keyAt(i);
+                assert constant.kind == typeHub.kind;
+                if (tool.runtime().areConstantObjectsEqual(value().asConstant(), typeHub)) {
+                    survivingEdge = keySuccessorIndex(i);
+                }
+            }
+            for (int i = 0; i < blockSuccessorCount(); i++) {
+                if (i != survivingEdge) {
+                    tool.deleteBranch(blockSuccessor(i));
+                }
+            }
+            tool.addToWorkList(blockSuccessor(survivingEdge));
+            ((StructuredGraph) graph()).removeSplitPropagate(this, survivingEdge);
+        }
+        if (value() instanceof ReadHubNode) {
+            ObjectStamp stamp = ((ReadHubNode) value()).object().objectStamp();
+            if (stamp.type() != null) {
+                int validKeys = 0;
+                for (int i = 0; i < keyCount(); i++) {
+                    if (keys[i].isSubtypeOf(stamp.type())) {
+                        validKeys++;
+                    }
+                }
+                if (validKeys == 0) {
+                    tool.addToWorkList(defaultSuccessor());
+                    ((StructuredGraph) graph()).removeSplitPropagate(this, defaultSuccessorIndex());
+                } else if (validKeys != keys.length) {
+                    ArrayList<BeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
+                    ResolvedJavaType[] newKeys = new ResolvedJavaType[validKeys];
+                    int[] newKeySuccessors = new int [validKeys + 1];
+                    double[] newKeyProbabilities = new double[validKeys + 1];
+                    double totalProbability = 0;
+                    int current = 0;
+                    for (int i = 0; i < keyCount() + 1; i++) {
+                        if (i == keyCount() || keys[i].isSubtypeOf(stamp.type())) {
+                            int index = newSuccessors.indexOf(keySuccessor(i));
+                            if (index == -1) {
+                                index = newSuccessors.size();
+                                newSuccessors.add(keySuccessor(i));
+                            }
+                            newKeySuccessors[current] = index;
+                            if (i < keyCount()) {
+                                newKeys[current] = keys[i];
+                            }
+                            newKeyProbabilities[current] = keyProbability(i);
+                            totalProbability += keyProbability(i);
+                            current++;
+                        }
+                    }
+                    if (totalProbability > 0) {
+                        for (int i = 0; i < current; i++) {
+                            newKeyProbabilities[i] /= totalProbability;
+                        }
+                    }
+
+                    double[] newSuccessorProbabilities = successorProbabilites(newSuccessors.size(), newKeySuccessors, newKeyProbabilities);
+
+                    for (int i = 0; i < blockSuccessorCount(); i++) {
+                        BeginNode successor = blockSuccessor(i);
+                        if (!newSuccessors.contains(successor)) {
+                            tool.deleteBranch(successor);
+                        }
+                        setBlockSuccessor(i, null);
+                    }
+
+                    BeginNode[] successorsArray = newSuccessors.toArray(new BeginNode[newSuccessors.size()]);
+                    TypeSwitchNode newSwitch = graph().add(new TypeSwitchNode(value(), successorsArray, newSuccessorProbabilities, newKeys, newKeyProbabilities, newKeySuccessors));
+                    ((FixedWithNextNode) predecessor()).setNext(newSwitch);
+                    GraphUtil.killWithUnusedFloatingInputs(this);
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,18 @@
  */
 package com.oracle.graal.nodes.spi;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 
 
 public interface CanonicalizerTool {
-    CiTarget target();
-    CiAssumptions assumptions();
-    RiRuntime runtime();
+    TargetDescription target();
+    Assumptions assumptions();
+    CodeCacheProvider runtime();
+
+    /**
+     * Determines if a given constant is an object/array whose current
+     * fields/elements will never change.
+     */
+    boolean isImmutable(Constant objectConstant);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/EscapeField.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/EscapeField.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,15 +22,15 @@
  */
 package com.oracle.graal.nodes.spi;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 
 public class EscapeField {
 
     private final String name;
     private final Object representation;
-    private final RiType type;
+    private final JavaType type;
 
-    public EscapeField(String name, Object representation, RiType type) {
+    public EscapeField(String name, Object representation, JavaType type) {
         this.name = name;
         this.representation = representation;
         this.type = type;
@@ -44,7 +44,7 @@
         return representation;
     }
 
-    public RiType type() {
+    public JavaType type() {
         return type;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/EscapeOp.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/EscapeOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,26 +24,24 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.virtual.*;
-
 
 public abstract class EscapeOp {
 
     public abstract boolean canAnalyze(Node node);
 
     public boolean escape(Node node, Node usage) {
-        if (usage instanceof NullCheckNode) {
-            assert ((NullCheckNode) usage).object() == node;
+        if (usage instanceof IsNullNode) {
+            assert ((IsNullNode) usage).object() == node;
             return false;
         } else if (usage instanceof IsTypeNode) {
             assert ((IsTypeNode) usage).objectClass() == node;
             return false;
-        } else if (usage instanceof FrameState) {
+        } else if (usage instanceof VirtualState) {
             assert usage.inputs().contains(node);
             return true;
         } else if (usage instanceof AccessMonitorNode) {
@@ -73,8 +71,6 @@
                 // in order to not escape the access needs to have a valid constant index and either a store into node or self-referencing
                 return !isValidConstantIndex(x) || x.value() == node && x.array() != node;
             }
-        } else if (usage instanceof VirtualObjectFieldNode) {
-            return false;
         } else if (usage instanceof RegisterFinalizerNode) {
             assert ((RegisterFinalizerNode) usage).object() == node;
             return false;
@@ -94,9 +90,9 @@
     }
 
     public static boolean isValidConstantIndex(AccessIndexedNode x) {
-        CiConstant index = x.index().asConstant();
+        Constant index = x.index().asConstant();
         if (x.array() instanceof NewArrayNode) {
-            CiConstant length = ((NewArrayNode) x.array()).dimension(0).asConstant();
+            Constant length = ((NewArrayNode) x.array()).dimension(0).asConstant();
             return index != null && length != null && index.asInt() >= 0 && index.asInt() < length.asInt();
         } else {
             return false;
@@ -107,13 +103,13 @@
 
     public void beforeUpdate(Node node, Node usage) {
         // IsNonNullNode and IsTypeNode should have been eliminated by the CanonicalizerPhase, but we can't rely on this
-        if (usage instanceof NullCheckNode) {
-            NullCheckNode x = (NullCheckNode) usage;
-            ((StructuredGraph) x.graph()).replaceFloating(x, ConstantNode.forBoolean(!x.expectedNull, node.graph()));
+        if (usage instanceof IsNullNode) {
+            IsNullNode x = (IsNullNode) usage;
+            ((StructuredGraph) x.graph()).replaceFloating(x, ConstantNode.forBoolean(false, node.graph()));
         } else if (usage instanceof IsTypeNode) {
             IsTypeNode x = (IsTypeNode) usage;
-            assert x.type() == ((ValueNode) node).exactType();
-            ((StructuredGraph) x.graph()).replaceFloating(x, ConstantNode.forBoolean(true, node.graph()));
+            boolean result = ((ValueNode) node).objectStamp().type() == x.type();
+            ((StructuredGraph) x.graph()).replaceFloating(x, ConstantNode.forBoolean(result, node.graph()));
         } else if (usage instanceof AccessMonitorNode) {
             ((AccessMonitorNode) usage).eliminate();
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,15 +22,15 @@
  */
 package com.oracle.graal.nodes.spi;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 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.*;
-import com.oracle.max.cri.ri.*;
 
 public abstract class LIRGeneratorTool {
-    public abstract CiTarget target();
+    public abstract TargetDescription target();
 
     /**
      * Checks whether the supplied constant can be used without loading it into a register
@@ -38,7 +38,7 @@
      * @param c The constant to check.
      * @return True if the constant can be used directly, false if the constant needs to be in a register.
      */
-    public abstract boolean canInlineConstant(CiConstant c);
+    public abstract boolean canInlineConstant(Constant c);
 
     /**
      * Checks whether the supplied constant can be used without loading it into a register
@@ -46,49 +46,53 @@
      * @param c The constant to check.
      * @return True if the constant can be used directly, false if the constant needs to be in a register.
      */
-    public abstract boolean canStoreConstant(CiConstant c);
+    public abstract boolean canStoreConstant(Constant c);
+
+    public abstract RegisterAttributes attributes(Register register);
 
-    public abstract CiValue operand(ValueNode object);
-    public abstract CiValue newVariable(CiKind kind);
-    public abstract CiValue setResult(ValueNode x, CiValue operand);
+    public abstract Value operand(ValueNode object);
+    public abstract Value newVariable(Kind kind);
+    public abstract Value setResult(ValueNode x, Value operand);
 
-    public abstract CiAddress makeAddress(LocationNode location, ValueNode object);
+    public abstract Address makeAddress(LocationNode location, ValueNode object);
 
-    public abstract CiValue emitMove(CiValue input);
-    public abstract void emitMove(CiValue src, CiValue dst);
-    public abstract CiValue emitLoad(CiValue loadAddress, boolean canTrap);
-    public abstract void emitStore(CiValue storeAddress, CiValue input, boolean canTrap);
-    public abstract CiValue emitLea(CiValue address);
+    public abstract Value emitMove(Value input);
+    public abstract void emitMove(Value src, Value dst);
+    public abstract Value emitLoad(Value loadAddress, boolean canTrap);
+    public abstract void emitStore(Value storeAddress, Value input, boolean canTrap);
+    public abstract Value emitLea(Value address);
 
-    public abstract CiValue emitNegate(CiValue input);
-    public abstract CiValue emitAdd(CiValue a, CiValue b);
-    public abstract CiValue emitSub(CiValue a, CiValue b);
-    public abstract CiValue emitMul(CiValue a, CiValue b);
-    public abstract CiValue emitDiv(CiValue a, CiValue b);
-    public abstract CiValue emitRem(CiValue a, CiValue b);
-    public abstract CiValue emitUDiv(CiValue a, CiValue b);
-    public abstract CiValue emitURem(CiValue a, CiValue b);
+    public abstract Value emitNegate(Value input);
+    public abstract Value emitAdd(Value a, Value b);
+    public abstract Value emitSub(Value a, Value b);
+    public abstract Value emitMul(Value a, Value b);
+    public abstract Value emitDiv(Value a, Value b);
+    public abstract Value emitRem(Value a, Value b);
+    public abstract Value emitUDiv(Value a, Value b);
+    public abstract Value emitURem(Value a, Value b);
+
+    public abstract Value emitAnd(Value a, Value b);
+    public abstract Value emitOr(Value a, Value b);
+    public abstract Value emitXor(Value a, Value b);
 
-    public abstract CiValue emitAnd(CiValue a, CiValue b);
-    public abstract CiValue emitOr(CiValue a, CiValue b);
-    public abstract CiValue emitXor(CiValue a, CiValue b);
+    public abstract Value emitShl(Value a, Value b);
+    public abstract Value emitShr(Value a, Value b);
+    public abstract Value emitUShr(Value a, Value b);
 
-    public abstract CiValue emitShl(CiValue a, CiValue b);
-    public abstract CiValue emitShr(CiValue a, CiValue b);
-    public abstract CiValue emitUShr(CiValue a, CiValue b);
-
-    public abstract CiValue emitConvert(ConvertNode.Op opcode, CiValue inputVal);
+    public abstract Value emitConvert(ConvertNode.Op opcode, Value inputVal);
     public abstract void emitMembar(int barriers);
-    public abstract void emitDeoptimizeOn(Condition cond, RiDeoptAction action, RiDeoptReason reason, Object deoptInfo);
-    public abstract void emitDeoptimize(RiDeoptAction action, RiDeoptReason reason, Object deoptInfo, long leafGraphId);
-    public abstract CiValue emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args);
+    public abstract void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo);
+    public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo, long leafGraphId);
+    public abstract Value emitCall(Object target, Kind result, Kind[] arguments, boolean canTrap, Value... args);
+    public final Value emitCall(RuntimeCall runtimeCall, boolean canTrap, Value... args) {
+        return emitCall(runtimeCall, runtimeCall.resultKind, runtimeCall.arguments, canTrap, args);
+    }
 
     public abstract void emitIf(IfNode i);
     public abstract void emitConditional(ConditionalNode i);
-    public abstract void emitGuardCheck(BooleanNode comp, RiDeoptReason deoptReason, RiDeoptAction deoptAction, long leafGraphId);
+    public abstract void emitGuardCheck(BooleanNode comp, DeoptimizationReason deoptReason, DeoptimizationAction deoptAction, boolean negated, long leafGraphId);
 
-    public abstract void emitLookupSwitch(LookupSwitchNode i);
-    public abstract void emitTableSwitch(TableSwitchNode i);
+    public abstract void emitSwitch(SwitchNode i);
 
     public abstract void emitInvoke(Invoke i);
     public abstract void emitRuntimeCall(RuntimeCallNode i);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Negatable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -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.spi;
+
+import com.oracle.graal.nodes.*;
+
+/**
+ * This interface marks a node as being able to negate its effect, this is intended for nodes that depend on a
+ * BooleanNode condition. The canonical representation of has, for example, no way to represent a != b. If such an
+ * expression appears during canonicalization the negated expression will be created (a == b) and the usages will be
+ * negated, using this interface's {@link #negate()} method.
+ */
+public interface Negatable {
+
+    /**
+     * Tells this node that a condition it depends has been negated, and that it thus needs to invert its own effect.
+     * For example, an {@link IfNode} would switch its true and false successors.
+     */
+    Negatable negate();
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ObjectTypeFeedbackStore.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ObjectTypeFeedbackStore.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,7 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -45,7 +44,7 @@
         }
 
         @Override
-        public boolean constantBound(Condition condition, final CiConstant constant) {
+        public boolean constantBound(Condition condition, final Constant constant) {
             assert condition == Condition.EQ || condition == Condition.NE;
             if (condition == Condition.EQ) {
                 return store.prove(Equals.class, new BooleanPredicate<Equals>() {
@@ -85,7 +84,7 @@
         }
 
         @Override
-        public boolean declaredType(final RiResolvedType type) {
+        public boolean declaredType(final ResolvedJavaType type) {
             return store.prove(Info.class, new BooleanPredicate<Info>() {
                 @Override
                 public boolean evaluate(Info element) {
@@ -99,7 +98,7 @@
         }
 
         @Override
-        public boolean exactType(final RiResolvedType type) {
+        public boolean exactType(final ResolvedJavaType type) {
             return store.prove(ObjectTypeExact.class, new BooleanPredicate<ObjectTypeExact>() {
                 @Override
                 public boolean evaluate(ObjectTypeExact element) {
@@ -109,12 +108,12 @@
         }
 
         @Override
-        public boolean notDeclaredType(RiResolvedType type) {
+        public boolean notDeclaredType(ResolvedJavaType type) {
             return false;
         }
 
         @Override
-        public boolean notExactType(final RiResolvedType type) {
+        public boolean notExactType(final ResolvedJavaType type) {
             return store.prove(Info.class, new BooleanPredicate<Info>() {
                 @Override
                 public boolean evaluate(Info element) {
@@ -138,7 +137,7 @@
         }
 
         @Override
-        public Node dependency() {
+        public ValueNode dependency() {
             return store.dependency;
         }
     }
@@ -150,9 +149,9 @@
     }
 
     private static final class Equals extends Info {
-        public final CiConstant constant;
+        public final Constant constant;
 
-        public Equals(CiConstant constant) {
+        public Equals(Constant constant) {
             this.constant = constant;
         }
 
@@ -163,9 +162,9 @@
     }
 
     private static final class NotEquals extends Info {
-        public final CiConstant constant;
+        public final Constant constant;
 
-        public NotEquals(CiConstant constant) {
+        public NotEquals(Constant constant) {
             this.constant = constant;
         }
 
@@ -176,16 +175,16 @@
     }
 
     private static class ObjectType extends Info {
-        public final RiResolvedType type;
+        public final ResolvedJavaType type;
 
-        public ObjectType(RiResolvedType type) {
+        public ObjectType(ResolvedJavaType type) {
             this.type = type;
         }
     }
 
     private static final class ObjectTypeDeclared extends ObjectType {
 
-        public ObjectTypeDeclared(RiResolvedType type) {
+        public ObjectTypeDeclared(ResolvedJavaType type) {
             super(type);
         }
 
@@ -197,7 +196,7 @@
 
     private static final class ObjectTypeExact extends ObjectType {
 
-        public ObjectTypeExact(RiResolvedType type) {
+        public ObjectTypeExact(ResolvedJavaType type) {
             super(type);
         }
 
@@ -225,7 +224,7 @@
 
     private final TypeFeedbackChanged changed;
 
-    private Node dependency;
+    private ValueNode dependency;
 
     private void updateDependency() {
         dependency = changed.node;
@@ -291,7 +290,7 @@
     }
 
     @Override
-    public void constantBound(Condition condition, CiConstant constant) {
+    public void constantBound(Condition condition, Constant constant) {
         assert condition == Condition.EQ || condition == Condition.NE;
 
         if (condition == Condition.EQ) {
@@ -347,7 +346,7 @@
     }
 
     @Override
-    public void declaredType(RiResolvedType type, boolean nonNull) {
+    public void declaredType(ResolvedJavaType type, boolean nonNull) {
         assert type != null;
 
         for (ListIterator<Info> iter = infos.listIterator(); iter.hasNext();) {
@@ -358,7 +357,7 @@
                 if (typeInfo.type == type && index == 0) {
                     if (index == 0) {
                         if (nonNull) {
-                            constantBound(Condition.NE, CiConstant.NULL_OBJECT);
+                            constantBound(Condition.NE, Constant.NULL_OBJECT);
                         }
                         return;
                     } else {
@@ -370,12 +369,12 @@
         infos.add(new ObjectTypeDeclared(type));
         updateDependency();
         if (nonNull) {
-            constantBound(Condition.NE, CiConstant.NULL_OBJECT);
+            constantBound(Condition.NE, Constant.NULL_OBJECT);
         }
     }
 
     @Override
-    public void exactType(RiResolvedType type) {
+    public void exactType(ResolvedJavaType type) {
         assert type != null;
 
         for (ListIterator<Info> iter = infos.listIterator(); iter.hasNext();) {
@@ -385,7 +384,7 @@
                 ObjectTypeExact typeInfo = (ObjectTypeExact) info;
                 if (typeInfo.type == type && index == 0) {
                     if (index == 0) {
-                        constantBound(Condition.NE, CiConstant.NULL_OBJECT);
+                        constantBound(Condition.NE, Constant.NULL_OBJECT);
                         return;
                     } else {
                         iter.remove();
@@ -395,15 +394,15 @@
         }
         infos.add(new ObjectTypeExact(type));
         updateDependency();
-        constantBound(Condition.NE, CiConstant.NULL_OBJECT);
+        constantBound(Condition.NE, Constant.NULL_OBJECT);
     }
 
     @Override
-    public void notDeclaredType(RiResolvedType type, boolean includesNull) {
+    public void notDeclaredType(ResolvedJavaType type, boolean includesNull) {
     }
 
     @Override
-    public void notExactType(RiResolvedType type) {
+    public void notExactType(ResolvedJavaType type) {
     }
 
     public static ObjectTypeFeedbackStore meet(ObjectTypeFeedbackStore[] others) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ObjectTypeFeedbackTool.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ObjectTypeFeedbackTool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,22 +22,21 @@
  */
 package com.oracle.graal.nodes.spi.types;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 
 public interface ObjectTypeFeedbackTool {
 
-    void constantBound(Condition condition, CiConstant constant);
+    void constantBound(Condition condition, Constant constant);
 
     void valueBound(Condition condition, ValueNode otherValue);
 
-    void declaredType(RiResolvedType type, boolean nonNull);
+    void declaredType(ResolvedJavaType type, boolean nonNull);
 
-    void exactType(RiResolvedType type);
+    void exactType(ResolvedJavaType type);
 
-    void notDeclaredType(RiResolvedType type, boolean includesNull);
+    void notDeclaredType(ResolvedJavaType type, boolean includesNull);
 
-    void notExactType(RiResolvedType type);
+    void notExactType(ResolvedJavaType type);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ObjectTypeQuery.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ObjectTypeQuery.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,24 +22,23 @@
  */
 package com.oracle.graal.nodes.spi.types;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 
 public interface ObjectTypeQuery extends TypeQuery {
 
-    boolean constantBound(Condition condition, CiConstant constant);
+    boolean constantBound(Condition condition, Constant constant);
 
     boolean valueBound(Condition condition, ValueNode otherValue);
 
-    boolean declaredType(RiResolvedType type);
+    boolean declaredType(ResolvedJavaType type);
 
-    boolean exactType(RiResolvedType type);
+    boolean exactType(ResolvedJavaType type);
 
-    boolean notDeclaredType(RiResolvedType type);
+    boolean notDeclaredType(ResolvedJavaType type);
 
-    boolean notExactType(RiResolvedType type);
+    boolean notExactType(ResolvedJavaType type);
 
     ObjectTypeFeedbackStore store();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ScalarTypeFeedbackStore.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ScalarTypeFeedbackStore.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,10 +24,9 @@
 
 import java.util.*;
 
-import com.oracle.graal.graph.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.max.cri.ci.*;
 
 public class ScalarTypeFeedbackStore extends TypeFeedbackStore<ScalarTypeFeedbackStore> implements ScalarTypeFeedbackTool, CloneableTypeFeedback {
 
@@ -40,8 +39,8 @@
         }
 
         @Override
-        public boolean constantBound(Condition condition, CiConstant constant) {
-            if (constant.kind == CiKind.Int || constant.kind == CiKind.Long) {
+        public boolean constantBound(Condition condition, Constant constant) {
+            if (constant.kind == Kind.Int || constant.kind == Kind.Long) {
                 switch (condition) {
                     case EQ:
                         return store.constantBounds.lowerBound == constant.asLong() && store.constantBounds.upperBound == constant.asLong();
@@ -89,7 +88,7 @@
         }
 
         @Override
-        public Node dependency() {
+        public ValueNode dependency() {
             return store.dependency;
         }
     }
@@ -118,21 +117,21 @@
         }
     }
 
-    private final CiKind kind;
+    private final Kind kind;
     private final ConstantBound constantBounds;
     private final TypeFeedbackChanged changed;
-    private Node dependency;
+    private ValueNode dependency;
     private HashMap<ValueNode, Condition> valueBounds;
 
     private void updateDependency() {
         dependency = changed.node;
     }
 
-    public ScalarTypeFeedbackStore(CiKind kind, TypeFeedbackChanged changed) {
+    public ScalarTypeFeedbackStore(Kind kind, TypeFeedbackChanged changed) {
         this.kind = kind;
-        if (kind == CiKind.Int) {
+        if (kind == Kind.Int) {
             constantBounds = new ConstantBound(Integer.MIN_VALUE, Integer.MAX_VALUE);
-        } else if (kind == CiKind.Long) {
+        } else if (kind == Kind.Long) {
             constantBounds = new ConstantBound(Long.MIN_VALUE, Long.MAX_VALUE);
         } else {
             constantBounds = null;
@@ -157,7 +156,7 @@
     }
 
     @Override
-    public void constantBound(Condition condition, CiConstant constant) {
+    public void constantBound(Condition condition, Constant constant) {
         ConstantBound newBound = createBounds(condition, constant);
         if (newBound != null) {
             if (constantBounds.join(newBound)) {
@@ -166,9 +165,9 @@
         }
     }
 
-    private static ConstantBound createBounds(Condition condition, CiConstant constant) {
+    private static ConstantBound createBounds(Condition condition, Constant constant) {
         ConstantBound newBound;
-        if (constant.kind == CiKind.Int || constant.kind == CiKind.Long) {
+        if (constant.kind == Kind.Int || constant.kind == Kind.Long) {
             switch (condition) {
                 case EQ:
                     newBound = new ConstantBound(constant.asLong(), constant.asLong());
@@ -237,39 +236,39 @@
             case LE:
             case LT:
                 simpleValueBound(condition, otherValue);
-                constantBound(condition, new CiConstant(kind, other.constantBounds.upperBound));
+                constantBound(condition, new Constant(kind, other.constantBounds.upperBound));
                 break;
             case GE:
             case GT:
                 simpleValueBound(condition, otherValue);
-                constantBound(condition, new CiConstant(kind, other.constantBounds.lowerBound));
+                constantBound(condition, new Constant(kind, other.constantBounds.lowerBound));
                 break;
             case BT:
                 if (other.constantBounds.lowerBound >= 0) {
                     simpleValueBound(Condition.LT, otherValue);
-                    constantBound(Condition.GE, new CiConstant(kind, 0));
-                    constantBound(Condition.LT, new CiConstant(kind, other.constantBounds.upperBound));
+                    constantBound(Condition.GE, new Constant(kind, 0));
+                    constantBound(Condition.LT, new Constant(kind, other.constantBounds.upperBound));
                 }
                 break;
             case BE:
                 if (other.constantBounds.lowerBound >= 0) {
                     simpleValueBound(Condition.LE, otherValue);
-                    constantBound(Condition.GE, new CiConstant(kind, 0));
-                    constantBound(Condition.LE, new CiConstant(kind, other.constantBounds.upperBound));
+                    constantBound(Condition.GE, new Constant(kind, 0));
+                    constantBound(Condition.LE, new Constant(kind, other.constantBounds.upperBound));
                 }
                 break;
             case AT:
                 if (other.constantBounds.upperBound < 0) {
                     simpleValueBound(Condition.GT, otherValue);
-                    constantBound(Condition.LT, new CiConstant(kind, 0));
-                    constantBound(Condition.GT, new CiConstant(kind, other.constantBounds.lowerBound));
+                    constantBound(Condition.LT, new Constant(kind, 0));
+                    constantBound(Condition.GT, new Constant(kind, other.constantBounds.lowerBound));
                 }
                 break;
             case AE:
                 if (other.constantBounds.upperBound < 0) {
                     simpleValueBound(Condition.GE, otherValue);
-                    constantBound(Condition.LT, new CiConstant(kind, 0));
-                    constantBound(Condition.GE, new CiConstant(kind, other.constantBounds.lowerBound));
+                    constantBound(Condition.LT, new Constant(kind, 0));
+                    constantBound(Condition.GE, new Constant(kind, other.constantBounds.lowerBound));
                 }
                 break;
         }
@@ -358,20 +357,20 @@
     }
 
     @Override
-    public void setTranslated(CiConstant deltaConstant, ScalarTypeQuery old) {
+    public void setTranslated(Constant deltaConstant, ScalarTypeQuery old) {
         assert deltaConstant.kind == kind;
         ScalarTypeFeedbackStore other = old.store();
         assert other.kind == kind;
         long lower = other.constantBounds.lowerBound;
         long upper = other.constantBounds.upperBound;
-        if (kind == CiKind.Int) {
+        if (kind == Kind.Int) {
             int delta = deltaConstant.asInt();
             int newLower = (int) lower + delta;
             int newUpper = (int) upper + delta;
             if ((newLower <= lower && newUpper <= upper) || (newLower > lower && newUpper > upper)) {
                 constantBounds.join(new ConstantBound(newLower, newUpper));
             }
-        } else if (kind == CiKind.Long) {
+        } else if (kind == Kind.Long) {
             long delta = deltaConstant.asLong();
             long newLower = lower + delta;
             long newUpper = upper + delta;
@@ -387,20 +386,20 @@
         return constantBounds.lowerBound == minValue(kind) && constantBounds.upperBound == maxValue(kind) && (valueBounds == null || valueBounds.isEmpty());
     }
 
-    private static long minValue(CiKind kind) {
-        if (kind == CiKind.Int) {
+    private static long minValue(Kind kind) {
+        if (kind == Kind.Int) {
             return Integer.MIN_VALUE;
-        } else if (kind == CiKind.Long) {
+        } else if (kind == Kind.Long) {
             return Long.MIN_VALUE;
         } else {
             throw new UnsupportedOperationException();
         }
     }
 
-    private static long maxValue(CiKind kind) {
-        if (kind == CiKind.Int) {
+    private static long maxValue(Kind kind) {
+        if (kind == Kind.Int) {
             return Integer.MAX_VALUE;
-        } else if (kind == CiKind.Long) {
+        } else if (kind == Kind.Long) {
             return Long.MAX_VALUE;
         } else {
             throw new UnsupportedOperationException();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ScalarTypeFeedbackTool.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ScalarTypeFeedbackTool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,15 +22,15 @@
  */
 package com.oracle.graal.nodes.spi.types;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 
 public interface ScalarTypeFeedbackTool {
 
-    void constantBound(Condition condition, CiConstant constant);
+    void constantBound(Condition condition, Constant constant);
 
     void valueBound(Condition condition, ValueNode otherValue, ScalarTypeQuery type);
 
-    void setTranslated(CiConstant delta, ScalarTypeQuery old);
+    void setTranslated(Constant delta, ScalarTypeQuery old);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ScalarTypeQuery.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/ScalarTypeQuery.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.nodes.spi.types;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 
 public interface ScalarTypeQuery extends TypeQuery {
 
-    boolean constantBound(Condition condition, CiConstant constant);
+    boolean constantBound(Condition condition, Constant constant);
 
     boolean valueBound(Condition condition, ValueNode otherValue);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeCanonicalizable.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeCanonicalizable.java	Wed Jun 27 17:35:32 2012 +0200
@@ -29,11 +29,11 @@
 
 public interface TypeCanonicalizable {
 
-    Node[] EMPTY_ARRAY = new Node[0];
+    ValueNode[] EMPTY_ARRAY = new ValueNode[0];
 
     public static class Result {
         public final ValueNode replacement;
-        public final Node[] dependencies;
+        public final ValueNode[] dependencies;
 
         public Result(ValueNode replacement) {
             this.replacement = replacement;
@@ -44,7 +44,7 @@
             assert query != null;
             this.replacement = replacement;
             if (query.dependency() != null) {
-                this.dependencies = new Node[] {query.dependency()};
+                this.dependencies = new ValueNode[] {query.dependency()};
             } else {
                 this.dependencies = EMPTY_ARRAY;
             }
@@ -58,7 +58,7 @@
                     deps.add(query.dependency());
                 }
             }
-            this.dependencies = deps.toArray(new Node[deps.size()]);
+            this.dependencies = deps.toArray(new ValueNode[deps.size()]);
         }
 
         @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeFeedbackChanged.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeFeedbackChanged.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.nodes.spi.types;
 
-import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
 
 public class TypeFeedbackChanged {
 
-    public Node node;
+    public ValueNode node;
 
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeFeedbackTool.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeFeedbackTool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.spi.types;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 
 public interface TypeFeedbackTool {
@@ -35,7 +35,7 @@
 
     ObjectTypeQuery queryObject(ValueNode value);
 
-    RiRuntime runtime();
+    CodeCacheProvider runtime();
 
     TypeFeedbackTool negate();
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeQuery.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/types/TypeQuery.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.nodes.spi.types;
 
-import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
 
 public interface TypeQuery {
 
-    Node dependency();
+    ValueNode dependency();
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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.type;
+
+import com.oracle.graal.api.meta.*;
+
+
+public class FloatStamp extends Stamp {
+
+    protected FloatStamp(Kind kind) {
+        super(kind);
+        assert kind == Kind.Float || kind == Kind.Double;
+    }
+
+    @Override
+    public String toString() {
+        return "" + kind().typeChar;
+    }
+
+    @Override
+    public boolean alwaysDistinct(Stamp other) {
+        return false;
+    }
+
+    @Override
+    public Stamp meet(Stamp other) {
+        assert kind() == other.kind();
+        return this;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/GenericStamp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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.type;
+
+import com.oracle.graal.api.meta.*;
+
+public final class GenericStamp extends Stamp {
+
+    public enum GenericStampType {
+        Dependency, Extension, Virtual, Condition, Void
+    }
+
+    private final GenericStampType type;
+
+    protected GenericStamp(GenericStampType type) {
+        super(Kind.Void);
+        this.type = type;
+    }
+
+    public GenericStampType type() {
+        return type;
+    }
+
+    @Override
+    public String toString() {
+        return type.toString();
+    }
+
+    @Override
+    public boolean alwaysDistinct(Stamp other) {
+        return false;
+    }
+
+    @Override
+    public Stamp meet(Stamp other) {
+        assert ((GenericStamp) other).type == type;
+        return this;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 + ((type == null) ? 0 : type.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        if (type != ((GenericStamp) obj).type) {
+            return false;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,160 @@
+/*
+ * 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.type;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Describes the possible values of a {@link ValueNode} that produces an int or long result.
+ *
+ * The description consists of (inclusive) lower and upper bounds and a bit-mask.
+ */
+public class IntegerStamp extends Stamp {
+
+    private final long lowerBound;
+    private final long upperBound;
+    private final long mask;
+
+    public IntegerStamp(Kind kind) {
+        this(kind, kind.minValue(), kind.maxValue(), defaultMask(kind));
+    }
+
+    public IntegerStamp(Kind kind, long lowerBound, long upperBound, long mask) {
+        super(kind);
+        assert lowerBound <= upperBound;
+        assert lowerBound >= kind.minValue();
+        assert upperBound <= kind.maxValue();
+        assert (mask & defaultMask(kind)) == mask;
+        this.lowerBound = lowerBound;
+        this.upperBound = upperBound;
+        this.mask = mask;
+    }
+
+    /**
+     * The (inclusive) lower bound on the value described by this stamp.
+     */
+    public long lowerBound() {
+        return lowerBound;
+    }
+
+    /**
+     * The (inclusive) upper bound on the value described by this stamp.
+     */
+    public long upperBound() {
+        return upperBound;
+    }
+
+    /**
+     * This bit-mask describes the bits that can be set in the value described by this stamp. It is primarily used to
+     * represent values that are multiples of a known power of two.
+     */
+    public long mask() {
+        return mask;
+    }
+
+    public boolean isUnrestricted() {
+        return lowerBound == kind().minValue() && upperBound == kind().maxValue() && mask == defaultMask(kind());
+    }
+
+    public boolean contains(long value) {
+        return value >= lowerBound && value <= upperBound && (value & mask) == (value & defaultMask(kind()));
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append(kind().typeChar);
+        if (lowerBound == upperBound) {
+            str.append(" [").append(lowerBound).append(']');
+        } else if (lowerBound != kind().minValue() || upperBound != kind().maxValue()) {
+            str.append(" [").append(lowerBound).append(" - ").append(upperBound).append(']');
+        }
+        if (mask != defaultMask(kind())) {
+            str.append(" #").append(Long.toHexString(mask));
+        }
+        return str.toString();
+    }
+
+    @Override
+    public boolean alwaysDistinct(Stamp otherStamp) {
+        IntegerStamp other = (IntegerStamp) otherStamp;
+        return lowerBound > other.upperBound || upperBound < other.lowerBound;
+    }
+
+    @Override
+    public Stamp meet(Stamp otherStamp) {
+        IntegerStamp other = (IntegerStamp) otherStamp;
+        assert kind() == other.kind();
+        long meetUpperBound = Math.max(upperBound, other.upperBound);
+        long meetLowerBound = Math.min(lowerBound, other.lowerBound);
+        long meetMask = mask | other.mask;
+        if (meetLowerBound == lowerBound && meetUpperBound == upperBound && meetMask == mask) {
+            return this;
+        } else {
+            return new IntegerStamp(kind(), meetLowerBound, meetUpperBound, meetMask);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (int) (lowerBound ^ (lowerBound >>> 32));
+        result = prime * result + (int) (upperBound ^ (upperBound >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        IntegerStamp other = (IntegerStamp) obj;
+        if (lowerBound != other.lowerBound || upperBound != other.upperBound || mask != other.mask) {
+            return false;
+        }
+        return true;
+    }
+
+    public static long defaultMask(Kind kind) {
+        if (kind == Kind.Int) {
+            return 0xFFFFFFFFL;
+        } else {
+            return 0xFFFFFFFFFFFFFFFFL;
+        }
+    }
+
+    public static long maskFor(Kind kind, long lowerBound, long upperBound) {
+        long mask = lowerBound | upperBound;
+        if (mask == 0) {
+            return 0;
+        } else {
+            return ((-1L) >>> Long.numberOfLeadingZeros(mask)) & defaultMask(kind);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/ObjectStamp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,131 @@
+/*
+ * 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.type;
+
+import com.oracle.graal.api.meta.*;
+
+
+public class ObjectStamp extends Stamp {
+
+    private final ResolvedJavaType type;
+    private final boolean exactType;
+    private final boolean nonNull;
+
+    public ObjectStamp(ResolvedJavaType type, boolean exactType, boolean nonNull) {
+        super(Kind.Object);
+        assert !exactType || type != null;
+        this.type = type;
+        this.exactType = exactType;
+        this.nonNull = nonNull;
+    }
+
+    @Override
+    public boolean nonNull() {
+        return nonNull;
+    }
+
+    public ResolvedJavaType type() {
+        return type;
+    }
+
+    public boolean isExactType() {
+        return exactType;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append(kind().typeChar);
+        str.append(nonNull ? "!" : "").append(exactType ? "#" : "").append(' ').append(type == null ? "-" : type.name());
+        return str.toString();
+    }
+
+    @Override
+    public boolean alwaysDistinct(Stamp otherStamp) {
+        ObjectStamp other = (ObjectStamp) otherStamp;
+        if (other.type == null || type == null) {
+            // We have no type information for one of the values.
+            return false;
+        } else if (other.nonNull || nonNull) {
+            // One of the two values cannot be null.
+            return !other.type.isInterface() && !type.isInterface() && !other.type.isSubtypeOf(type) && !type.isSubtypeOf(other.type);
+        }
+        return false;
+    }
+
+    @Override
+    public Stamp meet(Stamp otherStamp) {
+        ObjectStamp other = (ObjectStamp) otherStamp;
+        ResolvedJavaType orType = meetTypes(type(), other.type());
+        boolean meetExactType = orType == type && orType == other.type && exactType && other.exactType;
+        boolean meetNonNull = nonNull && other.nonNull;
+
+        if (orType == type && meetExactType == exactType && meetNonNull == nonNull) {
+            return this;
+        } else {
+            return new ObjectStamp(orType, meetExactType, meetNonNull);
+        }
+    }
+
+    private static ResolvedJavaType meetTypes(ResolvedJavaType a, ResolvedJavaType b) {
+        if (a == b) {
+            return a;
+        } else if (a == null || b == null) {
+            return null;
+        } else {
+            return a.leastCommonAncestor(b);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (exactType ? 1231 : 1237);
+        result = prime * result + (nonNull ? 1231 : 1237);
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        ObjectStamp other = (ObjectStamp) obj;
+        if (exactType != other.exactType || nonNull != other.nonNull) {
+            return false;
+        }
+        if (type == null) {
+            if (other.type != null) {
+                return false;
+            }
+        } else if (!type.equals(other.type)) {
+            return false;
+        }
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/Stamp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,18 +22,37 @@
  */
 package com.oracle.graal.nodes.type;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.types.*;
 
+/**
+ * A stamp is the basis for a type system over the nodes in a graph.
+ */
+public abstract class Stamp {
 
-public interface Stamp {
-    boolean nonNull();
-    RiResolvedType declaredType();
-    RiResolvedType exactType();
-    CiKind kind();
-    boolean alwaysDistinct(Stamp other);
+    private final Kind kind;
+
+    protected Stamp(Kind kind) {
+        this.kind = kind;
+    }
+
+    public Kind kind() {
+        return kind;
+    }
 
-    ScalarTypeQuery scalarType();
-    ObjectTypeQuery objectType();
+    public ScalarTypeQuery scalarType() {
+        return null;
+    }
+
+    public ObjectTypeQuery objectType() {
+        return null;
+    }
+
+    public boolean nonNull() {
+        return false;
+    }
+
+    public abstract boolean alwaysDistinct(Stamp other);
+
+    public abstract Stamp meet(Stamp other);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,269 +22,136 @@
  */
 package com.oracle.graal.nodes.type;
 
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.types.*;
+import com.oracle.graal.nodes.type.GenericStamp.GenericStampType;
 
 
 public class StampFactory {
 
-    private static class BasicValueStamp implements Stamp {
-
-        private final CiKind kind;
-        private final boolean nonNull;
-        private RiResolvedType declaredType;
-        private RiResolvedType exactType;
-        private final ScalarTypeQuery scalarType;
-        private final ObjectTypeQuery objectType;
-
-        public BasicValueStamp(CiKind kind) {
-            this(kind, false, null, null);
-        }
-
-        public BasicValueStamp(CiKind kind, boolean nonNull, RiResolvedType declaredType, RiResolvedType exactType) {
-            this(kind, nonNull, declaredType, exactType, null, null);
-        }
-
-        public BasicValueStamp(CiKind kind, boolean nonNull, RiResolvedType declaredType, RiResolvedType exactType, ScalarTypeQuery scalarType, ObjectTypeQuery objectType) {
-            this.kind = kind;
-            this.nonNull = nonNull;
-            this.declaredType = declaredType;
-            this.exactType = exactType;
-            this.scalarType = scalarType;
-            this.objectType = objectType;
-        }
-
-        @Override
-        public CiKind kind() {
-            return kind;
-        }
-
-        @Override
-        public boolean nonNull() {
-            return nonNull;
-        }
-
-        @Override
-        public RiResolvedType declaredType() {
-            return declaredType;
-        }
-
-        @Override
-        public RiResolvedType exactType() {
-            return exactType;
-        }
+    private static final Stamp[] stampCache = new Stamp[Kind.values().length];
+    private static final Stamp objectStamp = new ObjectStamp(null, false, false);
+    private static final Stamp objectNonNullStamp = new ObjectStamp(null, false, true);
+    private static final Stamp dependencyStamp = new GenericStamp(GenericStampType.Dependency);
+    private static final Stamp extensionStamp = new GenericStamp(GenericStampType.Extension);
+    private static final Stamp virtualStamp = new GenericStamp(GenericStampType.Virtual);
+    private static final Stamp conditionStamp = new GenericStamp(GenericStampType.Condition);
+    private static final Stamp voidStamp = new GenericStamp(GenericStampType.Void);
 
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == this) {
-                return true;
-            }
-            if (obj instanceof Stamp) {
-                Stamp other = (Stamp) obj;
-                return kind == other.kind() && nonNull() == other.nonNull() && declaredType() == other.declaredType() && exactType() == other.exactType();
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return kind.hashCode();
-        }
+    private static final Stamp positiveInt = forInteger(Kind.Int, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
 
-        @Override
-        public String toString() {
-            StringBuilder str = new StringBuilder();
-            str.append(kind().typeChar);
-            if (nonNull || declaredType != null || exactType != null) {
-                str.append(nonNull ? "!" : "").append(' ').append(declaredType == null ? "-" : declaredType.name()).append(' ').append(exactType == null ? "-" : exactType.name());
-            }
-            if (scalarType != null) {
-                str.append(' ').append(scalarType);
-            }
-            if (objectType != null) {
-                str.append(' ').append(objectType);
-            }
-            return str.toString();
-        }
-
-        @Override
-        public boolean alwaysDistinct(Stamp other) {
-            if (other.kind() != kind()) {
-                return true;
-            } else if (kind() != CiKind.Object) {
-                return false;
-            } else if (other.declaredType() == null || declaredType() == null) {
-                // We have no type information for one of the values.
-                return false;
-            } else if (other.nonNull() || nonNull()) {
-                // One of the two values cannot be null.
-                return !other.declaredType().isInterface() && !declaredType().isInterface() && !other.declaredType().isSubtypeOf(declaredType()) && !declaredType().isSubtypeOf(other.declaredType());
-            } else {
-                // Both values may be null.
-                return false;
-            }
-        }
-
-        @Override
-        public ScalarTypeQuery scalarType() {
-            return scalarType;
-        }
-
-        @Override
-        public ObjectTypeQuery objectType() {
-            return objectType;
-        }
+    private static void setCache(Kind kind, Stamp stamp) {
+        stampCache[kind.ordinal()] = stamp;
     }
 
-    private static final Stamp[] stampCache = new Stamp[CiKind.values().length];
     static {
-        for (CiKind k : CiKind.values()) {
-            stampCache[k.ordinal()] = new BasicValueStamp(k);
-        }
+        setCache(Kind.Boolean, new IntegerStamp(Kind.Boolean));
+        setCache(Kind.Byte, new IntegerStamp(Kind.Byte));
+        setCache(Kind.Short, new IntegerStamp(Kind.Short));
+        setCache(Kind.Char, new IntegerStamp(Kind.Char));
+        setCache(Kind.Int, new IntegerStamp(Kind.Int));
+        setCache(Kind.Long, new IntegerStamp(Kind.Long));
+
+        setCache(Kind.Float, new FloatStamp(Kind.Float));
+        setCache(Kind.Double, new FloatStamp(Kind.Double));
+
+        setCache(Kind.Jsr, new IntegerStamp(Kind.Jsr));
+
+        setCache(Kind.Object, objectStamp);
+        setCache(Kind.Void, voidStamp);
     }
 
-    public static Stamp illegal() {
-        return forKind(CiKind.Illegal);
+    public static Stamp forWord(Kind wordKind, boolean nonNull) {
+        return new WordStamp(wordKind, nonNull);
+    }
+
+    public static Stamp forKind(Kind kind) {
+        assert stampCache[kind.stackKind().ordinal()] != null : "unexpected forKind(" + kind + ")";
+        return stampCache[kind.stackKind().ordinal()];
+    }
+
+    public static Stamp forVoid() {
+        return voidStamp;
     }
 
     public static Stamp intValue() {
-        return forKind(CiKind.Int);
+        return forKind(Kind.Int);
     }
 
-    public static Stamp forKind(CiKind kind) {
-        return stampCache[kind.stackKind().ordinal()];
+    public static Stamp dependency() {
+        return dependencyStamp;
     }
 
-    public static Stamp forKind(CiKind kind, ScalarTypeQuery scalarTypeFeedback, ObjectTypeQuery objectTypeFeedback) {
-        if (scalarTypeFeedback == null && objectTypeFeedback == null) {
-            return forKind(kind);
-        } else {
-            return new BasicValueStamp(kind, false, null, null, scalarTypeFeedback, objectTypeFeedback);
-        }
+    public static Stamp extension() {
+        return extensionStamp;
     }
 
-    public static final Stamp positiveInt = forInt(0, Integer.MAX_VALUE);
+    public static Stamp virtual() {
+        return virtualStamp;
+    }
+
+    public static Stamp condition() {
+        return conditionStamp;
+    }
 
     public static Stamp positiveInt() {
         return positiveInt;
     }
 
-    public static Stamp forInt(int lowerBound, int upperBound) {
-        ScalarTypeFeedbackStore scalarType = new ScalarTypeFeedbackStore(CiKind.Int, new TypeFeedbackChanged());
-        scalarType.constantBound(Condition.GE, CiConstant.forInt(lowerBound));
-        scalarType.constantBound(Condition.LE, CiConstant.forInt(upperBound));
-
-        return new BasicValueStamp(CiKind.Int, false, null, null, scalarType.query(), null);
-    }
-
-    public static Stamp forLong(long lowerBound, long upperBound) {
-        ScalarTypeFeedbackStore scalarType = new ScalarTypeFeedbackStore(CiKind.Long, new TypeFeedbackChanged());
-        scalarType.constantBound(Condition.GE, CiConstant.forLong(lowerBound));
-        scalarType.constantBound(Condition.LE, CiConstant.forLong(upperBound));
-
-        return new BasicValueStamp(CiKind.Long, false, null, null, scalarType.query(), null);
+    public static Stamp forInteger(Kind kind, long lowerBound, long upperBound, long mask) {
+        return new IntegerStamp(kind, lowerBound, upperBound, mask);
     }
 
-    public static Stamp exactNonNull(final RiResolvedType type) {
-        // (cwimmer) type can be null for certain Maxine-internal objects such as the static hub. Is this a problem here?
-        assert type == null || type.kind(false) == CiKind.Object;
-        ObjectTypeFeedbackStore objectType = new ObjectTypeFeedbackStore(new TypeFeedbackChanged());
-        objectType.constantBound(Condition.NE, CiConstant.NULL_OBJECT);
-        objectType.exactType(type);
-        return new BasicValueStamp(CiKind.Object, true, type, type, null, objectType.query());
-    }
-
-    public static Stamp forConstant(CiConstant value) {
-        assert value.kind != CiKind.Object;
-        if (value.kind == CiKind.Object) {
+    public static Stamp forConstant(Constant value) {
+        assert value.kind != Kind.Object;
+        if (value.kind == Kind.Object) {
             throw new GraalInternalError("unexpected kind: %s", value.kind);
         } else {
-            if (value.kind == CiKind.Int) {
-                return forInt(value.asInt(), value.asInt());
-            } else if (value.kind == CiKind.Long) {
-                return forLong(value.asLong(), value.asLong());
+            if (value.kind == Kind.Int || value.kind == Kind.Long) {
+                return forInteger(value.kind, value.asLong(), value.asLong(), value.asLong() & IntegerStamp.defaultMask(value.kind));
             }
             return forKind(value.kind.stackKind());
         }
     }
 
-    public static Stamp forConstant(CiConstant value, RiRuntime runtime) {
-        assert value.kind == CiKind.Object;
-        if (value.kind == CiKind.Object) {
-            ObjectTypeFeedbackStore objectType = new ObjectTypeFeedbackStore(new TypeFeedbackChanged());
-            objectType.constantBound(Condition.EQ, value);
-            RiResolvedType type = value.isNull() ? null : runtime.getTypeOf(value);
-            return new BasicValueStamp(CiKind.Object, value.isNonNull(), type, type, null, objectType.query());
+    public static Stamp forConstant(Constant value, MetaAccessProvider runtime) {
+        assert value.kind == Kind.Object;
+        if (value.kind == Kind.Object) {
+            ResolvedJavaType type = value.isNull() ? null : runtime.getTypeOf(value);
+            return new ObjectStamp(type, value.isNonNull(), value.isNonNull());
         } else {
             throw new GraalInternalError("CiKind.Object expected, actual kind: %s", value.kind);
         }
     }
 
-    public static Stamp objectNonNull() {
-        return new BasicValueStamp(CiKind.Object, true, null, null);
+    public static Stamp object() {
+        return objectStamp;
     }
 
-    public static Stamp declared(final RiResolvedType type) {
-        assert type != null;
-        assert type.kind(false) == CiKind.Object;
-        return new BasicValueStamp(CiKind.Object, false, type, type.exactType());
+    public static Stamp objectNonNull() {
+        return objectNonNullStamp;
     }
 
-    public static Stamp declaredNonNull(final RiResolvedType type) {
-        assert type != null;
-        assert type.kind(false) == CiKind.Object;
-        return new BasicValueStamp(CiKind.Object, true, type, type.exactType());
+    public static Stamp declared(ResolvedJavaType type) {
+        return declared(type, false);
     }
 
-    public static Stamp or(Collection<? extends StampProvider> values) {
-        if (values.size() == 0) {
-            return illegal();
-        } else {
-            Iterator< ? extends StampProvider> iterator = values.iterator();
-            Stamp first = iterator.next().stamp();
-            if (values.size() == 1) {
-                return first;
-            }
+    public static Stamp declaredNonNull(ResolvedJavaType type) {
+        return declared(type, true);
+    }
 
-            boolean nonNull = first.nonNull();
-            RiResolvedType declaredType = first.declaredType();
-            RiResolvedType exactType = first.exactType();
-            while (iterator.hasNext()) {
-                Stamp current = iterator.next().stamp();
-                assert current.kind() == first.kind() : values + " first=" + first + " current=" + current + " first kind=" + first.kind() + " current kind=" + current.kind();
-                nonNull &= current.nonNull();
-                declaredType = orTypes(declaredType, current.declaredType());
-                if (exactType != current.exactType()) {
-                    exactType = null;
-                }
-            }
-
-            if (nonNull != first.nonNull() || declaredType != first.declaredType() || exactType != first.exactType()) {
-                return new BasicValueStamp(first.kind(), nonNull, declaredType, exactType);
-            } else {
-                return first;
-            }
+    public static Stamp declared(ResolvedJavaType type, boolean nonNull) {
+        assert type != null;
+        assert type.kind() == Kind.Object;
+        ResolvedJavaType exact = type.exactType();
+        if (exact != null) {
+            return new ObjectStamp(exact, true, nonNull);
+        } else {
+            return new ObjectStamp(type, false, nonNull);
         }
     }
 
-    private static RiResolvedType orTypes(RiResolvedType a, RiResolvedType b) {
-        if (a == b) {
-            return a;
-        } else if (a == null || b == null) {
-            return null;
-        } else {
-            if (a.isSubtypeOf(b)) {
-                return b;
-            } else if (b.isSubtypeOf(a)) {
-                return a;
-            } else {
-                return null;
-            }
-        }
+    public static Stamp exactNonNull(ResolvedJavaType type) {
+        return new ObjectStamp(type, true, true);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,168 @@
+/*
+ * 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.type;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Helper class that is used to keep all stamp-related operations in one place.
+ */
+// TODO(ls) maybe move the contents into IntegerStamp
+public class StampTool {
+
+    public static Stamp negate(Stamp stamp) {
+        Kind kind = stamp.kind();
+        if (stamp instanceof IntegerStamp) {
+            IntegerStamp integerStamp = (IntegerStamp) stamp;
+            if (integerStamp.lowerBound() != kind.minValue()) {
+                // TODO(ls) check if the mask calculation is correct...
+                return new IntegerStamp(kind, -integerStamp.upperBound(), -integerStamp.lowerBound(), IntegerStamp.defaultMask(kind) & (integerStamp.mask() | -integerStamp.mask()));
+            }
+        }
+        return StampFactory.forKind(kind);
+    }
+
+    public static Stamp meet(Collection<? extends StampProvider> values) {
+        Iterator< ? extends StampProvider> iterator = values.iterator();
+        if (iterator.hasNext()) {
+            Stamp stamp = iterator.next().stamp();
+            while (iterator.hasNext()) {
+                stamp = stamp.meet(iterator.next().stamp());
+            }
+            return stamp;
+        } else {
+            return StampFactory.forVoid();
+        }
+    }
+
+    public static Stamp add(IntegerStamp stamp1, IntegerStamp stamp2) {
+        Kind kind = stamp1.kind();
+        assert kind == stamp2.kind();
+        if (addOverflow(stamp1.lowerBound(), stamp2.lowerBound(), kind)) {
+            return StampFactory.forKind(kind);
+        }
+        if (addOverflow(stamp1.upperBound(), stamp2.upperBound(), kind)) {
+            return StampFactory.forKind(kind);
+        }
+        long lowerBound = stamp1.lowerBound() + stamp2.lowerBound();
+        long upperBound = stamp1.upperBound() + stamp2.upperBound();
+        long mask = IntegerStamp.maskFor(kind, lowerBound, upperBound) & (stamp1.mask() | stamp2.mask());
+
+        return StampFactory.forInteger(kind, lowerBound, upperBound, mask);
+    }
+
+    public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {
+        return add(stamp1, (IntegerStamp) StampTool.negate(stamp2));
+    }
+
+    public static Stamp div(IntegerStamp stamp1, IntegerStamp stamp2) {
+        Kind kind = stamp1.kind();
+        if (stamp2.lowerBound() > 0) {
+            long lowerBound = stamp1.lowerBound() / stamp2.lowerBound();
+            long upperBound = stamp1.upperBound() / stamp2.lowerBound();
+            return StampFactory.forInteger(kind, lowerBound, upperBound, IntegerStamp.maskFor(kind, lowerBound, upperBound));
+        }
+        return StampFactory.forKind(kind);
+    }
+
+    private static boolean addOverflow(long x, long y, Kind kind) {
+        long result = x + y;
+        if (kind == Kind.Long) {
+            return ((x ^ result) & (y ^ result)) < 0;
+        } else {
+            assert kind == Kind.Int;
+            return result > Integer.MAX_VALUE || result < Integer.MIN_VALUE;
+        }
+    }
+
+    private static final long INTEGER_SIGN_BIT = 0x80000000L;
+    private static final long LONG_SIGN_BIT = 0x8000000000000000L;
+
+    private static Stamp stampForMask(Kind kind, long mask) {
+        long lowerBound;
+        long upperBound;
+        if (kind == Kind.Int && (mask & INTEGER_SIGN_BIT) != 0) {
+            // the mask is negative
+            lowerBound = Integer.MIN_VALUE;
+            upperBound = mask ^ INTEGER_SIGN_BIT;
+        } else if (kind == Kind.Long && (mask & LONG_SIGN_BIT) != 0) {
+            // the mask is negative
+            lowerBound = Long.MIN_VALUE;
+            upperBound = mask ^ LONG_SIGN_BIT;
+        } else {
+            lowerBound = 0;
+            upperBound = mask;
+        }
+        return StampFactory.forInteger(kind, lowerBound, upperBound, mask);
+    }
+
+    public static Stamp and(IntegerStamp stamp1, IntegerStamp stamp2) {
+        Kind kind = stamp1.kind();
+        long mask = stamp1.mask() & stamp2.mask();
+        return stampForMask(kind, mask);
+    }
+
+    public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) {
+        Kind kind = stamp1.kind();
+        long mask = stamp1.mask() | stamp2.mask();
+        return stampForMask(kind, mask);
+    }
+
+    public static Stamp unsignedRightShift(IntegerStamp value, IntegerStamp shift) {
+        Kind kind = value.kind();
+        if (shift.lowerBound() == shift.upperBound()) {
+            long shiftMask = kind == Kind.Int ? 0x1FL : 0x3FL;
+            long shiftCount = shift.lowerBound() & shiftMask;
+            long lowerBound;
+            long upperBound;
+            if (value.lowerBound() < 0) {
+                lowerBound = 0;
+                upperBound = IntegerStamp.defaultMask(kind) >>> shiftCount;
+            } else {
+                lowerBound = value.lowerBound() >>> shiftCount;
+                upperBound = value.upperBound() >>> shiftCount;
+            }
+            long mask = value.mask() >>> shiftCount;
+            return StampFactory.forInteger(kind, lowerBound, upperBound, mask);
+        }
+        long mask = IntegerStamp.maskFor(kind, value.lowerBound(), value.upperBound());
+        return stampForMask(kind, mask);
+    }
+
+    public static Stamp leftShift(IntegerStamp value, IntegerStamp shift) {
+        Kind kind = value.kind();
+        int shiftBits = kind == Kind.Int ? 5 : 6;
+        long shiftMask = kind == Kind.Int ? 0x1FL : 0x3FL;
+        if ((shift.lowerBound() >>> shiftBits) == (shift.upperBound() >>> shiftBits)) {
+            long mask = 0;
+            for (long i = shift.lowerBound() & shiftMask; i <= (shift.upperBound() & shiftMask); i++) {
+                mask |= value.mask() << i;
+            }
+            mask &= IntegerStamp.defaultMask(kind);
+            return stampForMask(kind, mask);
+        }
+        return StampFactory.forKind(kind);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/WordStamp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,89 @@
+/*
+ * 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.type;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Models the word type.
+ */
+public class WordStamp extends Stamp {
+
+    private final boolean nonNull;
+
+    public WordStamp(Kind wordKind, boolean nonNull) {
+        super(wordKind);
+        this.nonNull = nonNull;
+    }
+
+    @Override
+    public boolean nonNull() {
+        return nonNull;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append(kind().typeChar);
+        str.append(nonNull ? "!" : "");
+        return str.toString();
+    }
+
+    @Override
+    public boolean alwaysDistinct(Stamp otherStamp) {
+        return false;
+    }
+
+    @Override
+    public Stamp meet(Stamp otherStamp) {
+        WordStamp other = (WordStamp) otherStamp;
+        if (other.nonNull == nonNull) {
+            return this;
+        } else {
+            return new WordStamp(kind(), nonNull && other.nonNull);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (nonNull ? 1231 : 1237);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        WordStamp other = (WordStamp) obj;
+        if (nonNull != other.nonNull) {
+            return false;
+        }
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,14 +26,18 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.iterators.NodePredicates.PositiveTypePredicate;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.nodes.java.*;
 
 public class GraphUtil {
 
+    private static final PositiveTypePredicate FLOATING = isA(FloatingNode.class).or(VirtualState.class).or(CallTargetNode.class);
+
     public static void killCFG(FixedNode node) {
         assert node.isAlive();
         if (node instanceof EndNode) {
@@ -43,7 +47,7 @@
         } else {
             // Normal control flow node.
             /* We do not take a successor snapshot because this iterator supports concurrent modifications
-             * as long as they do not change the size of the successor list. Not tasking a snapshot allows
+             * as long as they do not change the size of the successor list. Not taking a snapshot allows
              * us to see modifications to other branches that may happen while processing one branch.
              */
             for (Node successor : node.successors()) {
@@ -55,35 +59,37 @@
 
     private static void killEnd(EndNode end) {
         MergeNode merge = end.merge();
-        merge.removeEnd(end);
-        StructuredGraph graph = (StructuredGraph) end.graph();
-        if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) { //dead loop
-            for (PhiNode phi : merge.phis().snapshot()) {
-                propagateKill(phi);
-            }
-            LoopBeginNode begin = (LoopBeginNode) merge;
-            // disconnect and delete loop ends & loop exits
-            for (LoopEndNode loopend : begin.loopEnds().snapshot()) {
-                loopend.predecessor().replaceFirstSuccessor(loopend, null);
-                loopend.safeDelete();
+        if (merge != null) {
+            merge.removeEnd(end);
+            StructuredGraph graph = (StructuredGraph) end.graph();
+            if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) { //dead loop
+                for (PhiNode phi : merge.phis().snapshot()) {
+                    propagateKill(phi);
+                }
+                LoopBeginNode begin = (LoopBeginNode) merge;
+                // disconnect and delete loop ends & loop exits
+                for (LoopEndNode loopend : begin.loopEnds().snapshot()) {
+                    loopend.predecessor().replaceFirstSuccessor(loopend, null);
+                    loopend.safeDelete();
+                }
+                for (LoopExitNode loopexit : begin.loopExits().snapshot()) {
+                    for (ValueProxyNode vpn : loopexit.proxies().snapshot()) {
+                        graph.replaceFloating(vpn, vpn.value());
+                    }
+                    graph.replaceFixedWithFixed(loopexit, graph.add(new BeginNode()));
+                }
+                killCFG(begin.next());
+                begin.safeDelete();
+            } else if (merge instanceof LoopBeginNode && ((LoopBeginNode) merge).loopEnds().isEmpty()) { // not a loop anymore
+                graph.reduceDegenerateLoopBegin((LoopBeginNode) merge);
+            } else if (merge.phiPredecessorCount() == 1) { // not a merge anymore
+                graph.reduceTrivialMerge(merge);
             }
-            for (LoopExitNode loopexit : begin.loopExits().snapshot()) {
-                for (ValueProxyNode vpn : loopexit.proxies().snapshot()) {
-                    graph.replaceFloating(vpn, vpn.value());
-                }
-                graph.replaceFixedWithFixed(loopexit, graph.add(new BeginNode()));
-            }
-            killCFG(begin.next());
-            begin.safeDelete();
-        } else if (merge instanceof LoopBeginNode && ((LoopBeginNode) merge).loopEnds().isEmpty()) { // not a loop anymore
-            graph.reduceDegenerateLoopBegin((LoopBeginNode) merge);
-        } else if (merge.phiPredecessorCount() == 1) { // not a merge anymore
-            graph.reduceTrivialMerge(merge);
         }
     }
 
     public static NodePredicate isFloatingNode() {
-        return isA(FloatingNode.class).or(CallTargetNode.class).or(FrameState.class).or(VirtualObjectFieldNode.class).or(VirtualObjectNode.class);
+        return FLOATING;
     }
 
     public static void propagateKill(Node node) {
@@ -92,8 +98,8 @@
 
             // null out remaining usages
             node.replaceAtUsages(null);
-            node.replaceAtPredecessors(null);
-            killUnusedFloatingInputs(node);
+            node.replaceAtPredecessor(null);
+            killWithUnusedFloatingInputs(node);
 
             for (Node usage : usagesSnapshot) {
                 if (!usage.isDeleted()) {
@@ -107,13 +113,13 @@
         }
     }
 
-    public static void killUnusedFloatingInputs(Node node) {
+    public static void killWithUnusedFloatingInputs(Node node) {
         List<Node> floatingInputs = node.inputs().filter(isFloatingNode()).snapshot();
         node.safeDelete();
 
         for (Node in : floatingInputs) {
             if (in.isAlive() && in.usages().isEmpty()) {
-                killUnusedFloatingInputs(in);
+                killWithUnusedFloatingInputs(in);
             }
         }
     }
@@ -176,6 +182,36 @@
         }
     }
 
+    /**
+     * Gets an approximate source code location for a node if possible.
+     *
+     * @return a file name and source line number in stack trace format (e.g. "String.java:32")
+     *          if an approximate source location is found, null otherwise
+     */
+    public static String approxSourceLocation(Node node) {
+        Node n = node;
+        while (n != null) {
+            if (n instanceof MethodCallTargetNode) {
+                n = ((MethodCallTargetNode) n).invoke().node();
+            }
+
+            if (n instanceof StateSplit) {
+                FrameState stateAfter = ((StateSplit) n).stateAfter();
+                if (stateAfter != null) {
+                    ResolvedJavaMethod method = stateAfter.method();
+                    if (method != null) {
+                        StackTraceElement stackTraceElement = method.toStackTraceElement(stateAfter.bci);
+                        if (stackTraceElement.getFileName() != null && stackTraceElement.getLineNumber() >= 0) {
+                            return stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber();
+                        }
+                    }
+                }
+            }
+            n = n.predecessor();
+        }
+        return null;
+    }
+
     public static ValueNode unProxify(ValueNode proxy) {
         ValueNode v = proxy;
         while (v instanceof ValueProxyNode) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.virtual;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -32,7 +32,7 @@
 
     @Input ValueNode unboxedValue;
 
-    public BoxedVirtualObjectNode(RiResolvedType type, ValueNode unboxedValue) {
+    public BoxedVirtualObjectNode(ResolvedJavaType type, ValueNode unboxedValue) {
         super(type, 1);
         this.unboxedValue = unboxedValue;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectFieldNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2011, 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.virtual;
-
-import java.util.*;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public class VirtualObjectFieldNode extends ValueNode implements LIRLowerable {
-
-    @Input private VirtualObjectNode object;
-    @Input private ValueNode lastState;
-    @Input private ValueNode input;
-
-    private int index;
-
-    public VirtualObjectNode object() {
-        return object;
-    }
-
-    public ValueNode lastState() {
-        return lastState;
-    }
-
-    public ValueNode input() {
-        return input;
-    }
-
-    public VirtualObjectFieldNode(VirtualObjectNode object, ValueNode lastState, ValueNode input, int index) {
-        super(StampFactory.illegal());
-        this.index = index;
-        this.object = object;
-        this.lastState = lastState;
-        this.input = input;
-    }
-
-    public int index() {
-        return index;
-    }
-
-    @Override
-    public void generate(LIRGeneratorTool gen) {
-        // nothing to do...
-    }
-
-    @Override
-    public boolean verify() {
-        assertTrue(object != null, "No object");
-        assertTrue(input != null, "No input");
-        return super.verify();
-    }
-
-    @Override
-    public Map<Object, Object> getDebugProperties() {
-        Map<Object, Object> properties = super.getDebugProperties();
-        properties.put("index", index);
-        return properties;
-    }
-
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name && object() != null && object().fields() != null) {
-            return super.toString(Verbosity.Name) + " " + object().fields()[index].name();
-        } else {
-            return super.toString(verbosity);
-        }
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,32 +22,31 @@
  */
 package com.oracle.graal.nodes.virtual;
 
-import com.oracle.graal.nodes.*;
+import com.oracle.graal.api.meta.*;
+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 class VirtualObjectNode extends ValueNode implements LIRLowerable {
+public class VirtualObjectNode extends FloatingNode implements LIRLowerable {
 
-    private RiResolvedType type;
+    private ResolvedJavaType type;
     private EscapeField[] fields;
     private int fieldsCount;
 
-    public VirtualObjectNode(RiResolvedType type, EscapeField[] fields) {
-        super(StampFactory.illegal());
+    public VirtualObjectNode(ResolvedJavaType type, EscapeField[] fields) {
+        super(StampFactory.virtual());
         this.type = type;
         this.fields = fields;
         this.fieldsCount = fields.length;
     }
 
-    public VirtualObjectNode(RiResolvedType type, int fieldCount) {
-        super(StampFactory.illegal());
+    public VirtualObjectNode(ResolvedJavaType type, int fieldCount) {
+        super(StampFactory.virtual());
         this.type = type;
         this.fieldsCount = fieldCount;
     }
 
-    public RiType type() {
+    public JavaType type() {
         return type;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectState.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009, 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.virtual;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * This class encapsulated the virtual state of an escape analyzed object.
+ */
+public final class VirtualObjectState extends VirtualState implements Node.IterableNodeType, LIRLowerable {
+
+    @Input private VirtualObjectNode object;
+    @Input private NodeInputList<ValueNode> fieldValues;
+
+    public VirtualObjectNode object() {
+        return object;
+    }
+
+    public NodeInputList<ValueNode> fieldValues() {
+        return fieldValues;
+    }
+
+    public VirtualObjectState(VirtualObjectNode object, ValueNode[] fieldValues) {
+        assert object.fieldsCount() == fieldValues.length;
+        this.object = object;
+        this.fieldValues = new NodeInputList<>(this, fieldValues);
+    }
+
+    private VirtualObjectState(VirtualObjectNode object, List<ValueNode> fieldValues) {
+        assert object.fieldsCount() == fieldValues.size();
+        this.object = object;
+        this.fieldValues = new NodeInputList<>(this, fieldValues);
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        // Nothing to do, virtual object states are processed as part of the handling of StateSplit nodes.
+    }
+
+    @Override
+    public VirtualObjectState duplicateWithVirtualState() {
+        return graph().add(new VirtualObjectState(object, fieldValues));
+    }
+
+    @Override
+    public void applyToNonVirtual(NodeClosure< ? super ValueNode> closure) {
+        for (ValueNode value : fieldValues) {
+            closure.apply(this, value);
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/util/NodeIterators.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/util/NodeIterators.java	Wed Jun 27 17:35:32 2012 +0200
@@ -30,7 +30,7 @@
 public class NodeIterators {
 
     public static NodeIterable<FixedNode> dominators(final FixedNode n) {
-        return new NodeIterable<FixedNode>() {
+        return new AbstractNodeIterable<FixedNode>() {
             @Override
             public Iterator<FixedNode> iterator() {
                 return new NodeIterator<FixedNode>(){
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,15 @@
  */
 package com.oracle.graal.printer;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.io.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
 import com.oracle.graal.alloc.util.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.alloc.Interval.UsePosList;
 import com.oracle.graal.compiler.gen.*;
@@ -48,7 +49,7 @@
  */
 class CFGPrinter extends CompilationPrinter {
 
-    protected CiTarget target;
+    protected TargetDescription target;
     protected LIR lir;
     protected LIRGenerator lirGenerator;
     protected ControlFlowGraph cfg;
@@ -307,7 +308,7 @@
         out.print("tid ").print(nodeToString(node)).println(COLUMN_END);
 
         if (lirGenerator != null) {
-            CiValue operand = lirGenerator.nodeOperands.get(node);
+            Value operand = lirGenerator.nodeOperands.get(node);
             if (operand != null) {
                 out.print("result ").print(operand.toString()).println(COLUMN_END);
             }
@@ -381,7 +382,7 @@
         StringBuilder buf = new StringBuilder();
         FrameState curState = state;
         do {
-            buf.append(CiUtil.toLocation(curState.method(), curState.bci)).append('\n');
+            buf.append(CodeUtil.toLocation(curState.method(), curState.bci)).append('\n');
 
             if (curState.stackSize() > 0) {
                 buf.append("stack: ");
@@ -406,7 +407,7 @@
     private String stateValueToString(ValueNode value) {
         String result = nodeToString(value);
         if (lirGenerator != null && lirGenerator.nodeOperands != null && value != null) {
-            CiValue operand = lirGenerator.nodeOperands.get(value);
+            Value operand = lirGenerator.nodeOperands.get(value);
             if (operand != null) {
                 result += ": " + operand;
             }
@@ -437,7 +438,7 @@
                 out.adjustIndentation(-level);
                 String state;
                 if (inst.info.hasDebugInfo()) {
-                    state = debugInfoToString(inst.info.debugInfo().codePos, inst.info.debugInfo().registerRefMap, inst.info.debugInfo().frameRefMap, target.arch);
+                    state = debugInfoToString(inst.info.debugInfo().getBytecodePosition(), inst.info.debugInfo().getRegisterRefMap(), inst.info.debugInfo().getFrameRefMap(), target.arch);
                 } else {
                     state = debugInfoToString(inst.info.topFrame, null, null, target.arch);
                 }
@@ -462,7 +463,7 @@
             prefix = "B";
         } else if (node instanceof ValueNode) {
             ValueNode value = (ValueNode) node;
-            if (value.kind() == CiKind.Illegal) {
+            if (value.kind() == Kind.Illegal) {
                 prefix = "v";
             } else {
                 prefix = String.valueOf(value.kind().typeChar);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,10 +25,9 @@
 import java.io.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.criutils.*;
 import com.oracle.graal.alloc.util.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.gen.*;
@@ -38,6 +37,7 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.max.criutils.*;
 
 /**
  * Observes compilation events and uses {@link CFGPrinter} to produce a control flow graph for the <a
@@ -46,7 +46,8 @@
 public class CFGPrinterObserver implements DebugDumpHandler {
 
     private CFGPrinter cfgPrinter;
-    private RiResolvedMethod curMethod;
+    private ResolvedJavaMethod curMethod;
+    private List<String> curDecorators = Collections.emptyList();
 
     @Override
     public void dump(Object object, String message) {
@@ -57,14 +58,37 @@
         }
     }
 
-    private static RiResolvedMethod lookupMethod() {
-        RiResolvedMethod method = Debug.contextLookup(RiResolvedMethod.class);
-        if (method != null) {
-            return method;
+    /**
+     * Looks for the outer most method and its {@link DebugDumpScope#decorator}s
+     * in the current debug scope and opens a new compilation scope if this pair
+     * does not match the current method and decorator pair.
+     */
+    private void checkMethodScope() {
+        ResolvedJavaMethod method = null;
+        ArrayList<String> decorators = new ArrayList<>();
+        for (Object o : Debug.context()) {
+            if (o instanceof ResolvedJavaMethod) {
+                method = (ResolvedJavaMethod) o;
+                decorators.clear();
+            } else if (o instanceof StructuredGraph) {
+                StructuredGraph graph = (StructuredGraph) o;
+                assert graph != null && graph.method() != null : "cannot find method context for CFG dump";
+                method = graph.method();
+                decorators.clear();
+            } else if (o instanceof DebugDumpScope) {
+                DebugDumpScope debugDumpScope = (DebugDumpScope) o;
+                if (debugDumpScope.decorator) {
+                    decorators.add(debugDumpScope.name);
+                }
+            }
         }
-        StructuredGraph graph = Debug.contextLookup(StructuredGraph.class);
-        assert graph != null && graph.method() != null : "cannot find method context for CFG dump";
-        return graph.method();
+
+        if (method != curMethod || !curDecorators.equals(decorators)) {
+            cfgPrinter.printCompilation(method);
+            TTY.println("CFGPrinter: Dumping method %s", method);
+            curMethod = method;
+            curDecorators = decorators;
+        }
     }
 
     public void dumpSandboxed(Object object, String message) {
@@ -84,13 +108,7 @@
             TTY.println("CFGPrinter: Output to file %s", file);
         }
 
-        RiResolvedMethod newMethod = lookupMethod();
-
-        if (newMethod != curMethod) {
-            cfgPrinter.printCompilation(newMethod);
-            TTY.println("CFGPrinter: Dumping method %s", newMethod);
-            curMethod = newMethod;
-        }
+        checkMethodScope();
 
         cfgPrinter.target = compiler.target;
         if (object instanceof LIR) {
@@ -103,7 +121,7 @@
             cfgPrinter.cfg = cfgPrinter.lir.cfg;
         }
 
-        RiRuntime runtime = compiler.runtime;
+        CodeCacheProvider runtime = compiler.runtime;
 
         if (object instanceof BciBlockMapping) {
             BciBlockMapping blockMap = (BciBlockMapping) object;
@@ -119,26 +137,24 @@
             }
             cfgPrinter.printCFG(message, Arrays.asList(cfgPrinter.cfg.getBlocks()));
 
-        } else if (object instanceof CiTargetMethod) {
-            final CiTargetMethod tm = (CiTargetMethod) object;
+        } else if (object instanceof CompilationResult) {
+            final CompilationResult tm = (CompilationResult) object;
             final byte[] code = Arrays.copyOf(tm.targetCode(), tm.targetCodeSize());
-            RiCodeInfo info = new RiCodeInfo() {
-                public CiTargetMethod targetMethod() {
-                    return tm;
+            CodeInfo info = new CodeInfo() {
+                public ResolvedJavaMethod method() {
+                    return null;
                 }
                 public long start() {
                     return 0L;
                 }
-                public RiResolvedMethod method() {
-                    return null;
-                }
                 public byte[] code() {
                     return code;
                 }
             };
-            cfgPrinter.printMachineCode(runtime.disassemble(info), message);
-        } else if (object instanceof RiCodeInfo) {
-            cfgPrinter.printMachineCode(runtime.disassemble((RiCodeInfo) object), message);
+            cfgPrinter.printMachineCode(runtime.disassemble(info, tm), message);
+        } else if (isCompilationResultAndCodeInfo(object)) {
+            Object[] tuple = (Object[]) object;
+            cfgPrinter.printMachineCode(runtime.disassemble((CodeInfo) tuple[1], (CompilationResult) tuple[0]), message);
         } else if (object instanceof Interval[]) {
             cfgPrinter.printIntervals(message, (Interval[]) object);
 
@@ -152,4 +168,14 @@
         cfgPrinter.cfg = null;
         cfgPrinter.flush();
     }
+
+    private static boolean isCompilationResultAndCodeInfo(Object object) {
+        if (object instanceof Object[]) {
+            Object[] tuple = (Object[]) object;
+            if (tuple.length == 2 && tuple[0] instanceof CompilationResult && tuple[1] instanceof CodeInfo) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,13 +26,13 @@
 import java.util.*;
 import java.util.Map.Entry;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.bytecode.*;
 import com.oracle.graal.compiler.schedule.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.graal.graph.NodeClass.Position;
-import com.oracle.graal.java.bytecode.*;
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 
@@ -51,7 +51,7 @@
     /**
      * Starts a new group of graphs with the given name, short name and method byte code index (BCI) as properties.
      */
-    public void beginGroup(String name, String shortName, RiResolvedMethod method, int bci) {
+    public void beginGroup(String name, String shortName, ResolvedJavaMethod method, int bci) {
         beginGroup();
         beginProperties();
         printProperty("name", name);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinterDumpHandler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinterDumpHandler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,9 +26,9 @@
 import java.net.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 
@@ -123,7 +123,7 @@
                 for (int i = 0; i < inlineContext.size(); ++i) {
                     if (i >= previousInlineContext.size() || !inlineContext.get(i).equals(previousInlineContext.get(i))) {
                         for (int j = i; j < inlineContext.size(); ++j) {
-                            openScope(inlineContext.get(j));
+                            openScope(inlineContext.get(j), j == 0);
                         }
                         break;
                     }
@@ -148,19 +148,24 @@
     private static List<String> getInlineContext() {
         List<String> result = new ArrayList<>();
         for (Object o : Debug.context()) {
-            if (o instanceof RiResolvedMethod) {
-                RiResolvedMethod method = (RiResolvedMethod) o;
-                result.add(CiUtil.format("%H::%n(%p)", method));
+            if (o instanceof ResolvedJavaMethod) {
+                ResolvedJavaMethod method = (ResolvedJavaMethod) o;
+                result.add(CodeUtil.format("%H::%n(%p)", method));
             } else if (o instanceof DebugDumpScope) {
                 DebugDumpScope debugDumpScope = (DebugDumpScope) o;
-                result.add(debugDumpScope.getName());
+                if (debugDumpScope.decorator && !result.isEmpty()) {
+                    result.set(result.size() - 1, debugDumpScope.name + ":" + result.get(result.size() - 1));
+                } else {
+                    result.add(debugDumpScope.name);
+                }
             }
         }
         return result;
     }
 
-    private void openScope(String name) {
-        printer.beginGroup(name, name, Debug.contextLookup(RiResolvedMethod.class), -1);
+    private void openScope(String name, boolean showThread) {
+        String prefix = showThread ? Thread.currentThread().getName() + ":" : "";
+        printer.beginGroup(prefix + name, name, Debug.contextLookup(ResolvedJavaMethod.class), -1);
     }
 
     private void closeScope() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/WordTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2011, 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.snippets;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.tests.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.snippets.Snippet.InliningPolicy;
+
+/**
+ * Tests for the {@link Word} type.
+ */
+public class WordTest extends GraalCompilerTest implements SnippetsInterface {
+
+    private final SnippetInstaller installer;
+
+    public WordTest() {
+        TargetDescription target = Graal.getRequiredCapability(GraalCompiler.class).target;
+        installer = new SnippetInstaller(runtime, target);
+    }
+
+    private static final ThreadLocal<InliningPolicy> inliningPolicy = new ThreadLocal<>();
+
+    @Override
+    protected StructuredGraph parse(Method m) {
+        ResolvedJavaMethod resolvedMethod = runtime.getResolvedJavaMethod(m);
+        return installer.makeGraph(resolvedMethod, inliningPolicy.get());
+    }
+
+    @Test
+    public void test_arithmetic() {
+        long[] words = new long[] {Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE};
+        for (long word : words) {
+            for (int addend = -1000; addend < 1000; addend++) {
+                test("plus_int", word, addend);
+                test("plus_int", word, -addend);
+                test("minus_int", word, addend);
+                test("minus_int", word, -addend);
+            }
+            for (long addend : words) {
+                test("plus_int", word, (int) addend);
+                test("minus_int", word, (int) addend);
+                test("plus_int", word, -((int) addend));
+                test("minus_int", word, -((int) addend));
+            }
+        }
+    }
+
+    @Test
+    public void test_compare() {
+        long[] words = new long[] {Long.MIN_VALUE, Long.MIN_VALUE + 1, -1L, 0L, 1L, Long.MAX_VALUE - 1, Long.MAX_VALUE};
+        for (long word1 : words) {
+            for (long word2 : words) {
+                for (String method : new String[] {"aboveOrEqual", "above", "belowOrEqual", "below"}) {
+                    test(method, word1, word2);
+                    test(method, word2, word1);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void test_fromObject() {
+        inliningPolicy.set(new InliningPolicy() {
+            public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
+                return InliningPolicy.Default.shouldInline(method, caller) && !method.name().equals("hashCode");
+            }
+        });
+        test("fromToObject", "object1", "object2");
+        test("fromToObject", "object1", "object1");
+        test("fromToObject", "object", null);
+        test("fromToObject", null, "object");
+        test("fromToObject", null, null);
+        inliningPolicy.set(null);
+    }
+
+    @Snippet
+    public static long plus_int(long word, int addend) {
+        return Word.fromLong(word).plus(addend).toLong();
+    }
+
+    @Snippet
+    public static long minus_int(long word, int addend) {
+        return Word.fromLong(word).plus(addend).toLong();
+    }
+
+    @Snippet
+    public static boolean aboveOrEqual(long word1, long word2) {
+        return Word.fromLong(word1).aboveOrEqual(Word.fromLong(word2));
+    }
+
+    @Snippet
+    public static boolean above(long word1, long word2) {
+        return Word.fromLong(word1).above(Word.fromLong(word2));
+    }
+
+    @Snippet
+    public static boolean belowOrEqual(long word1, long word2) {
+        return Word.fromLong(word1).belowOrEqual(Word.fromLong(word2));
+    }
+
+    @Snippet
+    public static boolean below(long word1, long word2) {
+        return Word.fromLong(word1).below(Word.fromLong(word2));
+    }
+
+    @Snippet
+    public static int fromToObject(Object o1, Object o2) {
+        return Word.fromObject(o1).toObject().hashCode() + Word.fromObject(o2).toObject().hashCode();
+    }
+}
+
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/DoubleSnippets.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/DoubleSnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.snippets;
 
-import com.oracle.max.cri.util.*;
 import com.oracle.graal.nodes.calc.*;
 
 /**
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/FloatSnippets.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/FloatSnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.snippets;
 
-import com.oracle.max.cri.util.*;
 import com.oracle.graal.nodes.calc.*;
 
 /**
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/GraalIntrinsics.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,19 +23,17 @@
 package com.oracle.graal.snippets;
 
 import com.oracle.graal.compiler.*;
-import com.oracle.graal.cri.*;
-import com.oracle.max.cri.ci.*;
 
 /**
  * Definition of the snippets that are VM-independent and can be intrinsified by Graal in any VM.
  */
 public class GraalIntrinsics {
-    public static void installIntrinsics(GraalRuntime runtime, CiTarget target) {
+    public static void installIntrinsics(SnippetInstaller installer) {
         if (GraalOptions.Intrinsify) {
-            Snippets.install(runtime, target, new MathSnippetsX86());
-            Snippets.install(runtime, target, new DoubleSnippets());
-            Snippets.install(runtime, target, new FloatSnippets());
-            Snippets.install(runtime, target, new NodeClassSnippets());
+            installer.install(MathSnippetsX86.class);
+            installer.install(DoubleSnippets.class);
+            installer.install(FloatSnippets.class);
+            installer.install(NodeClassSnippets.class);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/JavacBug.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, 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.snippets;
+
+/**
+ * Used to indicate that an otherwise strange looking code pattern is required to work around a bug in javac.
+ */
+public @interface JavacBug {
+    /**
+     * A description of the bug. Only really useful if there is no existing entry for the bug in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
+     */
+    String value() default "";
+
+    /**
+     * An identifier in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
+     */
+    int id() default 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Log.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,163 @@
+/*
+ * 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.snippets;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.extended.*;
+
+/**
+ * Provides printf-like debug facility. This should only be used in {@linkplain Snippet snippets}.
+ */
+public final class Log {
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic(RuntimeCallNode.class)
+    private static void log(@ConstantNodeParameter RuntimeCall logObject, Object object, boolean newline, boolean string) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic(RuntimeCallNode.class)
+    private static void log(@ConstantNodeParameter RuntimeCall logPrimitive, int typeChar, long value, boolean newline) {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+
+    public static void print(boolean value) {
+        log(RuntimeCall.LogPrimitive, Kind.Boolean.typeChar, value ? 1L : 0L, false);
+    }
+
+    public static void print(byte value) {
+        log(RuntimeCall.LogPrimitive, Kind.Byte.typeChar, value, false);
+    }
+
+    public static void print(char value) {
+        log(RuntimeCall.LogPrimitive, Kind.Char.typeChar, value, false);
+    }
+
+    public static void print(short value) {
+        log(RuntimeCall.LogPrimitive, Kind.Short.typeChar, value, false);
+    }
+
+    public static void print(int value) {
+        log(RuntimeCall.LogPrimitive, Kind.Int.typeChar, value, false);
+    }
+
+    public static void print(long value) {
+        log(RuntimeCall.LogPrimitive, Kind.Long.typeChar, value, false);
+    }
+
+    public static void print(float value) {
+        if (Float.isNaN(value)) {
+            print("NaN");
+        } else if (value == Float.POSITIVE_INFINITY) {
+            print("Infinity");
+        } else if (value == Float.NEGATIVE_INFINITY) {
+            print("-Infinity");
+        } else {
+            log(RuntimeCall.LogPrimitive, Kind.Float.typeChar, Float.floatToRawIntBits(value), false);
+        }
+    }
+
+    public static void print(double value) {
+        if (Double.isNaN(value)) {
+            print("NaN");
+        } else if (value == Double.POSITIVE_INFINITY) {
+            print("Infinity");
+        } else if (value == Double.NEGATIVE_INFINITY) {
+            print("-Infinity");
+        } else {
+            log(RuntimeCall.LogPrimitive, Kind.Double.typeChar, Double.doubleToRawLongBits(value), false);
+        }
+    }
+
+    public static void print(String value) {
+        log(RuntimeCall.LogObject, value, false, true);
+    }
+
+    public static void printAddress(Object o) {
+        log(RuntimeCall.LogObject, o, false, false);
+    }
+
+    public static void println(boolean value) {
+        log(RuntimeCall.LogPrimitive, Kind.Boolean.typeChar, value ? 1L : 0L, true);
+    }
+
+    public static void println(byte value) {
+        log(RuntimeCall.LogPrimitive, Kind.Byte.typeChar, value, true);
+    }
+
+    public static void println(char value) {
+        log(RuntimeCall.LogPrimitive, Kind.Char.typeChar, value, true);
+    }
+
+    public static void println(short value) {
+        log(RuntimeCall.LogPrimitive, Kind.Short.typeChar, value, true);
+    }
+
+    public static void println(int value) {
+        log(RuntimeCall.LogPrimitive, Kind.Int.typeChar, value, true);
+    }
+
+    public static void println(long value) {
+        log(RuntimeCall.LogPrimitive, Kind.Long.typeChar, value, true);
+    }
+
+    public static void println(float value) {
+        if (Float.isNaN(value)) {
+            println("NaN");
+        } else if (value == Float.POSITIVE_INFINITY) {
+            println("Infinity");
+        } else if (value == Float.NEGATIVE_INFINITY) {
+            println("-Infinity");
+        } else {
+            log(RuntimeCall.LogPrimitive, Kind.Float.typeChar, Float.floatToRawIntBits(value), true);
+        }
+    }
+
+    public static void println(double value) {
+        if (Double.isNaN(value)) {
+            println("NaN");
+        } else if (value == Double.POSITIVE_INFINITY) {
+            println("Infinity");
+        } else if (value == Double.NEGATIVE_INFINITY) {
+            println("-Infinity");
+        } else {
+            log(RuntimeCall.LogPrimitive, Kind.Double.typeChar, Double.doubleToRawLongBits(value), true);
+        }
+    }
+
+    public static void println(String value) {
+        log(RuntimeCall.LogObject, value, true, true);
+    }
+
+    public static void printlnAddress(Object o) {
+        log(RuntimeCall.LogObject, o, true, false);
+    }
+
+    public static void println() {
+        println("");
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSnippetsX86.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/MathSnippetsX86.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.snippets;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.snippets.nodes.*;
 import com.oracle.graal.snippets.nodes.MathIntrinsicNode.Operation;
@@ -61,7 +61,7 @@
         if (abs(x) < PI_4) {
             return MathIntrinsicNode.compute(x, Operation.SIN);
         } else {
-            return RuntimeCallNode.performCall(CiRuntimeCall.ArithmeticSin, x);
+            return RuntimeCallNode.callDouble(RuntimeCall.ArithmeticSin, x);
         }
     }
 
@@ -69,7 +69,7 @@
         if (abs(x) < PI_4) {
             return MathIntrinsicNode.compute(x, Operation.COS);
         } else {
-            return RuntimeCallNode.performCall(CiRuntimeCall.ArithmeticCos, x);
+            return RuntimeCallNode.callDouble(RuntimeCall.ArithmeticCos, x);
         }
     }
 
@@ -77,7 +77,7 @@
         if (abs(x) < PI_4) {
             return MathIntrinsicNode.compute(x, Operation.TAN);
         } else {
-            return RuntimeCallNode.performCall(CiRuntimeCall.ArithmeticTan, x);
+            return RuntimeCallNode.callDouble(RuntimeCall.ArithmeticTan, x);
         }
     }
 
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/NodeClassSnippets.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/NodeClassSnippets.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,32 +22,35 @@
  */
 package com.oracle.graal.snippets;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.extended.*;
 
 /**
- * Snippets for {@link NodeClass} methods.
+ * Snippets for improving the performance of some critical methods in {@link NodeClass} methods.
+ * These snippets improve the performance by forcing the relevant methods to be inlined
+ * (intrinsification being a special form of inlining) and removing a checked cast.
+ * The latter cannot be done directly in Java code as {@link UnsafeCastNode}
+ * is not available to the project containing {@link NodeClass}.
  */
 @SuppressWarnings("unused")
 @ClassSubstitution(NodeClass.class)
 public class NodeClassSnippets implements SnippetsInterface {
 
-
     private static Node getNode(Node node, long offset) {
-        return UnsafeCastNode.cast(UnsafeLoadNode.load(node, 0, offset, CiKind.Object), Node.class);
+        return UnsafeCastNode.cast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class);
     }
 
     private static NodeList<Node> getNodeList(Node node, long offset) {
-        return UnsafeCastNode.cast(UnsafeLoadNode.load(node, 0, offset, CiKind.Object), NodeList.class);
+        return UnsafeCastNode.cast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class);
     }
 
     private static void putNode(Node node, long offset, Node value) {
-        UnsafeStoreNode.store(node, 0, offset, value, CiKind.Object);
+        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
     }
 
     private static void putNodeList(Node node, long offset, NodeList value) {
-        UnsafeStoreNode.store(node, 0, offset, value, CiKind.Object);
+        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
     }
 
 }
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java	Wed Jun 27 17:35:32 2012 +0200
@@ -23,9 +23,147 @@
 package com.oracle.graal.snippets;
 
 import java.lang.annotation.*;
+import java.lang.reflect.*;
 
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.snippets.Word.Operation;
+import com.oracle.graal.snippets.nodes.*;
+
+/**
+ * A snippet is a Graal graph expressed as a Java source method. Graal snippets can be used for:
+ * <ul>
+ * <li>intrinsifying native JDK methods (see {@link ClassSubstitution})</li>
+ * <li>lowering operations that have runtime dependent semantics (e.g. the {@code CHECKCAST} bytecode) </li>
+ * <li>replacing a method call with a single graph node (see {@link NodeIntrinsic})</li>
+ * </ul>
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface Snippet {
 
+    /**
+     * Specifies the class defining the inlining policy for this snippet.
+     * A {@linkplain InliningPolicy#Default default} policy is used if none is supplied.
+     */
+    Class<? extends InliningPolicy> inlining() default InliningPolicy.class;
+
+    /**
+     * Guides inlining decisions used when installing a snippet.
+     */
+    public interface InliningPolicy {
+        /**
+         * Determines if {@code method} should be inlined into {@code caller}.
+         */
+        boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller);
+
+        /**
+         * The default inlining policy which inlines everything except for
+         * constructors of {@link Throwable} classes.
+         */
+        InliningPolicy Default = new InliningPolicy() {
+            public boolean shouldInline(ResolvedJavaMethod method, ResolvedJavaMethod caller) {
+                if (Throwable.class.isAssignableFrom(method.holder().toJava())) {
+                    if (method.name().equals("<init>")) {
+                        return false;
+                    }
+                }
+                if (method.getAnnotation(Operation.class) != null) {
+                    return false;
+                }
+                return true;
+            }
+        };
+    }
+
+    /**
+     * Annotates a method replaced by a compile-time constant.
+     * A (resolved) call to the annotated method is replaced
+     * with a constant obtained by calling the annotated method via reflection.
+     *
+     * All arguments to such a method (including the receiver if applicable)
+     * must be compile-time constants.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    public static @interface Fold {
+    }
+
+    /**
+     * Denotes a snippet parameter that will be bound during snippet
+     * template {@linkplain SnippetTemplate#instantiate instantiation}.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    public @interface Parameter {
+        /**
+         * The name of this parameter.
+         */
+        String value();
+
+        /**
+         * Determines if this parameter represents 0 or more arguments. During snippet template creation,
+         * its value must be an array whose length specifies the number of arguments (the contents
+         * of the array are ignored) bound to the parameter during {@linkplain SnippetTemplate#instantiate instantiation}.
+         *
+         * Such a parameter must be used in a counted loop in the snippet preceded by a call
+         * to {@link ExplodeLoopNode#explodeLoop()}. The counted looped must be a
+         * standard iteration over all the loop's elements (i.e. {@code for (T e : arr) ... }).
+         */
+        boolean multiple() default false;
+    }
+
+    /**
+     * Denotes a snippet parameter that will bound to a constant value during
+     * snippet template {@linkplain SnippetTemplate#instantiate instantiation}.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.PARAMETER)
+    public @interface ConstantParameter {
+        /**
+         * The name of this constant.
+         */
+        String value();
+    }
+
+    /**
+     * Wrapper for the prototype value of a {@linkplain Parameter#multiple() multiple} parameter.
+     */
+    public static class Multiple {
+        public final Object array;
+        private final Class componentType;
+        private final int length;
+
+        public static Multiple multiple(Class componentType, int length) {
+            return new Multiple(Array.newInstance(componentType, length));
+        }
+
+        public Multiple(Object array) {
+            assert array != null;
+            this.componentType = array.getClass().getComponentType();
+            assert this.componentType != null;
+            this.length = java.lang.reflect.Array.getLength(array);
+            this.array = array;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Multiple) {
+                Multiple other = (Multiple) obj;
+                return other.componentType == componentType &&
+                        other.length == length;
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return componentType.hashCode() ^ length;
+        }
+
+        @Override
+        public String toString() {
+            return componentType.getName() + "[" + length + "]";
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2011, 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.snippets;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.compiler.util.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.snippets.Snippet.InliningPolicy;
+
+/**
+ * Utility for snippet {@linkplain #install(Class) installation}.
+ */
+public class SnippetInstaller {
+
+    private final ExtendedRiRuntime runtime;
+    private final TargetDescription target;
+    private final BoxingMethodPool pool;
+
+    /**
+     * A graph cache used by this installer to avoid using the compiler
+     * storage for each method processed during snippet installation.
+     * Without this, all processed methods are to be determined as
+     * {@linkplain IntrinsificationPhase#canIntrinsify intrinsifiable}.
+     */
+    private final Map<ResolvedJavaMethod, StructuredGraph> graphCache;
+
+    public SnippetInstaller(ExtendedRiRuntime runtime, TargetDescription target) {
+        this.runtime = runtime;
+        this.target = target;
+        this.pool = new BoxingMethodPool(runtime);
+        this.graphCache = new HashMap<>();
+    }
+
+    /**
+     * Finds all the snippet methods in a given class, builds a graph for them and
+     * installs the graph with the key value of {@code Graph.class} in the
+     * {@linkplain ResolvedJavaMethod#compilerStorage() compiler storage} of each method.
+     * <p>
+     * If {@code snippetsHolder} is annotated with {@link ClassSubstitution}, then all
+     * methods in the class are snippets. Otherwise, the snippets are those methods
+     * annotated with {@link Snippet}.
+     */
+    public void install(Class<? extends SnippetsInterface> snippetsHolder) {
+        if (snippetsHolder.isAnnotationPresent(ClassSubstitution.class)) {
+            installSubstitutions(snippetsHolder, snippetsHolder.getAnnotation(ClassSubstitution.class).value());
+        } else {
+            installSnippets(snippetsHolder);
+        }
+    }
+
+    private void installSnippets(Class< ? extends SnippetsInterface> clazz) {
+        for (Method method : clazz.getDeclaredMethods()) {
+            if (method.getAnnotation(Snippet.class) != null) {
+                int modifiers = method.getModifiers();
+                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                    throw new RuntimeException("Snippet must not be abstract or native");
+                }
+                ResolvedJavaMethod snippet = runtime.getResolvedJavaMethod(method);
+                assert snippet.compilerStorage().get(Graph.class) == null;
+                StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet));
+                //System.out.println("snippet: " + graph);
+                snippet.compilerStorage().put(Graph.class, graph);
+            }
+        }
+    }
+
+    private void installSubstitutions(Class< ? extends SnippetsInterface> clazz, Class<?> originalClazz) {
+        for (Method method : clazz.getDeclaredMethods()) {
+            try {
+                Method originalMethod = originalClazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
+                if (!originalMethod.getReturnType().isAssignableFrom(method.getReturnType())) {
+                    throw new RuntimeException("Snippet has incompatible return type");
+                }
+                int modifiers = method.getModifiers();
+                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                    throw new RuntimeException("Snippet must not be abstract or native");
+                }
+                ResolvedJavaMethod snippet = runtime.getResolvedJavaMethod(method);
+                StructuredGraph graph = makeGraph(snippet, inliningPolicy(snippet));
+                //System.out.println("snippet: " + graph);
+                runtime.getResolvedJavaMethod(originalMethod).compilerStorage().put(Graph.class, graph);
+            } catch (NoSuchMethodException e) {
+                throw new GraalInternalError("Could not resolve method in " + originalClazz + " to substitute with " + method, e);
+            }
+        }
+    }
+
+    private static InliningPolicy inliningPolicy(ResolvedJavaMethod method) {
+        Class<? extends InliningPolicy> policyClass = InliningPolicy.class;
+        Snippet snippet = method.getAnnotation(Snippet.class);
+        if (snippet != null) {
+            policyClass = snippet.inlining();
+        }
+        if (policyClass == InliningPolicy.class) {
+            return InliningPolicy.Default;
+        }
+        try {
+            return policyClass.getConstructor().newInstance();
+        } catch (Exception e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    public StructuredGraph makeGraph(final ResolvedJavaMethod method, final InliningPolicy policy) {
+        StructuredGraph graph = parseGraph(method, policy);
+
+        Debug.dump(graph, "%s: Final", method.name());
+
+        return graph;
+    }
+
+    private StructuredGraph parseGraph(final ResolvedJavaMethod method, final InliningPolicy policy) {
+        StructuredGraph graph = graphCache.get(method);
+        if (graph == null) {
+            graph = buildGraph(method, policy == null ? inliningPolicy(method) : policy);
+            //System.out.println("built " + graph);
+            graphCache.put(method, graph);
+        }
+        return graph;
+    }
+
+    private StructuredGraph buildGraph(final ResolvedJavaMethod method, final InliningPolicy policy) {
+        final StructuredGraph graph = new StructuredGraph(method);
+        return Debug.scope("BuildSnippetGraph", new Object[] {method, graph}, new Callable<StructuredGraph>() {
+            @Override
+            public StructuredGraph call() throws Exception {
+                GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault();
+                GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE);
+                graphBuilder.apply(graph);
+
+                Debug.dump(graph, "%s: %s", method.name(), GraphBuilderPhase.class.getSimpleName());
+
+                new SnippetVerificationPhase().apply(graph);
+
+                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
+
+                for (Invoke invoke : graph.getInvokes()) {
+                    MethodCallTargetNode callTarget = invoke.callTarget();
+                    ResolvedJavaMethod callee = callTarget.targetMethod();
+                    if (policy.shouldInline(callee, method)) {
+                        StructuredGraph targetGraph = parseGraph(callee, policy);
+                        InliningUtil.inline(invoke, targetGraph, true);
+                        Debug.dump(graph, "after inlining %s", callee);
+                        if (GraalOptions.OptCanonicalizer) {
+                            new WordTypeRewriterPhase(target.wordKind, runtime.getResolvedJavaType(target.wordKind)).apply(graph);
+                            new CanonicalizerPhase(target, runtime, null).apply(graph);
+                        }
+                    }
+                }
+
+                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
+
+                new WordTypeRewriterPhase(target.wordKind, runtime.getResolvedJavaType(target.wordKind)).apply(graph);
+
+                new DeadCodeEliminationPhase().apply(graph);
+                if (GraalOptions.OptCanonicalizer) {
+                    new CanonicalizerPhase(target, runtime, null).apply(graph);
+                }
+
+                for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
+                    end.disableSafepoint();
+                }
+
+                new InsertStateAfterPlaceholderPhase().apply(graph);
+
+                if (GraalOptions.ProbabilityAnalysis) {
+                    new DeadCodeEliminationPhase().apply(graph);
+                    new ComputeProbabilityPhase().apply(graph);
+                }
+                return graph;
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2011, 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.snippets;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.ConstantNodeParameter;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.snippets.Snippet.Fold;
+
+public class SnippetIntrinsificationPhase extends Phase {
+
+    private final CodeCacheProvider runtime;
+    private final BoxingMethodPool pool;
+
+    public SnippetIntrinsificationPhase(CodeCacheProvider runtime, BoxingMethodPool pool) {
+        this.runtime = runtime;
+        this.pool = pool;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Invoke i : graph.getInvokes()) {
+            tryIntrinsify(i);
+        }
+    }
+
+    private void tryIntrinsify(Invoke invoke) {
+        ResolvedJavaMethod target = invoke.callTarget().targetMethod();
+        NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
+        if (intrinsic != null) {
+            assert target.getAnnotation(Fold.class) == null;
+
+            Class< ? >[] parameterTypes = CodeUtil.signatureToTypes(target.signature(), target.holder());
+
+            // Prepare the arguments for the reflective constructor call on the node class.
+            Object[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target, false);
+
+            // Create the new node instance.
+            Class< ? > c = getNodeClass(target, intrinsic);
+            Node newInstance = createNodeInstance(c, parameterTypes, nodeConstructorArguments);
+
+            // Replace the invoke with the new node.
+            invoke.node().graph().add(newInstance);
+            invoke.intrinsify(newInstance);
+
+            // Clean up checkcast instructions inserted by javac if the return type is generic.
+            cleanUpReturnCheckCast(newInstance);
+        } else if (target.getAnnotation(Fold.class) != null) {
+            Class< ? >[] parameterTypes = CodeUtil.signatureToTypes(target.signature(), target.holder());
+
+            // Prepare the arguments for the reflective method call
+            Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
+            Object receiver = null;
+            if (!invoke.callTarget().isStatic()) {
+                receiver = arguments[0];
+                arguments = Arrays.asList(arguments).subList(1, arguments.length).toArray();
+            }
+
+            // Call the method
+            Constant constant = callMethod(target.signature().returnKind(), target.holder().toJava(), target.name(), parameterTypes, receiver, arguments);
+
+            if (constant != null) {
+                // Replace the invoke with the result of the call
+                ConstantNode node = ConstantNode.forConstant(constant, runtime, invoke.node().graph());
+                invoke.intrinsify(node);
+
+                // Clean up checkcast instructions inserted by javac if the return type is generic.
+                cleanUpReturnCheckCast(node);
+            } else {
+                // Remove the invoke
+                invoke.intrinsify(null);
+            }
+        }
+    }
+
+    /**
+     * Converts the arguments of an invoke node to object values suitable for use as the arguments
+     * to a reflective invocation of a Java constructor or method.
+     *
+     * @param folding specifies if the invocation is for handling a {@link Fold} annotation
+     */
+    private Object[] prepareArguments(Invoke invoke, Class< ? >[] parameterTypes, ResolvedJavaMethod target, boolean folding) {
+        NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
+        Object[] reflectionCallArguments = new Object[arguments.size()];
+        for (int i = 0; i < reflectionCallArguments.length; ++i) {
+            int parameterIndex = i;
+            if (!invoke.callTarget().isStatic()) {
+                parameterIndex--;
+            }
+            ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i));
+            if (folding || CodeUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) {
+                assert argument instanceof ConstantNode : "parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument;
+                ConstantNode constantNode = (ConstantNode) argument;
+                Constant constant = constantNode.asConstant();
+                Object o = constant.boxedValue();
+                if (o instanceof Class< ? >) {
+                    reflectionCallArguments[i] = runtime.getResolvedJavaType((Class< ? >) o);
+                    parameterTypes[i] = ResolvedJavaType.class;
+                } else {
+                    if (parameterTypes[i] == boolean.class) {
+                        reflectionCallArguments[i] = Boolean.valueOf(constant.asInt() != 0);
+                    } else if (parameterTypes[i] == byte.class) {
+                        reflectionCallArguments[i] = Byte.valueOf((byte) constant.asInt());
+                    } else if (parameterTypes[i] == short.class) {
+                        reflectionCallArguments[i] = Short.valueOf((short) constant.asInt());
+                    } else if (parameterTypes[i] == char.class) {
+                        reflectionCallArguments[i] = Character.valueOf((char) constant.asInt());
+                    } else {
+                        reflectionCallArguments[i] = o;
+                    }
+                }
+            } else {
+                reflectionCallArguments[i] = argument;
+                parameterTypes[i] = ValueNode.class;
+            }
+        }
+        return reflectionCallArguments;
+    }
+
+    private static Class< ? > getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) {
+        Class< ? > result = intrinsic.value();
+        if (result == NodeIntrinsic.class) {
+            result = target.holder().toJava();
+        }
+        assert Node.class.isAssignableFrom(result);
+        return result;
+    }
+
+    private ValueNode tryBoxingElimination(int parameterIndex, ResolvedJavaMethod target, ValueNode node) {
+        if (parameterIndex >= 0) {
+            Type type = target.getGenericParameterTypes()[parameterIndex];
+            if (type instanceof TypeVariable) {
+                TypeVariable typeVariable = (TypeVariable) type;
+                if (typeVariable.getBounds().length == 1) {
+                    Type boundType = typeVariable.getBounds()[0];
+                    if (boundType instanceof Class && ((Class) boundType).getSuperclass() == null) {
+                        // Unbound generic => try boxing elimination
+                        if (node.usages().size() == 2) {
+                            if (node instanceof Invoke) {
+                                Invoke invokeNode = (Invoke) node;
+                                MethodCallTargetNode callTarget = invokeNode.callTarget();
+                                if (pool.isBoxingMethod(callTarget.targetMethod())) {
+                                    FrameState stateAfter = invokeNode.stateAfter();
+                                    assert stateAfter.usages().size() == 1;
+                                    invokeNode.node().replaceAtUsages(null);
+                                    ValueNode result = callTarget.arguments().get(0);
+                                    StructuredGraph graph = (StructuredGraph) node.graph();
+                                    if (invokeNode instanceof InvokeWithExceptionNode) {
+                                        // Destroy exception edge & clear stateAfter.
+                                        InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
+
+                                        invokeWithExceptionNode.killExceptionEdge();
+                                        graph.removeSplit(invokeWithExceptionNode, InvokeWithExceptionNode.NORMAL_EDGE);
+                                    } else {
+                                        graph.removeFixed((InvokeNode) invokeNode);
+                                    }
+                                    stateAfter.safeDelete();
+                                    GraphUtil.propagateKill(callTarget);
+                                    return result;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return node;
+    }
+
+    private static Class asBoxedType(Class type) {
+        if (!type.isPrimitive()) {
+            return type;
+        }
+
+        if (Boolean.TYPE == type) {
+            return Boolean.class;
+        }
+        if (Character.TYPE == type) {
+            return Character.class;
+        }
+        if (Byte.TYPE == type) {
+            return Byte.class;
+        }
+        if (Short.TYPE == type) {
+            return Short.class;
+        }
+        if (Integer.TYPE == type) {
+            return Integer.class;
+        }
+        if (Long.TYPE == type) {
+            return Long.class;
+        }
+        if (Float.TYPE == type) {
+            return Float.class;
+        }
+        assert Double.TYPE == type;
+        return Double.class;
+    }
+
+    static final int VARARGS = 0x00000080;
+
+    private static Node createNodeInstance(Class< ? > nodeClass, Class< ? >[] parameterTypes, Object[] nodeConstructorArguments) {
+        Object[] arguments = null;
+        Constructor< ? > constructor = null;
+        nextConstructor:
+        for (Constructor c : nodeClass.getDeclaredConstructors()) {
+            Class[] signature = c.getParameterTypes();
+            if ((c.getModifiers() & VARARGS) != 0) {
+                int fixedArgs = signature.length - 1;
+                if (parameterTypes.length < fixedArgs) {
+                    continue nextConstructor;
+                }
+
+                for (int i = 0; i < fixedArgs; i++) {
+                    if (!parameterTypes[i].equals(signature[i])) {
+                        continue nextConstructor;
+                    }
+                }
+
+                Class componentType = signature[fixedArgs].getComponentType();
+                assert componentType != null : "expected last parameter of varargs constructor " + c + " to be an array type";
+                Class boxedType = asBoxedType(componentType);
+                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
+                    if (!boxedType.isInstance(nodeConstructorArguments[i])) {
+                        continue nextConstructor;
+                    }
+                }
+
+                arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1);
+                int varargsLength = nodeConstructorArguments.length - fixedArgs;
+                Object varargs = Array.newInstance(componentType, varargsLength);
+                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
+                    Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i]);
+                }
+                arguments[fixedArgs] = varargs;
+                constructor = c;
+                break;
+            } else if (Arrays.equals(parameterTypes, signature)) {
+                arguments = nodeConstructorArguments;
+                constructor = c;
+                break;
+            }
+        }
+        if (constructor == null) {
+            throw new GraalInternalError("Could not find constructor in " + nodeClass + " compatible with signature " + Arrays.toString(parameterTypes));
+        }
+        constructor.setAccessible(true);
+        try {
+            return (ValueNode) constructor.newInstance(arguments);
+        } catch (Exception e) {
+            throw new RuntimeException(constructor + Arrays.toString(nodeConstructorArguments), e);
+        }
+    }
+
+    /**
+     * Calls a Java method via reflection.
+     */
+    private static Constant callMethod(Kind returnKind, Class< ? > holder, String name, Class< ? >[] parameterTypes, Object receiver, Object[] arguments) {
+        Method method;
+        try {
+            method = holder.getDeclaredMethod(name, parameterTypes);
+            method.setAccessible(true);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        try {
+            Object result = method.invoke(receiver, arguments);
+            if (result == null) {
+                return null;
+            }
+            return Constant.forBoxed(returnKind, result);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static String sourceLocation(Node n) {
+        String loc = GraphUtil.approxSourceLocation(n);
+        return loc == null ? "<unknown>" : loc;
+    }
+
+    public void cleanUpReturnCheckCast(Node newInstance) {
+        if (newInstance instanceof ValueNode && ((ValueNode) newInstance).kind() != Kind.Object) {
+            StructuredGraph graph = (StructuredGraph) newInstance.graph();
+            for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) {
+                for (ValueProxyNode vpn : checkCastNode.usages().filter(ValueProxyNode.class).snapshot()) {
+                    graph.replaceFloating(vpn, checkCastNode);
+                }
+                for (Node checkCastUsage : checkCastNode.usages().snapshot()) {
+                    if (checkCastUsage instanceof ValueAnchorNode) {
+                        ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage;
+                        graph.removeFixed(valueAnchorNode);
+                    } else if (checkCastUsage instanceof MethodCallTargetNode) {
+                        MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage;
+                        assert pool.isUnboxingMethod(checkCastCallTarget.targetMethod()) :
+                            "checkcast at " + sourceLocation(checkCastNode) + " not used by an unboxing method but by a call at " +
+                            sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod();
+                        Invoke invokeNode = checkCastCallTarget.invoke();
+                        invokeNode.node().replaceAtUsages(newInstance);
+                        if (invokeNode instanceof InvokeWithExceptionNode) {
+                            // Destroy exception edge & clear stateAfter.
+                            InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invokeNode;
+
+                            invokeWithExceptionNode.killExceptionEdge();
+                            graph.removeSplit(invokeWithExceptionNode, InvokeWithExceptionNode.NORMAL_EDGE);
+                        } else {
+                            graph.removeFixed((InvokeNode) invokeNode);
+                        }
+                        checkCastCallTarget.safeDelete();
+                    } else if (checkCastUsage instanceof FrameState) {
+                        checkCastUsage.replaceFirstInput(checkCastNode, null);
+                    } else {
+                        assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode);
+                    }
+                }
+                FixedNode next = checkCastNode.next();
+                checkCastNode.setNext(null);
+                checkCastNode.replaceAtPredecessor(next);
+                GraphUtil.killCFG(checkCastNode);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,491 @@
+/*
+ * 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.snippets;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.loop.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.Verbosity;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.snippets.Snippet.ConstantParameter;
+import com.oracle.graal.snippets.Snippet.Multiple;
+import com.oracle.graal.snippets.Snippet.Parameter;
+import com.oracle.graal.snippets.nodes.*;
+
+/**
+ * A snippet template is a graph created by parsing a snippet method and then
+ * specialized by binding constants to the snippet's {@link ConstantParameter} parameters.
+ *
+ * Snippet templates can be managed in a {@link Cache}.
+ */
+public class SnippetTemplate {
+
+    /**
+     * A snippet template key encapsulates the method from which a snippet was built
+     * and the arguments used to specialized the snippet.
+     *
+     * @see Cache
+     */
+    public static class Key implements Iterable<Map.Entry<String, Object>> {
+        public final ResolvedJavaMethod method;
+        private final HashMap<String, Object> map = new HashMap<>();
+        private int hash;
+
+        public Key(ResolvedJavaMethod method) {
+            this.method = method;
+            this.hash = method.hashCode();
+        }
+
+        public Key add(String name, Object value) {
+            assert !map.containsKey(name);
+            map.put(name, value);
+            hash = hash ^ name.hashCode();
+            if (value != null) {
+                hash *= (value.hashCode() + 1);
+            }
+            return this;
+        }
+
+        public int length() {
+            return map.size();
+        }
+
+        public Object get(String name) {
+            return map.get(name);
+        }
+
+        @Override
+        public Iterator<Entry<String, Object>> iterator() {
+            return map.entrySet().iterator();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof Key) {
+                Key other = (Key) obj;
+                return other.method == method && other.map.equals(map);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+
+        @Override
+        public String toString() {
+            return CodeUtil.format("%h.%n", method) + map.toString();
+        }
+    }
+
+    /**
+     * Arguments used to instantiate a template.
+     */
+    public static class Arguments implements Iterable<Map.Entry<String, Object>> {
+        private final HashMap<String, Object> map = new HashMap<>();
+
+        public static Arguments arguments(String name, Object value) {
+            return new Arguments().add(name, value);
+        }
+
+        public Arguments add(String name, Object value) {
+            assert !map.containsKey(name);
+            map.put(name, value);
+            return this;
+        }
+
+        public int length() {
+            return map.size();
+        }
+
+        @Override
+        public Iterator<Entry<String, Object>> iterator() {
+            return map.entrySet().iterator();
+        }
+
+        @Override
+        public String toString() {
+            return map.toString();
+        }
+    }
+
+    /**
+     * A collection of snippet templates accessed by a {@link Key} instance.
+     */
+    public static class Cache {
+
+        private final ConcurrentHashMap<SnippetTemplate.Key, SnippetTemplate> templates = new ConcurrentHashMap<>();
+        private final CodeCacheProvider runtime;
+
+
+        public Cache(CodeCacheProvider runtime) {
+            this.runtime = runtime;
+        }
+
+        /**
+         * Gets a template for a given key, creating it first if necessary.
+         */
+        public SnippetTemplate get(final SnippetTemplate.Key key) {
+            SnippetTemplate template = templates.get(key);
+            if (template == null) {
+                template = Debug.scope("SnippetSpecialization", key.method, new Callable<SnippetTemplate>() {
+                    @Override
+                    public SnippetTemplate call() throws Exception {
+                        return new SnippetTemplate(runtime, key);
+                    }
+                });
+                //System.out.println(key + " -> " + template);
+                templates.put(key, template);
+            }
+            return template;
+        }
+
+    }
+
+    /**
+     * Creates a snippet template.
+     */
+    public SnippetTemplate(CodeCacheProvider runtime, SnippetTemplate.Key key) {
+        ResolvedJavaMethod method = key.method;
+        assert Modifier.isStatic(method.accessFlags()) : "snippet method must be static: " + method;
+        Signature signature = method.signature();
+
+        // Copy snippet graph, replacing @Constant parameters with given arguments
+        StructuredGraph snippetGraph = (StructuredGraph) method.compilerStorage().get(Graph.class);
+        StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
+        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
+        replacements.put(snippetGraph.start(), snippetCopy.start());
+
+        int parameterCount = signature.argumentCount(false);
+        Parameter[] parameterAnnotations = new Parameter[parameterCount];
+        ConstantNode[] placeholders = new ConstantNode[parameterCount];
+        for (int i = 0; i < parameterCount; i++) {
+            ConstantParameter c = CodeUtil.getParameterAnnotation(ConstantParameter.class, i, method);
+            if (c != null) {
+                String name = c.value();
+                Object arg = key.get(name);
+                Kind kind = signature.argumentKindAt(i);
+                assert checkConstantArgument(method, signature, i, name, arg, kind);
+                replacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(Constant.forBoxed(kind, arg), runtime, snippetCopy));
+            } else {
+                Parameter p = CodeUtil.getParameterAnnotation(Parameter.class, i, method);
+                assert p != null : method + ": parameter " + i + " must be annotated with either @Constant or @Parameter";
+                String name = p.value();
+                if (p.multiple()) {
+                    Object multiple = key.get(name);
+                    assert multiple != null : method + ": requires a Multiple named " + name;
+                    assert checkMultipleArgument(method, signature, i, name, multiple);
+                    Object array = ((Multiple) multiple).array;
+                    ConstantNode placeholder = ConstantNode.forObject(array, runtime, snippetCopy);
+                    replacements.put(snippetGraph.getLocal(i), placeholder);
+                    placeholders[i] = placeholder;
+                }
+                parameterAnnotations[i] = p;
+            }
+        }
+        snippetCopy.addDuplicates(snippetGraph.getNodes(), replacements);
+
+        Debug.dump(snippetCopy, "Before specialization");
+        if (!replacements.isEmpty()) {
+            new CanonicalizerPhase(null, runtime, null, 0, null).apply(snippetCopy);
+        }
+
+        // Gather the template parameters
+        parameters = new HashMap<>();
+        for (int i = 0; i < parameterCount; i++) {
+            Parameter p = parameterAnnotations[i];
+            if (p != null) {
+                if (p.multiple()) {
+                    assert snippetCopy.getLocal(i) == null;
+                    Object array = ((Multiple) key.get(p.value())).array;
+                    int length = Array.getLength(array);
+                    LocalNode[] locals = new LocalNode[length];
+                    Stamp stamp = StampFactory.forKind(runtime.getResolvedJavaType(array.getClass().getComponentType()).kind());
+                    for (int j = 0; j < length; j++) {
+                        assert (parameterCount & 0xFFFF) == parameterCount;
+                        int idx = i << 16 | j;
+                        LocalNode local = snippetCopy.unique(new LocalNode(idx, stamp));
+                        locals[j] = local;
+                    }
+                    parameters.put(p.value(), locals);
+
+                    ConstantNode placeholder = placeholders[i];
+                    assert placeholder != null;
+                    for (Node usage : placeholder.usages().snapshot()) {
+                        if (usage instanceof LoadIndexedNode) {
+                            LoadIndexedNode loadIndexed = (LoadIndexedNode) usage;
+                            Debug.dump(snippetCopy, "Before replacing %s", loadIndexed);
+                            LoadSnippetParameterNode loadSnippetParameter = snippetCopy.add(new LoadSnippetParameterNode(locals, loadIndexed.index(), loadIndexed.stamp()));
+                            snippetCopy.replaceFixedWithFixed(loadIndexed, loadSnippetParameter);
+                            Debug.dump(snippetCopy, "After replacing %s", loadIndexed);
+                        }
+                    }
+                } else {
+                    LocalNode local = snippetCopy.getLocal(i);
+                    assert local != null;
+                    parameters.put(p.value(), local);
+                }
+            }
+        }
+
+        // Do any required loop explosion
+        boolean exploded = false;
+        do {
+            exploded = false;
+            ExplodeLoopNode explodeLoop = snippetCopy.getNodes().filter(ExplodeLoopNode.class).first();
+            if (explodeLoop != null) { // Earlier canonicalization may have removed the loop altogether
+                LoopBeginNode loopBegin = explodeLoop.findLoopBegin();
+                if (loopBegin != null) {
+                    LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
+                    int mark = snippetCopy.getMark();
+                    LoopTransformations.fullUnroll(loop, runtime);
+                    new CanonicalizerPhase(null, runtime, null, mark, null).apply(snippetCopy);
+                }
+                FixedNode explodeLoopNext = explodeLoop.next();
+                explodeLoop.clearSuccessors();
+                explodeLoop.replaceAtPredecessor(explodeLoopNext);
+                explodeLoop.replaceAtUsages(null);
+                GraphUtil.killCFG(explodeLoop);
+                exploded = true;
+            }
+        } while (exploded);
+
+        // Remove all frame states from inlined snippet graph. Snippets must be atomic (i.e. free
+        // of side-effects that prevent deoptimizing to a point before the snippet).
+        for (Node node : snippetCopy.getNodes()) {
+            if (node instanceof StateSplit) {
+                StateSplit stateSplit = (StateSplit) node;
+                FrameState frameState = stateSplit.stateAfter();
+                assert !stateSplit.hasSideEffect() : "snippets cannot contain side-effecting node " + node + "\n    " + frameState.toString(Verbosity.Debugger);
+                if (frameState != null) {
+                    stateSplit.setStateAfter(null);
+                }
+            }
+        }
+
+        new DeadCodeEliminationPhase().apply(snippetCopy);
+
+        assert checkAllMultipleParameterPlaceholdersAreDeleted(parameterCount, placeholders);
+
+        this.graph = snippetCopy;
+        nodes = new ArrayList<>(graph.getNodeCount());
+        ReturnNode retNode = null;
+        StartNode entryPointNode = graph.start();
+        for (Node node : graph.getNodes()) {
+            if (node == entryPointNode || node == entryPointNode.stateAfter()) {
+                // Do nothing.
+            } else {
+                nodes.add(node);
+                if (node instanceof ReturnNode) {
+                    retNode = (ReturnNode) node;
+                }
+            }
+        }
+        this.returnNode = retNode;
+    }
+
+    private static boolean checkAllMultipleParameterPlaceholdersAreDeleted(int parameterCount, ConstantNode[] placeholders) {
+        for (int i = 0; i < parameterCount; i++) {
+            if (placeholders[i] != null) {
+                assert placeholders[i].isDeleted() : placeholders[i];
+            }
+        }
+        return true;
+    }
+
+    private static boolean checkConstantArgument(final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) {
+        if (kind.isObject()) {
+            Class<?> type = signature.argumentTypeAt(i, method.holder()).resolve(method.holder()).toJava();
+            assert arg == null || type.isInstance(arg) :
+                method + ": wrong value type for " + name + ": expected " + type.getName() + ", got " + arg.getClass().getName();
+        } else {
+            assert arg != null && kind.toBoxedJavaClass() == arg.getClass() :
+                method + ": wrong value kind for " + name + ": expected " + kind + ", got " + (arg == null ? "null" : arg.getClass().getSimpleName());
+        }
+        return true;
+    }
+
+    private static boolean checkMultipleArgument(final ResolvedJavaMethod method, Signature signature, int i, String name, Object multiple) {
+        assert multiple instanceof Multiple;
+        Object arg = ((Multiple) multiple).array;
+        ResolvedJavaType type = (ResolvedJavaType) signature.argumentTypeAt(i, method.holder());
+        Class< ? > javaType = type.toJava();
+        assert javaType.isArray() : "multiple parameter must be an array type";
+        assert javaType.isInstance(arg) : "value for " + name + " is not a " + javaType.getName() + " instance: " + arg;
+        return true;
+    }
+
+    /**
+     * The graph built from the snippet method.
+     */
+    private final StructuredGraph graph;
+
+    /**
+     * The named parameters of this template that must be bound to values during instantiation.
+     * Each value in this map is either a {@link LocalNode} instance or a {@link LocalNode} array.
+     */
+    private final Map<String, Object> parameters;
+
+    /**
+     * The return node (if any) of the snippet.
+     */
+    private final ReturnNode returnNode;
+
+    /**
+     * The nodes to be inlined when this specialization is instantiated.
+     */
+    private final ArrayList<Node> nodes;
+
+    /**
+     * Gets the instantiation-time bindings to this template's parameters.
+     *
+     * @return the map that will be used to bind arguments to parameters when inlining this template
+     */
+    private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, CodeCacheProvider runtime, SnippetTemplate.Arguments args) {
+        IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
+
+        for (Map.Entry<String, Object> e : args) {
+            String name = e.getKey();
+            Object parameter = parameters.get(name);
+            assert parameter != null : this + " has no parameter named " + name;
+            Object argument = e.getValue();
+            if (parameter instanceof LocalNode) {
+                if (argument instanceof ValueNode) {
+                    replacements.put((LocalNode) parameter, (ValueNode) argument);
+                } else {
+                    Kind kind = ((LocalNode) parameter).kind();
+                    Constant constant = Constant.forBoxed(kind, argument);
+                    replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph));
+                }
+            } else {
+                assert parameter instanceof LocalNode[];
+                LocalNode[] locals = (LocalNode[]) parameter;
+                Object array = argument;
+                assert array != null && array.getClass().isArray();
+                int length = locals.length;
+                assert Array.getLength(array) == length : length + " != " + Array.getLength(array);
+                for (int j = 0; j < length; j++) {
+                    LocalNode local = locals[j];
+                    assert local != null;
+                    Constant constant = Constant.forBoxed(local.kind(), Array.get(array, j));
+                    ConstantNode element = ConstantNode.forConstant(constant, runtime, replaceeGraph);
+                    replacements.put(local, element);
+                }
+            }
+        }
+        return replacements;
+    }
+
+    /**
+     * Replaces a given node with this specialized snippet.
+     *
+     * @param runtime
+     * @param replacee the node that will be replaced
+     * @param anchor the control flow replacee
+     * @param args the arguments to be bound to the flattened positional parameters of the snippet
+     */
+    public void instantiate(CodeCacheProvider runtime,
+                    Node replacee,
+                    FixedWithNextNode anchor, SnippetTemplate.Arguments args) {
+
+        // Inline the snippet nodes, replacing parameters with the given args in the process
+        String name = graph.name == null ? "{copy}" : graph.name + "{copy}";
+        StructuredGraph graphCopy = new StructuredGraph(name, graph.method());
+        StartNode entryPointNode = graph.start();
+        FixedNode firstCFGNode = entryPointNode.next();
+        StructuredGraph replaceeGraph = (StructuredGraph) replacee.graph();
+        IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args);
+        Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, replacements);
+        Debug.dump(replaceeGraph, "After inlining snippet %s", graphCopy.method());
+
+        // Re-wire the control flow graph around the replacee
+        FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
+        anchor.replaceAtPredecessor(firstCFGNodeDuplicate);
+        FixedNode next = anchor.next();
+        anchor.setNext(null);
+
+        // Replace all usages of the replacee with the value returned by the snippet
+        Node returnValue = null;
+        if (returnNode != null) {
+            if (returnNode.result() instanceof LocalNode) {
+                returnValue = replacements.get(returnNode.result());
+            } else {
+                returnValue = duplicates.get(returnNode.result());
+            }
+            assert returnValue != null || replacee.usages().isEmpty();
+            replacee.replaceAtUsages(returnValue);
+
+            Node returnDuplicate = duplicates.get(returnNode);
+            returnDuplicate.clearInputs();
+            returnDuplicate.replaceAndDelete(next);
+        }
+
+        // Remove the replacee from its graph
+        replacee.clearInputs();
+        replacee.replaceAtUsages(null);
+        if (replacee instanceof FixedNode) {
+            GraphUtil.killCFG((FixedNode) replacee);
+        } else {
+            GraphUtil.killWithUnusedFloatingInputs(replacee);
+        }
+        if (anchor != replacee) {
+            GraphUtil.killCFG(anchor);
+        }
+
+        Debug.dump(replaceeGraph, "After lowering %s with %s", replacee, this);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder(graph.toString()).append('(');
+        String sep = "";
+        for (Map.Entry<String, Object> e : parameters.entrySet()) {
+            String name = e.getKey();
+            Object value = e.getValue();
+            buf.append(sep);
+            sep = ", ";
+            if (value instanceof LocalNode) {
+                LocalNode local = (LocalNode) value;
+                buf.append(local.kind().name()).append(' ').append(name);
+            } else {
+                LocalNode[] locals = (LocalNode[]) value;
+                String kind = locals.length == 0 ? "?" : locals[0].kind().name();
+                buf.append(kind).append('[').append(locals.length).append("] ").append(name);
+            }
+        }
+        return buf.append(')').toString();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetVerificationPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2011, 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.snippets;
+
+import static com.oracle.graal.snippets.WordTypeRewriterPhase.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.NodeIntrinsic;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.snippets.Word.*;
+
+/**
+ * Verifies invariants that must hold for snippet code above and beyond normal
+ * bytecode verification.
+ */
+public class SnippetVerificationPhase extends Phase {
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
+            for (Node usage : node.usages()) {
+                if (usage instanceof AccessMonitorNode) {
+                    verify(!isWord(node), node, usage, "word value has no monitor");
+                } else if (usage instanceof LoadFieldNode) {
+                    verify(!isWord(node) || ((LoadFieldNode) usage).object() != node, node, usage, "cannot load from word value");
+                } else if (usage instanceof StoreFieldNode) {
+                    verify(!isWord(node) || ((StoreFieldNode) usage).object() != node, node, usage, "cannot store to word value");
+                } else if (usage instanceof CheckCastNode) {
+                    verify(!isWord(node), node, usage, "word value cannot be cast");
+                    verify(!isWord(((CheckCastNode) usage).targetClass()), node, usage, "cannot cast to word value");
+                } else if (usage instanceof LoadIndexedNode) {
+                    verify(!isWord(node) || ((LoadIndexedNode) usage).array() != node, node, usage, "cannot load from word value");
+                    verify(!isWord(node) || ((LoadIndexedNode) usage).index() != node, node, usage, "cannot use word value as index");
+                } else if (usage instanceof StoreIndexedNode) {
+                    verify(!isWord(node) || ((StoreIndexedNode) usage).array() != node, node, usage, "cannot store to word value");
+                    verify(!isWord(node) || ((StoreIndexedNode) usage).index() != node, node, usage, "cannot use word value as index");
+                    verify(!isWord(node) || ((StoreIndexedNode) usage).value() != node, node, usage, "cannot store word value to array");
+                } else if (usage instanceof MethodCallTargetNode) {
+                    MethodCallTargetNode callTarget = (MethodCallTargetNode) usage;
+                    ResolvedJavaMethod method = callTarget.targetMethod();
+                    if (method.getAnnotation(NodeIntrinsic.class) == null) {
+                        Invoke invoke = (Invoke) callTarget.usages().first();
+                        NodeInputList<ValueNode> arguments = callTarget.arguments();
+                        boolean isStatic = Modifier.isStatic(method.accessFlags());
+                        int argc = 0;
+                        if (!isStatic) {
+                            ValueNode receiver = arguments.get(argc);
+                            if (receiver == node && isWord(node)) {
+                                Operation operation = method.getAnnotation(Word.Operation.class);
+                                verify(operation != null, node, invoke.node(), "cannot dispatch on word value to non @Operation annotated method " + method);
+                            }
+                            argc++;
+                        }
+                        Signature signature = method.signature();
+                        for (int i = 0; i < signature.argumentCount(false); i++) {
+                            ValueNode argument = arguments.get(argc);
+                            if (argument == node) {
+                                ResolvedJavaType type = (ResolvedJavaType) signature.argumentTypeAt(i, method.holder());
+                                verify((type.toJava() == Word.class) == isWord(argument), node, invoke.node(), "cannot pass word value to non-word parameter " + i + " or vice-versa");
+                            }
+                            argc++;
+                        }
+                    }
+                } else if (usage instanceof ArrayLengthNode) {
+                    verify(!isWord(node) || ((ArrayLengthNode) usage).array() != node, node, usage, "cannot get array length from word value");
+                } else if (usage instanceof PhiNode) {
+                    if (!(node instanceof MergeNode)) {
+                        PhiNode phi = (PhiNode) usage;
+                        for (ValueNode input : phi.values()) {
+                            verify(isWord(node) == isWord(input), node, input, "cannot merge word and non-word values");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private static void verify(boolean condition, Node node, Node usage, String message) {
+        if (!condition) {
+            error(node, usage, message);
+        }
+    }
+
+    private static void error(Node node, Node usage, String message) {
+        throw new GraalInternalError(String.format("Snippet verification error: %s" +
+                        "%n   node: %s (%s)" +
+                        "%n  usage: %s (%s)", message, node, sourceLocation(node), usage, sourceLocation(usage)));
+    }
+
+    private static String sourceLocation(Node n) {
+        if (n instanceof PhiNode) {
+            StringBuilder buf = new StringBuilder();
+            for (Node usage : n.usages()) {
+                String loc = sourceLocation(usage);
+                if (!loc.equals("<unknown>")) {
+                    if (buf.length() != 0) {
+                        buf.append(", ");
+                    }
+                    buf.append(loc);
+                }
+            }
+            return buf.toString();
+        } else {
+            String loc = GraphUtil.approxSourceLocation(n);
+            return loc == null ? "<unknown>" : loc;
+        }
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2011, 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.snippets;
-
-import java.lang.reflect.*;
-import java.util.concurrent.*;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.phases.*;
-import com.oracle.graal.compiler.util.*;
-import com.oracle.graal.cri.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-
-/**
- * Utilities for snippet installation and management.
- */
-public class Snippets {
-
-    public static void install(GraalRuntime runtime, CiTarget target, SnippetsInterface obj) {
-        Class<? extends SnippetsInterface> clazz = obj.getClass();
-        BoxingMethodPool pool = new BoxingMethodPool(runtime);
-        if (clazz.isAnnotationPresent(ClassSubstitution.class)) {
-            installSubstitution(runtime, target, clazz, pool, clazz.getAnnotation(ClassSubstitution.class).value());
-        } else {
-            installSnippets(runtime, target, clazz, pool);
-        }
-    }
-
-    private static void installSnippets(GraalRuntime runtime, CiTarget target, Class< ? extends SnippetsInterface> clazz,
-                    BoxingMethodPool pool) {
-        for (Method snippet : clazz.getDeclaredMethods()) {
-            int modifiers = snippet.getModifiers();
-            if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
-                throw new RuntimeException("Snippet must not be abstract or native");
-            }
-            RiResolvedMethod snippetRiMethod = runtime.getRiMethod(snippet);
-            if (snippetRiMethod.compilerStorage().get(Graph.class) == null) {
-                buildSnippetGraph(snippetRiMethod, runtime, target, pool);
-            }
-        }
-    }
-
-    private static void installSubstitution(GraalRuntime runtime, CiTarget target, Class< ? extends SnippetsInterface> clazz,
-                    BoxingMethodPool pool, Class<?> original) throws GraalInternalError {
-        for (Method snippet : clazz.getDeclaredMethods()) {
-            try {
-                Method method = original.getDeclaredMethod(snippet.getName(), snippet.getParameterTypes());
-                if (!method.getReturnType().isAssignableFrom(snippet.getReturnType())) {
-                    throw new RuntimeException("Snippet has incompatible return type");
-                }
-                int modifiers = snippet.getModifiers();
-                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
-                    throw new RuntimeException("Snippet must not be abstract or native");
-                }
-                RiResolvedMethod snippetRiMethod = runtime.getRiMethod(snippet);
-                StructuredGraph graph = buildSnippetGraph(snippetRiMethod, runtime, target, pool);
-                runtime.getRiMethod(method).compilerStorage().put(Graph.class, graph);
-            } catch (NoSuchMethodException e) {
-                throw new RuntimeException("Could not resolve method to substitute with: " + snippet.getName(), e);
-            }
-        }
-    }
-
-    private static StructuredGraph buildSnippetGraph(final RiResolvedMethod snippetRiMethod, final GraalRuntime runtime, final CiTarget target, final BoxingMethodPool pool) {
-        return Debug.scope("BuildSnippetGraph", snippetRiMethod, new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() throws Exception {
-                GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault();
-                GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE);
-                StructuredGraph graph = new StructuredGraph(snippetRiMethod);
-                graphBuilder.apply(graph);
-
-                Debug.dump(graph, "%s: %s", snippetRiMethod.name(), GraphBuilderPhase.class.getSimpleName());
-
-                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
-
-                for (Invoke invoke : graph.getInvokes()) {
-                    MethodCallTargetNode callTarget = invoke.callTarget();
-                    RiResolvedMethod targetMethod = callTarget.targetMethod();
-                    RiResolvedType holder = targetMethod.holder();
-                    if (holder.isSubtypeOf(runtime.getType(SnippetsInterface.class))) {
-                        StructuredGraph targetGraph = (StructuredGraph) targetMethod.compilerStorage().get(Graph.class);
-                        if (targetGraph == null) {
-                            targetGraph = buildSnippetGraph(targetMethod, runtime, target, pool);
-                        }
-                        InliningUtil.inline(invoke, targetGraph, true);
-                        if (GraalOptions.OptCanonicalizer) {
-                            new CanonicalizerPhase(target, runtime, null).apply(graph);
-                        }
-                    }
-                }
-
-                new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
-
-                Debug.dump(graph, "%s: %s", snippetRiMethod.name(), GraphBuilderPhase.class.getSimpleName());
-                new DeadCodeEliminationPhase().apply(graph);
-                if (GraalOptions.OptCanonicalizer) {
-                    new CanonicalizerPhase(target, runtime, null).apply(graph);
-                }
-
-                for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
-                    end.disableSafepoint();
-                }
-
-                new InsertStateAfterPlaceholderPhase().apply(graph);
-
-                Debug.dump(graph, "%s: Final", snippetRiMethod.name());
-
-                snippetRiMethod.compilerStorage().put(Graph.class, graph);
-
-                return graph;
-            }
-        });
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Word.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,180 @@
+/*
+ * 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.snippets;
+
+import static com.oracle.graal.snippets.Word.Opcode.*;
+
+import java.lang.annotation.*;
+
+/**
+ * Special type for use in snippets to represent machine word sized data.
+ */
+public final class Word {
+
+    /**
+     * Links a method to a canonical operation represented by an {@link Opcode} value.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    public @interface Operation {
+        Opcode value();
+    }
+
+    /**
+     * The canonical {@link Operation} represented by a method in the {@link Word} class.
+     */
+    public enum Opcode {
+        ZERO,
+        W2A,
+        A2W,
+        L2W,
+        I2W,
+        W2L,
+        W2I,
+        PLUS,
+        MINUS,
+        BELOW,
+        BELOW_EQUAL,
+        ABOVE,
+        ABOVE_EQUAL;
+    }
+
+    private Word(long value, Object object) {
+        assert object == null || value == 0L;
+        this.value = value;
+        this.object = object;
+    }
+
+    private final long value;
+    private final Object object;
+
+    @Operation(ZERO)
+    public static Word zero() {
+        return new Word(0L, null);
+    }
+
+    @Operation(W2A)
+    public Object toObject() {
+        assert value == 0L;
+        return object;
+    }
+
+    @Operation(A2W)
+    public static Word fromObject(Object value) {
+        return new Word(0L, value);
+    }
+
+    @Operation(L2W)
+    public static Word fromLong(long value) {
+        return new Word(value, null);
+    }
+
+    @Operation(I2W)
+    public static Word fromInt(int value) {
+        return new Word(value, null);
+    }
+
+    @Operation(W2I)
+    public int toInt() {
+        assert object == null;
+        return (int) value;
+    }
+
+    @Operation(W2L)
+    public long toLong() {
+        assert object == null;
+        return value;
+    }
+
+    @Operation(ABOVE)
+    public boolean above(Word other) {
+        assert object == null;
+        assert other.object == null;
+        long a = value;
+        long b = other.value;
+        return (a > b) ^ ((a < 0) != (b < 0));
+    }
+
+    @Operation(ABOVE_EQUAL)
+    public boolean aboveOrEqual(Word other) {
+        assert object == null;
+        assert other.object == null;
+        long a = value;
+        long b = other.value;
+        return (a >= b) ^ ((a < 0) != (b < 0));
+    }
+
+    @Operation(BELOW)
+    public boolean below(Word other) {
+        assert object == null;
+        assert other.object == null;
+        long a = value;
+        long b = other.value;
+        return (a < b) ^ ((a < 0) != (b < 0));
+    }
+
+    @Operation(BELOW_EQUAL)
+    public boolean belowOrEqual(Word other) {
+        assert object == null;
+        assert other.object == null;
+        long a = value;
+        long b = other.value;
+        return (a <= b) ^ ((a < 0) != (b < 0));
+    }
+
+    @Operation(PLUS)
+    public Word plus(int addend) {
+        assert object == null;
+        return new Word(value + addend, null);
+    }
+
+    @Operation(PLUS)
+    public Word plus(long addend) {
+        assert object == null;
+        return new Word(value + addend, null);
+    }
+
+    @Operation(PLUS)
+    public Word plus(Word addend) {
+        assert object == null;
+        return new Word(value + addend.value, null);
+    }
+
+    @Operation(MINUS)
+    public Word minus(int addend) {
+        assert object == null;
+        return new Word(value - addend, null);
+    }
+
+    @Operation(MINUS)
+    public Word minus(long addend) {
+        assert object == null;
+        return new Word(value - addend, null);
+    }
+
+    @Operation(MINUS)
+    public Word minus(Word addend) {
+        assert object == null;
+        return new Word(value - addend.value, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,267 @@
+/*
+ * 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.snippets;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.PhiNode.PhiType;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.calc.ConvertNode.Op;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.Word.Opcode;
+import com.oracle.graal.snippets.Word.Operation;
+
+/**
+ * Transforms all uses of the {@link Word} class into unsigned
+ * operations on {@code int} or {@code long} values, depending
+ * on the word kind of the underlying platform.
+ */
+public class WordTypeRewriterPhase extends Phase {
+
+    private final Kind wordKind;
+    private final ResolvedJavaType wordType;
+
+    public WordTypeRewriterPhase(Kind wordKind, ResolvedJavaType wordType) {
+        this.wordKind = wordKind;
+        this.wordType = wordType;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (Node n : graph.getNodes()) {
+            if (n instanceof ValueNode) {
+                ValueNode valueNode = (ValueNode) n;
+                if (isWord(valueNode)) {
+                    changeToWord(valueNode);
+                }
+            }
+        }
+
+        // Remove unnecessary/redundant unsafe casts
+        for (UnsafeCastNode unsafeCastNode : graph.getNodes().filter(UnsafeCastNode.class).snapshot()) {
+            if (!unsafeCastNode.isDeleted() && unsafeCastNode.object().stamp() == unsafeCastNode.stamp()) {
+                graph.replaceFloating(unsafeCastNode, unsafeCastNode.object());
+            }
+        }
+
+        for (MethodCallTargetNode callTargetNode : graph.getNodes(MethodCallTargetNode.class).snapshot()) {
+            ResolvedJavaMethod targetMethod = callTargetNode.targetMethod();
+            Operation operation = targetMethod.getAnnotation(Word.Operation.class);
+            if (operation != null) {
+                NodeInputList<ValueNode> arguments = callTargetNode.arguments();
+                Invoke invoke = (Invoke) callTargetNode.usages().first();
+                assert invoke != null : callTargetNode.targetMethod();
+
+                Opcode opcode = operation.value();
+                switch (opcode) {
+                    case ZERO: {
+                        assert arguments.size() == 0;
+                        invoke.intrinsify(wordKind.isLong() ? ConstantNode.forLong(0L, graph) : ConstantNode.forInt(0, graph));
+                        break;
+                    }
+
+                    case ABOVE: {
+                        assert arguments.size() == 2;
+                        invoke.intrinsify(compare(Condition.AT, graph, arguments.first(), arguments.last()));
+                        break;
+                    }
+
+                    case ABOVE_EQUAL: {
+                        assert arguments.size() == 2;
+                        invoke.intrinsify(compare(Condition.AE, graph, arguments.first(), arguments.last()));
+                        break;
+                    }
+
+                    case BELOW: {
+                        assert arguments.size() == 2;
+                        invoke.intrinsify(compare(Condition.BT, graph, arguments.first(), arguments.last()));
+                        break;
+                    }
+
+                    case BELOW_EQUAL: {
+                        assert arguments.size() == 2;
+                        invoke.intrinsify(compare(Condition.BE, graph, arguments.first(), arguments.last()));
+                        break;
+                    }
+
+                    case PLUS: {
+                        ValueNode addend = asWordKind(graph, arguments.last());
+                        IntegerAddNode op = graph.unique(new IntegerAddNode(wordKind, arguments.first(), addend));
+                        invoke.intrinsify(op);
+                        break;
+                    }
+
+                    case W2A: {
+                        assert arguments.size() == 1;
+                        ValueNode value = arguments.first();
+                        ResolvedJavaType targetType = (ResolvedJavaType) targetMethod.signature().returnType(targetMethod.holder());
+                        UnsafeCastNode cast = graph.unique(new UnsafeCastNode(value, targetType));
+                        invoke.intrinsify(cast);
+                        break;
+                    }
+
+                    case W2I: {
+                        assert arguments.size() == 1;
+                        ValueNode value = arguments.first();
+                        ValueNode intValue = fromWordKindTo(graph, value, Kind.Int);
+                        invoke.intrinsify(intValue);
+                        break;
+                    }
+
+                    case W2L: {
+                        assert arguments.size() == 1;
+                        ValueNode value = arguments.first();
+                        ValueNode longValue = fromWordKindTo(graph, value, Kind.Long);
+                        invoke.intrinsify(longValue);
+                        break;
+                    }
+
+                    case A2W: {
+                        assert arguments.size() == 1;
+                        ValueNode value = arguments.first();
+                        assert value.kind() == Kind.Object : value + ", " + targetMethod;
+                        UnsafeCastNode cast = graph.unique(new UnsafeCastNode(value, wordType));
+                        invoke.intrinsify(cast);
+                        break;
+                    }
+
+                    case L2W: {
+                        assert arguments.size() == 1;
+                        ValueNode value = arguments.first();
+                        assert value.kind() == Kind.Long;
+                        ValueNode wordValue = asWordKind(graph, value);
+                        invoke.intrinsify(wordValue);
+                        break;
+                    }
+
+                    case I2W: {
+                        assert arguments.size() == 1;
+                        ValueNode value = arguments.first();
+                        assert value.kind() == Kind.Int;
+                        invoke.intrinsify(asWordKind(graph, value));
+                        break;
+                    }
+
+                    default: {
+                        throw new GraalInternalError("Unknown opcode: %s", opcode);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates comparison node for a given condition and two input values.
+     */
+    private ValueNode compare(Condition condition, StructuredGraph graph, ValueNode left, ValueNode right) {
+        assert condition.isUnsigned() : condition;
+        assert left.kind() == wordKind;
+        assert right.kind() == wordKind;
+
+        // mirroring gets the condition into canonical form
+        boolean mirror = condition.canonicalMirror();
+
+        ValueNode a = mirror ? right : left;
+        ValueNode b = mirror ? left : right;
+
+        MaterializeNode materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b)), graph);
+
+        ValueNode op;
+        if (condition.canonicalNegate()) {
+            op = (ValueNode) materialize.negate();
+        } else {
+            op = materialize;
+        }
+        return op;
+    }
+
+    /**
+     * Adds a node if necessary to convert a given value into the word kind.
+     *
+     * @return the node for {@code value} producing a value of word kind
+     */
+    private ValueNode asWordKind(StructuredGraph graph, ValueNode value) {
+        if (value.kind() != wordKind) {
+            Op op;
+            if (wordKind.isLong()) {
+                assert value.kind().isInt();
+                op = Op.I2L;
+            } else {
+                assert wordKind.isInt();
+                assert value.kind().isLong();
+                op = Op.L2I;
+            }
+            return graph.unique(new ConvertNode(op, value));
+        }
+        return value;
+    }
+
+    private static ValueNode fromWordKindTo(StructuredGraph graph, ValueNode value, Kind to) {
+        Kind from = value.kind();
+        if (from != to) {
+            Op op;
+            if (from.isLong()) {
+                op = Op.L2I;
+            } else {
+                assert from.isInt();
+                op = Op.I2L;
+            }
+            return graph.unique(new ConvertNode(op, value));
+        }
+        return value;
+    }
+
+    public static boolean isWord(ValueNode node) {
+        if (node.kind().isObject()) {
+            return isWord(node.objectStamp().type());
+        }
+        return false;
+    }
+
+    public static boolean isWord(ResolvedJavaType type) {
+        if (type != null && type.toJava() == Word.class) {
+            return true;
+        }
+        return false;
+    }
+
+    private void changeToWord(ValueNode valueNode) {
+        assert !(valueNode instanceof ConstantNode);
+        valueNode.setStamp(StampFactory.forKind(wordKind));
+
+        // Propagate word kind.
+        for (Node n : valueNode.usages()) {
+            if (n instanceof PhiNode) {
+                changeToWord((ValueNode) n);
+                PhiNode phi = (PhiNode) n;
+                assert phi.type() == PhiType.Value;
+            } else if (n instanceof ReturnNode) {
+                changeToWord((ValueNode) n);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/ExplodeLoopNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,68 @@
+/*
+ * 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.snippets.nodes;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.Snippet.Parameter;
+
+/**
+ * Placeholder node to denote to snippet preparation that the following loop
+ * must be completely unrolled.
+ *
+ * @see Parameter#multiple()
+ */
+public final class ExplodeLoopNode extends FixedWithNextNode {
+
+    public ExplodeLoopNode() {
+        super(StampFactory.forVoid());
+    }
+
+    public LoopBeginNode findLoopBegin() {
+        Node next = next();
+        ArrayList<Node> succs = new ArrayList<>();
+        while (!(next instanceof LoopBeginNode)) {
+            assert next != null : "cannot find loop after " + this;
+            for (Node n : next.cfgSuccessors()) {
+                succs.add(n);
+            }
+            if (succs.size() == 1) {
+                next = succs.get(0);
+            } else {
+                return null;
+            }
+        }
+        return (LoopBeginNode) next;
+    }
+
+    /**
+     * A call to this method must be placed immediately prior to the loop that is to be exploded.
+     */
+    @NodeIntrinsic
+    public static void explodeLoop() {
+        throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/LoadSnippetParameterNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009, 2011, 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.snippets.nodes;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.snippets.Snippet.Parameter;
+
+/**
+ * Implements the semantics of a snippet {@link Parameter} whose {@link Parameter#multiple()} element is {@code true}.
+ */
+public final class LoadSnippetParameterNode extends FixedWithNextNode implements Canonicalizable {
+
+    @Input private ValueNode index;
+
+    private final LocalNode[] locals;
+
+    public LoadSnippetParameterNode(LocalNode[] locals, ValueNode index, Stamp stamp) {
+        super(stamp);
+        this.index = index;
+        this.locals = locals;
+    }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (index.isConstant()) {
+            return locals[index.asConstant().asInt()];
+        }
+        return this;
+    }
+}
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MathIntrinsicNode.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/nodes/MathIntrinsicNode.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,9 @@
 
 import static com.oracle.graal.lir.amd64.AMD64Arithmetic.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.graal.compiler.target.amd64.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.AMD64Arithmetic.Op2Reg;
@@ -35,7 +36,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.snippets.target.amd64.*;
 
-public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, AMD64LIRLowerable {
+public class MathIntrinsicNode extends FloatingNode implements Canonicalizable, LIRGenLowerable {
 
     @Input private ValueNode x;
     private final Operation operation;
@@ -54,17 +55,17 @@
 
     public MathIntrinsicNode(ValueNode x, Operation op) {
         super(StampFactory.forKind(x.kind()));
-        assert x.kind() == CiKind.Double;
+        assert x.kind() == Kind.Double;
         this.x = x;
         this.operation = op;
     }
 
     @Override
-    public void generateAmd64(AMD64LIRGenerator gen) {
+    public void generate(LIRGenerator gen) {
         Variable input = gen.load(gen.operand(x()));
         Variable result = gen.newVariable(kind());
         switch (operation()) {
-            case ABS:   gen.append(new Op2Reg(DAND, result, input, CiConstant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); break;
+            case ABS:   gen.append(new Op2Reg(DAND, result, input, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); break;
             case SQRT:  gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.SQRT, result, input)); break;
             case LOG:   gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.LOG, result, input)); break;
             case LOG10: gen.append(new AMD64MathIntrinsicOp(AMD64MathIntrinsicOp.Opcode.LOG10, result, input)); break;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/target/amd64/AMD64MathIntrinsicOp.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.snippets.target.amd64;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.util.*;
 
 import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
@@ -40,15 +40,15 @@
         LOG, LOG10;
     }
 
-    public AMD64MathIntrinsicOp(Opcode opcode, CiValue result, CiValue input) {
-        super(opcode, new CiValue[] {result}, null, new CiValue[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
+    public AMD64MathIntrinsicOp(Opcode opcode, Value result, Value input) {
+        super(opcode, new Value[] {result}, null, new Value[] {input}, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS);
     }
 
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         Opcode opcode = (Opcode) code;
-        CiValue result = output(0);
-        CiValue input = input(0);
+        Value result = output(0);
+        Value input = input(0);
 
         switch (opcode) {
             case SQRT:  masm.sqrtsd(asDoubleReg(result), asDoubleReg(input)); break;
--- a/graal/com.oracle.graal.snippets/test/test/com/oracle/graal/snippets/package-info.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2011, 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.
- */
-
-/**
- * Test cases for Graal snippets.
- */
-package test.com.oracle.graal.snippets;
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/BoxingEliminationTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/BoxingEliminationTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.tests;
 
-import static com.oracle.graal.graph.iterators.NodePredicates.*;
-
 import java.util.*;
 
 import org.junit.*;
@@ -32,24 +30,28 @@
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 
 /**
- * In the following tests, the usages of local variable "a" are replaced with the integer constant 0.
- * Then boxing elimination is applied and it is verified that the resulting graph is equal to the
- * graph of the method that just has a "return 1" statement in it.
+ * In the following tests, the usages of local variable "a" are replaced with the integer constant 0. Then boxing
+ * elimination is applied and it is verified that the resulting graph is equal to the graph of the method that just has
+ * a "return 1" statement in it.
  */
-public class BoxingEliminationTest extends GraphTest {
+public class BoxingEliminationTest extends GraalCompilerTest {
+
     private static final Short s = 2;
-    private static final String REFERENCE_SNIPPET = "referenceSnippet";
 
     @SuppressWarnings("all")
-    public static short referenceSnippet(short a) {
+    public static short referenceSnippet1() {
         return 1;
     }
 
+    @SuppressWarnings("all")
+    public static short referenceSnippet2() {
+        return 2;
+    }
+
     public static Short boxedShort() {
         return 1;
     }
@@ -64,30 +66,31 @@
 
     @Test
     public void test1() {
-        test("test1Snippet");
+        test("test1Snippet", "referenceSnippet1");
     }
 
     @SuppressWarnings("all")
-    public static short test1Snippet(short a) {
+    public static short test1Snippet() {
         return boxedShort();
     }
 
     @Test
     public void test2() {
-        test("test2Snippet");
+        test("test2Snippet", "referenceSnippet1");
     }
 
     @SuppressWarnings("all")
-    public static short test2Snippet(short a) {
+    public static short test2Snippet() {
         return (Short) boxedObject();
     }
+
     @Test
     public void test3() {
-        test("test3Snippet");
+        test("test3Snippet", "referenceSnippet1");
     }
 
     @SuppressWarnings("all")
-    public static short test3Snippet(short a) {
+    public static short test3Snippet() {
         short b = boxedShort();
         if (b < 0) {
             b = boxedShort();
@@ -97,15 +100,15 @@
 
     @Test
     public void test4() {
-        test("test4Snippet");
+        test("test4Snippet", "referenceSnippet2");
     }
 
     @SuppressWarnings("all")
-    public static short test4Snippet(short a) {
+    public static short test4Snippet() {
         return constantBoxedShort();
     }
 
-    private void test(final String snippet) {
+    private void test(final String snippet, final String referenceSnippet) {
         Debug.scope("BoxingEliminationTest", new DebugDumpScope(snippet), new Runnable() {
             @Override
             public void run() {
@@ -115,11 +118,6 @@
                 PhasePlan phasePlan = getDefaultPhasePlan();
                 phasePlan.addPhase(PhasePosition.AFTER_PARSING, identifyBoxingPhase);
                 identifyBoxingPhase.apply(graph);
-                LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
-                ConstantNode constant = ConstantNode.forShort((short) 0, graph);
-                for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
-                    n.replaceFirstInput(local, constant);
-                }
                 Collection<Invoke> hints = new ArrayList<>();
                 for (Invoke invoke : graph.getInvokes()) {
                     hints.add(invoke);
@@ -133,7 +131,7 @@
                 new ExpandBoxingNodesPhase(pool).apply(graph);
                 new CanonicalizerPhase(null, runtime(), null).apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
-                StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+                StructuredGraph referenceGraph = parse(referenceSnippet);
                 assertEquals(referenceGraph, graph);
             }
         });
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/CheckCastTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2011, 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.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * Tests the implementation of checkcast, allowing profiling information to
+ * be manually specified.
+ */
+public class CheckCastTest extends TypeCheckTest {
+
+    /**
+     * Enables making the target type "unknown" at compile time.
+     */
+    boolean unknown;
+
+    @Override
+    protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
+        CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first();
+        if (ccn != null) {
+            ResolvedJavaType targetClass = unknown ? null : ccn.targetClass();
+            CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.targetClassInstruction(), targetClass, ccn.object(), profile));
+            graph.replaceFixedWithFixed(ccn, ccnNew);
+        }
+        unknown = false;
+    }
+
+    @Override
+    protected void test(String name, JavaTypeProfile profile, Object... args) {
+        super.test(name, profile, args);
+        unknown = true;
+        super.test(name, profile, args);
+    }
+
+    @Test
+    public void test1() {
+        test("asNumber",    profile(),                        111);
+        test("asNumber",    profile(Integer.class),           111);
+        test("asNumber",    profile(Long.class, Short.class), 111);
+        test("asNumberExt", profile(),                        111);
+        test("asNumberExt", profile(Integer.class),           111);
+        test("asNumberExt", profile(Long.class, Short.class), 111);
+    }
+
+    @Test
+    public void test2() {
+        test("asString",    profile(),             "111");
+        test("asString",    profile(String.class), "111");
+        test("asString",    profile(String.class), "111");
+
+        final String nullString = null;
+        test("asString",    profile(),             nullString);
+        test("asString",    profile(String.class), nullString);
+        test("asString",    profile(String.class), nullString);
+
+        test("asStringExt", profile(),             "111");
+        test("asStringExt", profile(String.class), "111");
+        test("asStringExt", profile(String.class), "111");
+    }
+
+    @Test
+    public void test3() {
+        test("asNumber", profile(), "111");
+    }
+
+    @Test
+    public void test4() {
+        test("asString", profile(String.class), 111);
+    }
+
+    @Test
+    public void test5() {
+        test("asNumberExt", profile(), "111");
+    }
+
+    @Test
+    public void test6() {
+        test("asStringExt", profile(String.class), 111);
+    }
+
+    @Test
+    public void test7() {
+        Throwable throwable = new Exception();
+        test("asThrowable",   profile(),                             throwable);
+        test("asThrowable",   profile(Throwable.class),              throwable);
+        test("asThrowable",   profile(Exception.class, Error.class), throwable);
+    }
+
+    @Test
+    public void test8() {
+        test("arrayFill", profile(), new Object[100], "111");
+    }
+
+    public static Number asNumber(Object o) {
+        return (Number) o;
+    }
+
+    public static String asString(Object o) {
+        return (String) o;
+    }
+
+    public static Throwable asThrowable(Object o) {
+        return (Throwable) o;
+    }
+
+    public static ValueNode asValueNode(Object o) {
+        return (ValueNode) o;
+    }
+
+    public static Number asNumberExt(Object o) {
+        Number n = (Number) o;
+        return n.intValue() + 10;
+    }
+
+    public static String asStringExt(Object o) {
+        String s = (String) o;
+        return "#" + s;
+    }
+
+    public static Object[] arrayFill(Object[] arr, Object value) {
+        for (int i = 0; i < arr.length; i++) {
+            arr[i] = value;
+        }
+        return arr;
+    }
+
+    static class Depth1 implements Cloneable {}
+    static class Depth2 extends Depth1 {}
+    static class Depth3 extends Depth2 {}
+    static class Depth4 extends Depth3 {}
+    static class Depth5 extends Depth4 {}
+    static class Depth6 extends Depth5 {}
+    static class Depth7 extends Depth6 {}
+    static class Depth8 extends Depth7 {}
+    static class Depth9 extends Depth8 {}
+    static class Depth10 extends Depth9 {}
+    static class Depth11 extends Depth10 {}
+    static class Depth12 extends Depth11 {}
+    static class Depth13 extends Depth12 {}
+    static class Depth14 extends Depth12 {}
+
+    public static Depth12 asDepth12(Object o) {
+        return (Depth12) o;
+    }
+
+    public static Depth12[][] asDepth12Arr(Object o) {
+        return (Depth12[][]) o;
+    }
+
+    public static Cloneable asCloneable(Object o) {
+        return (Cloneable) o;
+    }
+
+    @Test
+    public void test9() {
+        Object o = new Depth13();
+        test("asDepth12",   profile(), o);
+        test("asDepth12",   profile(Depth13.class), o);
+        test("asDepth12",   profile(Depth13.class, Depth14.class), o);
+    }
+
+    @Test
+    public void test10() {
+        Object o = new Depth13[3][];
+        test("asDepth12Arr",   profile(), o);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/CompareCanonicalizerTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,78 @@
+/*
+ * 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.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.nodes.*;
+
+public class CompareCanonicalizerTest extends GraalCompilerTest {
+
+    @Test
+    public void testCanonicalComparison() {
+        StructuredGraph referenceGraph = parse("referenceCanonicalComparison");
+        for (int i = 1; i < 4; i++) {
+            StructuredGraph graph = parse("canonicalCompare" + i);
+            assertEquals(referenceGraph, graph);
+        }
+        new CanonicalizerPhase(null, runtime(), null).apply(referenceGraph);
+        for (int i = 1; i < 4; i++) {
+            StructuredGraph graph = parse("canonicalCompare" + i);
+            new CanonicalizerPhase(null, runtime(), null).apply(graph);
+            assertEquals(referenceGraph, graph);
+        }
+    }
+
+    public static int referenceCanonicalComparison(int a, int b) {
+        if (a < b) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    public static int canonicalCompare1(int a, int b) {
+        if (a >= b) {
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+
+    public static int canonicalCompare2(int a, int b) {
+        if (b > a) {
+            return 1;
+        } else {
+            return 2;
+        }
+    }
+
+    public static int canonicalCompare3(int a, int b) {
+        if (b <= a) {
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/CompiledMethodTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/CompiledMethodTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,21 +26,20 @@
 
 import org.junit.*;
 
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.InstalledCode.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiCompiledMethod.MethodInvalidatedException;
 
 /**
  * In the following tests, the usages of local variable "a" are replaced with the integer constant 0. Then
  * canonicalization is applied and it is verified that the resulting graph is equal to the graph of the method that just
  * has a "return 1" statement in it.
  */
-public class CompiledMethodTest extends GraphTest {
+public class CompiledMethodTest extends GraalCompilerTest {
 
     public static Object testMethod(Object arg1, Object arg2, Object arg3) {
         return arg1 + " " + arg2 + " " + arg3;
@@ -61,15 +60,14 @@
         for (Node node : graph.getNodes()) {
             if (node instanceof ConstantNode) {
                 ConstantNode constant = (ConstantNode) node;
-                if (constant.kind() == CiKind.Object && " ".equals(constant.value.asObject())) {
+                if (constant.kind() == Kind.Object && " ".equals(constant.value.asObject())) {
                     graph.replaceFloating(constant, ConstantNode.forObject("-", runtime, graph));
                 }
             }
         }
 
-        final RiResolvedMethod riMethod = runtime.getRiMethod(method);
-        CiTargetMethod targetMethod = runtime.compile(riMethod, graph);
-        RiCompiledMethod compiledMethod = runtime.addMethod(riMethod, targetMethod);
+        final ResolvedJavaMethod riMethod = runtime.getResolvedJavaMethod(method);
+        InstalledCode compiledMethod = getCode(riMethod, graph);
         try {
             Object result = compiledMethod.execute("1", "2", "3");
             Assert.assertEquals("1-2-3", result);
@@ -82,9 +80,8 @@
     public void test3() {
         Method method = getMethod("testMethod");
         final StructuredGraph graph = parse(method);
-        final RiResolvedMethod riMethod = runtime.getRiMethod(method);
-        CiTargetMethod targetMethod = runtime.compile(riMethod, graph);
-        RiCompiledMethod compiledMethod = runtime.addMethod(riMethod, targetMethod);
+        final ResolvedJavaMethod riMethod = runtime.getResolvedJavaMethod(method);
+        InstalledCode compiledMethod = getCode(riMethod, graph);
         try {
             Object result = compiledMethod.executeVarargs("1", "2", "3");
             Assert.assertEquals("1 2 3", result);
@@ -97,9 +94,8 @@
     public void test4() {
         Method method = getMethod("testMethodVirtual");
         final StructuredGraph graph = parse(method);
-        final RiResolvedMethod riMethod = runtime.getRiMethod(method);
-        CiTargetMethod targetMethod = runtime.compile(riMethod, graph);
-        RiCompiledMethod compiledMethod = runtime.addMethod(riMethod, targetMethod);
+        final ResolvedJavaMethod riMethod = runtime.getResolvedJavaMethod(method);
+        InstalledCode compiledMethod = getCode(riMethod, graph);
         try {
             f1 = "0";
             Object result = compiledMethod.executeVarargs(this, "1", "2", "3");
@@ -112,7 +108,7 @@
     @Test
     public void test2() throws NoSuchMethodException, SecurityException {
         Method method = CompilableObjectImpl.class.getDeclaredMethod("executeHelper", ObjectCompiler.class, String.class);
-        RiResolvedMethod riMethod = runtime.getRiMethod(method);
+        ResolvedJavaMethod riMethod = runtime.getResolvedJavaMethod(method);
         StructuredGraph graph = new StructuredGraph(riMethod);
         new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
         new CanonicalizerPhase(null, runtime, null).apply(graph);
@@ -121,15 +117,13 @@
         for (Node node : graph.getNodes()) {
             if (node instanceof ConstantNode) {
                 ConstantNode constant = (ConstantNode) node;
-                if (constant.kind() == CiKind.Object && "1 ".equals(constant.value.asObject())) {
+                if (constant.kind() == Kind.Object && "1 ".equals(constant.value.asObject())) {
                     graph.replaceFloating(constant, ConstantNode.forObject("1-", runtime, graph));
                 }
             }
         }
 
-        CiTargetMethod targetMethod = runtime.compile(riMethod, graph);
-        final RiCompiledMethod compiledMethod = runtime.addMethod(riMethod, targetMethod);
-
+        InstalledCode compiledMethod = getCode(riMethod, graph);
         final CompilableObject compilableObject = new CompilableObjectImpl(0);
 
         Object result;
@@ -181,9 +175,9 @@
 
     private final class ObjectCompilerImpl implements ObjectCompiler {
 
-        private final RiCompiledMethod compiledMethod;
+        private final InstalledCode compiledMethod;
 
-        private ObjectCompilerImpl(RiCompiledMethod compiledMethod) {
+        private ObjectCompilerImpl(InstalledCode compiledMethod) {
             this.compiledMethod = compiledMethod;
         }
 
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ConditionTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ConditionTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -28,7 +28,7 @@
 
 import org.junit.*;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.calc.*;
 
 
@@ -40,10 +40,10 @@
         for (Condition c1 : Condition.values()) {
             for (Condition c2 : Condition.values()) {
                 boolean implies = c1.implies(c2);
-                if (implies && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) {
-                    for (int i = 0; i < 10000; i++) {
-                        CiConstant a = CiConstant.forInt(rand.nextInt());
-                        CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt());
+                if (implies) {
+                    for (int i = 0; i < 1000; i++) {
+                        Constant a = Constant.forInt(rand.nextInt());
+                        Constant b = Constant.forInt(i < 100 ? a.asInt() : rand.nextInt());
                         boolean result1 = c1.foldCondition(a, b, null, false);
                         boolean result2 = c2.foldCondition(a, b, null, false);
                         if (result1 && implies) {
@@ -62,10 +62,10 @@
             for (Condition c2 : Condition.values()) {
                 Condition join = c1.join(c2);
                 assertTrue(join == c2.join(c1));
-                if (join != null && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) {
-                    for (int i = 0; i < 10000; i++) {
-                        CiConstant a = CiConstant.forInt(rand.nextInt());
-                        CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt());
+                if (join != null) {
+                    for (int i = 0; i < 1000; i++) {
+                        Constant a = Constant.forInt(rand.nextInt());
+                        Constant b = Constant.forInt(i < 100 ? a.asInt() : rand.nextInt());
                         boolean result1 = c1.foldCondition(a, b, null, false);
                         boolean result2 = c2.foldCondition(a, b, null, false);
                         boolean resultJoin = join.foldCondition(a, b, null, false);
@@ -85,10 +85,10 @@
             for (Condition c2 : Condition.values()) {
                 Condition meet = c1.meet(c2);
                 assertTrue(meet == c2.meet(c1));
-                if (meet != null && c1 != Condition.OF && c2 != Condition.OF && c1 != Condition.NOF && c2 != Condition.NOF) {
-                    for (int i = 0; i < 10000; i++) {
-                        CiConstant a = CiConstant.forInt(rand.nextInt());
-                        CiConstant b = CiConstant.forInt(i < 100 ? a.asInt() : rand.nextInt());
+                if (meet != null) {
+                    for (int i = 0; i < 1000; i++) {
+                        Constant a = Constant.forInt(rand.nextInt());
+                        Constant b = Constant.forInt(i < 100 ? a.asInt() : rand.nextInt());
                         boolean result1 = c1.foldCondition(a, b, null, false);
                         boolean result2 = c2.foldCondition(a, b, null, false);
                         boolean resultMeet = meet.foldCondition(a, b, null, false);
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/DegeneratedLoopsTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/DegeneratedLoopsTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,10 @@
  */
 package com.oracle.graal.compiler.tests;
 
-import static com.oracle.graal.graph.iterators.NodePredicates.*;
-
 import org.junit.*;
 
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -36,13 +33,13 @@
  * Then canonicalization is applied and it is verified that the resulting graph is equal to the
  * graph of the method that just has a "return 1" statement in it.
  */
-public class DegeneratedLoopsTest extends GraphTest {
+public class DegeneratedLoopsTest extends GraalCompilerTest {
 
     private static final String REFERENCE_SNIPPET = "referenceSnippet";
 
     @SuppressWarnings("all")
     public static int referenceSnippet(int a) {
-        return 1;
+        return a;
     }
 
     @Test
@@ -76,19 +73,19 @@
 
     }
 
-    private void test(String snippet) {
-        StructuredGraph graph = parse(snippet);
-        Debug.dump(graph, "Graph");
-        LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
-        ConstantNode constant = ConstantNode.forInt(0, graph);
-        for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
-            n.replaceFirstInput(local, constant);
-        }
-        for (Invoke invoke : graph.getInvokes()) {
-            invoke.intrinsify(null);
-        }
-        new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); Debug.dump(referenceGraph, "Graph");
-        assertEquals(referenceGraph, graph);
+    private void test(final String snippet) {
+        Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet), new Runnable() {
+            public void run() {
+                StructuredGraph graph = parse(snippet);
+                Debug.dump(graph, "Graph");
+                for (Invoke invoke : graph.getInvokes()) {
+                    invoke.intrinsify(null);
+                }
+                new CanonicalizerPhase(null, runtime(), null).apply(graph);
+                StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+                Debug.dump(referenceGraph, "Graph");
+                assertEquals(referenceGraph, graph);
+            }
+        });
     }
 }
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,22 +26,22 @@
 
 import org.junit.Test;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.max.cri.ci.*;
 
 /**
  * In these test cases the probability of all invokes is set to a high value, such that an InliningPhase should inline them all.
  * After that, the EscapeAnalysisPhase is expected to remove all allocations and return the correct values.
  */
-public class EscapeAnalysisTest extends GraphTest {
+public class EscapeAnalysisTest extends GraalCompilerTest {
 
     @Test
     public void test1() {
-        test("test1Snippet", CiConstant.forInt(101));
+        test("test1Snippet", Constant.forInt(101));
     }
 
     @SuppressWarnings("all")
@@ -52,7 +52,7 @@
 
     @Test
     public void test2() {
-        test("test2Snippet", CiConstant.forInt(0));
+        test("test2Snippet", Constant.forInt(0));
     }
 
     @SuppressWarnings("all")
@@ -63,7 +63,7 @@
 
     @Test
     public void test3() {
-        test("test3Snippet", CiConstant.forObject(null));
+        test("test3Snippet", Constant.forObject(null));
     }
 
     @SuppressWarnings("all")
@@ -74,7 +74,7 @@
 
     @Test
     public void testMonitor() {
-        test("testMonitorSnippet", CiConstant.forInt(0));
+        test("testMonitorSnippet", Constant.forInt(0));
     }
 
     private static native void notInlineable();
@@ -95,7 +95,7 @@
     }
 
     public void testMonitor2() {
-        test("testMonitor2Snippet", CiConstant.forInt(0));
+        test("testMonitor2Snippet", Constant.forInt(0));
     }
 
     /**
@@ -116,31 +116,35 @@
         }
     }
 
-    private void test(String snippet, CiConstant expectedResult) {
-        StructuredGraph graph = parse(snippet);
-        for (Invoke n : graph.getInvokes()) {
-            n.node().setProbability(100000);
-        }
+    private void test(final String snippet, final Constant expectedResult) {
+        Debug.scope("EscapeAnalysisTest", new DebugDumpScope(snippet), new Runnable() {
+            public void run() {
+                StructuredGraph graph = parse(snippet);
+                for (Invoke n : graph.getInvokes()) {
+                    n.node().setProbability(100000);
+                }
 
-        new InliningPhase(null, runtime(), null, null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
-        new DeadCodeEliminationPhase().apply(graph);
-        Debug.dump(graph, "Graph");
-        new EscapeAnalysisPhase(null, runtime(), null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
-        Debug.dump(graph, "Graph");
-        int retCount = 0;
-        for (ReturnNode ret : graph.getNodes(ReturnNode.class)) {
-            Assert.assertTrue(ret.result().isConstant());
-            Assert.assertEquals(ret.result().asConstant(), expectedResult);
-            retCount++;
-        }
-        Assert.assertEquals(1, retCount);
-        int newInstanceCount = 0;
-        for (@SuppressWarnings("unused") NewInstanceNode n : graph.getNodes(NewInstanceNode.class)) {
-            newInstanceCount++;
-        }
-        for (@SuppressWarnings("unused") NewObjectArrayNode n : graph.getNodes(NewObjectArrayNode.class)) {
-            newInstanceCount++;
-        }
-        Assert.assertEquals(0, newInstanceCount);
+                new InliningPhase(null, runtime(), null, null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
+                new DeadCodeEliminationPhase().apply(graph);
+                Debug.dump(graph, "Graph");
+                new EscapeAnalysisPhase(null, runtime(), null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
+                Debug.dump(graph, "Graph");
+                int retCount = 0;
+                for (ReturnNode ret : graph.getNodes(ReturnNode.class)) {
+                    Assert.assertTrue(ret.result().isConstant());
+                    Assert.assertEquals(ret.result().asConstant(), expectedResult);
+                    retCount++;
+                }
+                Assert.assertEquals(1, retCount);
+                int newInstanceCount = 0;
+                for (@SuppressWarnings("unused") NewInstanceNode n : graph.getNodes(NewInstanceNode.class)) {
+                    newInstanceCount++;
+                }
+                for (@SuppressWarnings("unused") NewObjectArrayNode n : graph.getNodes(NewObjectArrayNode.class)) {
+                    newInstanceCount++;
+                }
+                Assert.assertEquals(0, newInstanceCount);
+            }
+        });
     }
 }
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -25,6 +25,7 @@
 import org.junit.*;
 
 import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -50,28 +51,32 @@
         test("test1Snippet");
     }
 
-    private void test(String snippet) {
-        StructuredGraph graph = parse(snippet);
-        new LoweringPhase(runtime()).apply(graph);
-        new FloatingReadPhase().apply(graph);
+    private void test(final String snippet) {
+        Debug.scope("FloatingReadTest", new DebugDumpScope(snippet), new Runnable() {
+            public void run() {
+                StructuredGraph graph = parse(snippet);
+                new LoweringPhase(runtime(), null).apply(graph);
+                new FloatingReadPhase().apply(graph);
 
-        ReturnNode returnNode = null;
-        MonitorExitNode monitor = null;
+                ReturnNode returnNode = null;
+                MonitorExitNode monitor = null;
 
-        for (Node n : graph.getNodes()) {
-            if (n instanceof ReturnNode) {
-                returnNode = (ReturnNode) n;
-            } else if (n instanceof MonitorExitNode) {
-                monitor = (MonitorExitNode) n;
-            }
-        }
+                for (Node n : graph.getNodes()) {
+                    if (n instanceof ReturnNode) {
+                        returnNode = (ReturnNode) n;
+                    } else if (n instanceof MonitorExitNode) {
+                        monitor = (MonitorExitNode) n;
+                    }
+                }
 
-        Assert.assertNotNull(returnNode);
-        Assert.assertNotNull(monitor);
-        Assert.assertTrue(returnNode.result() instanceof FloatingReadNode);
+                Assert.assertNotNull(returnNode);
+                Assert.assertNotNull(monitor);
+                Assert.assertTrue(returnNode.result() instanceof FloatingReadNode);
 
-        FloatingReadNode read = (FloatingReadNode) returnNode.result();
+                FloatingReadNode read = (FloatingReadNode) returnNode.result();
 
-        assertOrderedAfterSchedule(graph, read, monitor);
+                assertOrderedAfterSchedule(graph, read, monitor);
+            }
+        });
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraalCompilerTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2011, 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.compiler.tests;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import junit.framework.*;
+
+import com.oracle.graal.api.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.graal.compiler.schedule.*;
+import com.oracle.graal.cri.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Node.Verbosity;
+import com.oracle.graal.java.*;
+import com.oracle.graal.lir.cfg.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Base class for Graal compiler unit tests. These are white box tests
+ * for Graal compiler transformations. The general pattern for a test is:
+ * <ol>
+ * <li>Create a graph by {@linkplain #parse(String) parsing} a method.</li>
+ * <li>Manually modify the graph (e.g. replace a parameter node with a constant).</li>
+ * <li>Apply a transformation to the graph.</li>
+ * <li>Assert that the transformed graph is equal to an expected graph.</li>
+ * </ol>
+ * <p>
+ * See {@link InvokeTest} as an example.
+ * <p>
+ * The tests can be run in Eclipse with the "Compiler Unit Test" Eclipse
+ * launch configuration found in the top level of this project or by
+ * running {@code mx unittest} on the command line.
+ */
+public abstract class GraalCompilerTest {
+
+    protected final ExtendedRiRuntime runtime;
+
+    public GraalCompilerTest() {
+        Debug.enable();
+        this.runtime = Graal.getRuntime().getCapability(ExtendedRiRuntime.class);
+    }
+
+    protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
+        String expectedString = getCanonicalGraphString(expected);
+        String actualString = getCanonicalGraphString(graph);
+        String mismatchString = "mismatch in graphs:\n========= expected =========\n" + expectedString + "\n\n========= actual =========\n" + actualString;
+
+        if (expected.getNodeCount() != graph.getNodeCount()) {
+            Debug.dump(expected, "Node count not matching - expected");
+            Debug.dump(graph, "Node count not matching - actual");
+            Assert.fail("Graphs do not have the same number of nodes: " + expected.getNodeCount() + " vs. " + graph.getNodeCount() + "\n" + mismatchString);
+        }
+        if (!expectedString.equals(actualString)) {
+            Debug.dump(expected, "mismatching graphs - expected");
+            Debug.dump(graph, "mismatching graphs - actual");
+            Assert.fail(mismatchString);
+        }
+    }
+
+    protected void assertConstantReturn(StructuredGraph graph, int value) {
+        String graphString = getCanonicalGraphString(graph);
+        Assert.assertEquals("unexpected number of ReturnNodes: " + graphString, graph.getNodes(ReturnNode.class).count(), 1);
+        ValueNode result = graph.getNodes(ReturnNode.class).first().result();
+        Assert.assertTrue("unexpected ReturnNode result node: " + graphString, result.isConstant());
+        Assert.assertEquals("unexpected ReturnNode result kind: " + graphString, result.asConstant().kind, Kind.Int);
+        Assert.assertEquals("unexpected ReturnNode result: " + graphString, result.asConstant().asInt(), value);
+    }
+
+    protected static String getCanonicalGraphString(StructuredGraph graph) {
+        SchedulePhase schedule = new SchedulePhase();
+        schedule.apply(graph);
+
+        NodeMap<Integer> canonicalId = graph.createNodeMap();
+        int nextId = 0;
+
+        StringBuilder result = new StringBuilder();
+        for (Block block : schedule.getCFG().getBlocks()) {
+            result.append("Block " + block + " ");
+            if (block == schedule.getCFG().getStartBlock()) {
+                result.append("* ");
+            }
+            result.append("-> ");
+            for (Block succ : block.getSuccessors()) {
+                result.append(succ + " ");
+            }
+            result.append("\n");
+            for (Node node : schedule.getBlockToNodesMap().get(block)) {
+                int id;
+                if (canonicalId.get(node) != null) {
+                    id = canonicalId.get(node);
+                } else {
+                    id = nextId++;
+                    canonicalId.set(node, id);
+                }
+                String name = node instanceof ConstantNode ? node.toString(Verbosity.Name) : node.getClass().getSimpleName();
+                result.append("  " + id + "|" + name + "    (" + node.usages().size() + ")\n");
+            }
+        }
+        return result.toString();
+    }
+
+    protected ExtendedRiRuntime runtime() {
+        return runtime;
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     *
+     * @param methodName the name of the method in {@code this.getClass()} to be parsed
+     */
+    protected StructuredGraph parse(String methodName) {
+        return parse(getMethod(methodName));
+    }
+
+    protected Method getMethod(String methodName) {
+        Method found = null;
+        for (Method m : this.getClass().getMethods()) {
+            if (m.getName().equals(methodName)) {
+                Assert.assertNull(found);
+                found = m;
+            }
+        }
+        if (found != null) {
+            return found;
+        } else {
+            throw new RuntimeException("method not found: " + methodName);
+        }
+    }
+
+    private static int compilationId = 0;
+
+    protected void assertEquals(Object expected, Object actual) {
+        Assert.assertEquals(expected, actual);
+    }
+
+    protected void test(String name, Object... args) {
+        Method method = getMethod(name);
+        Object expect = null;
+        Throwable exception = null;
+        try {
+            // This gives us both the expected return value as well as ensuring that the method to be compiled is fully resolved
+            expect = method.invoke(null, args);
+        } catch (InvocationTargetException e) {
+            exception = e.getTargetException();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        InstalledCode compiledMethod = getCode(runtime.getResolvedJavaMethod(method), parse(method));
+
+        if (exception != null) {
+            try {
+                compiledMethod.executeVarargs(args);
+                Assert.fail("expected " + exception);
+            } catch (Throwable e) {
+                Assert.assertEquals(exception.getClass(), e.getClass());
+            }
+        } else {
+            Object actual = compiledMethod.executeVarargs(args);
+            assertEquals(expect, actual);
+        }
+    }
+
+    private Map<ResolvedJavaMethod, InstalledCode> cache = new HashMap<>();
+
+    /**
+     * Gets installed code for a given method and graph, compiling it first if necessary.
+     */
+    protected InstalledCode getCode(final ResolvedJavaMethod method, final StructuredGraph graph) {
+        return getCode(method, graph, false);
+    }
+
+    /**
+     * Gets installed code for a given method and graph, compiling it first if necessary.
+     *
+     * @param forceCompile specifies whether to ignore any previous code cached for the (method, key) pair
+     */
+    protected InstalledCode getCode(final ResolvedJavaMethod method, final StructuredGraph graph, boolean forceCompile) {
+        if (!forceCompile) {
+            InstalledCode cached = cache.get(method);
+            if (cached != null && cached.isValid()) {
+                return cached;
+            }
+        }
+        InstalledCode installedCode = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(compilationId++), true), new Callable<InstalledCode>() {
+            public InstalledCode call() throws Exception {
+                CompilationResult targetMethod = runtime.compile(method, graph);
+                return addMethod(method, targetMethod);
+            }
+        });
+        cache.put(method, installedCode);
+        return installedCode;
+    }
+
+    protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult tm) {
+        GraalCompiler graalCompiler = Graal.getRuntime().getCapability(GraalCompiler.class);
+        assert graalCompiler != null;
+        return Debug.scope("CodeInstall", new Object[] {graalCompiler, method}, new Callable<InstalledCode>() {
+            @Override
+            public InstalledCode call() throws Exception {
+                final CodeInfo[] info = Debug.isDumpEnabled() ? new CodeInfo[1] : null;
+                InstalledCode installedMethod = runtime.addMethod(method, tm, info);
+                if (info != null) {
+                    Debug.dump(new Object[] {tm, info[0]}, "After code installation");
+                }
+                return installedMethod;
+            }
+        });
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     *
+     * @param methodName the name of the method in {@code this.getClass()} to be parsed
+     */
+    protected StructuredGraph parseProfiled(String methodName) {
+        return parseProfiled(getMethod(methodName));
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     */
+    protected StructuredGraph parse(Method m) {
+        ResolvedJavaMethod riMethod = runtime.getResolvedJavaMethod(m);
+        StructuredGraph graph = new StructuredGraph(riMethod);
+        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.ALL).apply(graph);
+        return graph;
+    }
+
+    /**
+     * Parses a Java method to produce a graph.
+     */
+    protected StructuredGraph parseProfiled(Method m) {
+        ResolvedJavaMethod riMethod = runtime.getResolvedJavaMethod(m);
+        StructuredGraph graph = new StructuredGraph(riMethod);
+        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph);
+        return graph;
+    }
+
+    protected PhasePlan getDefaultPhasePlan() {
+        PhasePlan plan = new PhasePlan();
+        plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.ALL));
+        return plan;
+    }
+}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraalRuntimeAccess.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2011, 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.compiler.tests;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.cri.*;
-
-/**
- * Utility for getting a {@link GraalRuntime} instance from the current execution environment.
- */
-class GraalRuntimeAccess {
-
-    /**
-     * The known classes declaring a {@code getGraalRuntime()} method. These class names
-     * have aliases that can be used with the {@code "graal.runtime"} system property to
-     * specify the VM environment to try first when getting a Graal runtime instance.
-     */
-    private static Map<String, String> graalRuntimeFactoryClasses = new LinkedHashMap<>();
-    static {
-        graalRuntimeFactoryClasses.put("HotSpot", "com.oracle.graal.hotspot.CompilerImpl");
-        graalRuntimeFactoryClasses.put("Maxine", "com.oracle.max.vm.ext.maxri.MaxRuntime");
-    }
-
-    /**
-     * Gets a Graal runtime instance from the current execution environment.
-     */
-    static GraalRuntime getGraalRuntime() {
-        String vm = System.getProperty("graal.runtime");
-        if (vm != null) {
-            String cn = graalRuntimeFactoryClasses.get(vm);
-            if (cn != null) {
-                GraalRuntime graal = getGraalRuntime(cn);
-                if (graal != null) {
-                    return graal;
-                }
-            }
-        }
-
-        for (String className : graalRuntimeFactoryClasses.values()) {
-            GraalRuntime graal = getGraalRuntime(className);
-            if (graal != null) {
-                return graal;
-            }
-        }
-        throw new InternalError("Could not create a GraalRuntime instance");
-    }
-
-    /**
-     * Calls {@code getGraalRuntime()} via reflection on a given class.
-     *
-     * @return {@code null} if there was an error invoking the methodor if the method return {@code null} itself
-     */
-    private static GraalRuntime getGraalRuntime(String className) {
-        try {
-            Class<?> c = Class.forName(className);
-            Method m = c.getDeclaredMethod("getGraalRuntime");
-            return (GraalRuntime) m.invoke(null);
-        } catch (Exception e) {
-            //e.printStackTrace();
-            System.err.println(e);
-            return null;
-        }
-    }
-}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraphScheduleTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraphScheduleTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -31,7 +31,7 @@
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 
-public class GraphScheduleTest extends GraphTest {
+public class GraphScheduleTest extends GraalCompilerTest {
     protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) {
         SchedulePhase ibp = new SchedulePhase();
         ibp.apply(graph);
@@ -40,7 +40,7 @@
         Block aBlock = nodeToBlock.get(a);
 
         if (bBlock == aBlock) {
-            List<Node> instructions = ibp.nodesFor(bBlock);
+            List<ScheduledNode> instructions = ibp.nodesFor(bBlock);
             Assert.assertTrue(instructions.indexOf(b) > instructions.indexOf(a));
         } else {
             Block block = bBlock;
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraphTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2011, 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.compiler.tests;
-
-import java.lang.reflect.*;
-
-import junit.framework.*;
-
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.phases.*;
-import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition;
-import com.oracle.graal.cri.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.max.cri.ri.*;
-
-/**
- * Base class for Graal compiler unit tests. These are white box tests
- * for Graal compiler transformations. The general pattern for a test is:
- * <ol>
- * <li>Create a graph by {@linkplain #parse(String) parsing} a method.</li>
- * <li>Manually modify the graph (e.g. replace a paramter node with a constant).</li>
- * <li>Apply a transformation to the graph.</li>
- * <li>Assert that the transformed graph is equal to an expected graph.</li>
- * </ol>
- * <p>
- * See {@link InvokeTest} as an example.
- * <p>
- * The tests can be run in Eclipse with the "Compiler Unit Test" Eclipse
- * launch configuration found in the top level of this project or by
- * running {@code mx unittest} on the command line.
- */
-public abstract class GraphTest {
-
-    protected final GraalRuntime runtime;
-
-    public GraphTest() {
-        Debug.enable();
-        this.runtime = GraalRuntimeAccess.getGraalRuntime();
-    }
-
-    protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
-        if (expected.getNodeCount() != graph.getNodeCount()) {
-            Debug.dump(expected, "Node count not matching - expected");
-            Debug.dump(graph, "Node count not matching - actual");
-            Assert.fail("Graphs do not have the same number of nodes: " + expected.getNodeCount() + " vs. " + graph.getNodeCount());
-        }
-    }
-
-    protected GraalRuntime runtime() {
-        return runtime;
-    }
-
-    /**
-     * Parses a Java method to produce a graph.
-     *
-     * @param methodName the name of the method in {@code this.getClass()} to be parsed
-     */
-    protected StructuredGraph parse(String methodName) {
-        return parse(getMethod(methodName));
-    }
-
-    protected Method getMethod(String methodName) {
-        Method found = null;
-        for (Method m : this.getClass().getMethods()) {
-            if (m.getName().equals(methodName)) {
-                Assert.assertNull(found);
-                found = m;
-            }
-        }
-        if (found != null) {
-            return found;
-        } else {
-            throw new RuntimeException("method not found: " + methodName);
-        }
-    }
-
-    /**
-     * Parses a Java method to produce a graph.
-     *
-     * @param methodName the name of the method in {@code this.getClass()} to be parsed
-     */
-    protected StructuredGraph parseProfiled(String methodName) {
-        return parseProfiled(getMethod(methodName));
-    }
-
-    /**
-     * Parses a Java method to produce a graph.
-     */
-    protected StructuredGraph parse(Method m) {
-        RiResolvedMethod riMethod = runtime.getRiMethod(m);
-        StructuredGraph graph = new StructuredGraph(riMethod);
-        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.ALL).apply(graph);
-        return graph;
-    }
-
-    /**
-     * Parses a Java method to produce a graph.
-     */
-    protected StructuredGraph parseProfiled(Method m) {
-        RiResolvedMethod riMethod = runtime.getRiMethod(m);
-        StructuredGraph graph = new StructuredGraph(riMethod);
-        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph);
-        return graph;
-    }
-
-    protected PhasePlan getDefaultPhasePlan() {
-        PhasePlan plan = new PhasePlan();
-        plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.ALL));
-        return plan;
-    }
-}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/IfBoxingEliminationTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/IfBoxingEliminationTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -33,7 +33,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 
-public class IfBoxingEliminationTest extends GraphTest {
+public class IfBoxingEliminationTest extends GraalCompilerTest {
 
     private static final String REFERENCE_SNIPPET = "referenceSnippet";
 
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/IfCanonicalizerTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/IfCanonicalizerTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -36,7 +36,7 @@
  * Then canonicalization is applied and it is verified that the resulting graph is equal to the
  * graph of the method that just has a "return 1" statement in it.
  */
-public class IfCanonicalizerTest extends GraphTest {
+public class IfCanonicalizerTest extends GraalCompilerTest {
 
     private static final String REFERENCE_SNIPPET = "referenceSnippet";
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InstanceOfTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2011, 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.compiler.tests;
+
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+/**
+ * Tests the implementation of instanceof, allowing profiling information to
+ * be manually specified.
+ */
+public class InstanceOfTest extends TypeCheckTest {
+
+    @Override
+    protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) {
+        InstanceOfNode ion = graph.getNodes().filter(InstanceOfNode.class).first();
+        if (ion != null) {
+            InstanceOfNode ionNew = graph.add(new InstanceOfNode(ion.targetClassInstruction(), ion.targetClass(), ion.object(), profile));
+            graph.replaceFloating(ion, ionNew);
+        }
+    }
+
+    @Test
+    public void test1() {
+        test("isString",    profile(),                        "object");
+        test("isString",    profile(String.class),            "object");
+
+        test("isString",    profile(),                        Object.class);
+        test("isString",    profile(String.class),            Object.class);
+    }
+
+    @Test
+    public void test2() {
+        test("isStringInt",    profile(),                        "object");
+        test("isStringInt",    profile(String.class),            "object");
+
+        test("isStringInt",    profile(),                        Object.class);
+        test("isStringInt",    profile(String.class),            Object.class);
+    }
+
+    @Test
+    public void test3() {
+        Throwable throwable = new Exception();
+        test("isThrowable",    profile(),                             throwable);
+        test("isThrowable",    profile(Throwable.class),              throwable);
+        test("isThrowable",    profile(Exception.class, Error.class), throwable);
+
+        test("isThrowable",    profile(),                             Object.class);
+        test("isThrowable",    profile(Throwable.class),              Object.class);
+        test("isThrowable",    profile(Exception.class, Error.class), Object.class);
+    }
+
+    @Test
+    public void test4() {
+        Throwable throwable = new Exception();
+        test("isThrowableInt",    profile(),                             throwable);
+        test("isThrowableInt",    profile(Throwable.class),              throwable);
+        test("isThrowableInt",    profile(Exception.class, Error.class), throwable);
+
+        test("isThrowableInt",    profile(),                             Object.class);
+        test("isThrowableInt",    profile(Throwable.class),              Object.class);
+        test("isThrowableInt",    profile(Exception.class, Error.class), Object.class);
+    }
+
+    @Test
+    public void test5() {
+        Map map = new HashMap<>();
+        test("isMap",    profile(),                             map);
+        test("isMap",    profile(HashMap.class),                map);
+        test("isMap",    profile(TreeMap.class, HashMap.class), map);
+
+        test("isMap",    profile(),                             Object.class);
+        test("isMap",    profile(HashMap.class),                Object.class);
+        test("isMap",    profile(TreeMap.class, HashMap.class), Object.class);
+    }
+
+    @Test
+    public void test6() {
+        Map map = new HashMap<>();
+        test("isMapInt",    profile(),                             map);
+        test("isMapInt",    profile(HashMap.class),                map);
+        test("isMapInt",    profile(TreeMap.class, HashMap.class), map);
+
+        test("isMapInt",    profile(),                             Object.class);
+        test("isMapInt",    profile(HashMap.class),                Object.class);
+        test("isMapInt",    profile(TreeMap.class, HashMap.class), Object.class);
+    }
+
+    public static boolean isString(Object o) {
+        return o instanceof String;
+    }
+
+    public static int isStringInt(Object o) {
+        if (o instanceof String) {
+            return 1;
+        }
+        return 0;
+    }
+
+    public static boolean isThrowable(Object o) {
+        return o instanceof Throwable;
+    }
+
+    public static int isThrowableInt(Object o) {
+        if (o instanceof Throwable) {
+            return 1;
+        }
+        return 0;
+    }
+
+    public static boolean isMap(Object o) {
+        return o instanceof Map;
+    }
+
+    public static int isMapInt(Object o) {
+        if (o instanceof Map) {
+            return 1;
+        }
+        return 0;
+    }
+}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeExceptionTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeExceptionTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -30,7 +30,7 @@
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.nodes.*;
 
-public class InvokeExceptionTest extends GraphTest {
+public class InvokeExceptionTest extends GraalCompilerTest {
 
     public static synchronized void throwException(int i) {
         if (i == 1) {
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,15 +22,12 @@
  */
 package com.oracle.graal.compiler.tests;
 
-import static com.oracle.graal.graph.iterators.NodePredicates.*;
-
 import java.util.*;
 
 import org.junit.*;
 
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -38,17 +35,21 @@
  * Then canonicalization is applied and it is verified that the resulting graph is equal to the
  * graph of the method that just has a "return 1" statement in it.
  */
-public class InvokeTest extends GraphTest {
+public class InvokeTest extends GraalCompilerTest {
 
     private static final String REFERENCE_SNIPPET = "referenceSnippet";
 
-    @SuppressWarnings("all")
-    public static int referenceSnippet(int a) {
+    public static int const1() {
         return 1;
     }
 
-    public static int const1() {
-        return 1;
+    public static int const7() {
+        return 7;
+    }
+
+    @SuppressWarnings("all")
+    public static int referenceSnippet() {
+        return 7;
     }
 
     @Test
@@ -57,8 +58,8 @@
     }
 
     @SuppressWarnings("all")
-    public static int test1Snippet(int a) {
-        return const1();
+    public static int test1Snippet() {
+        return const7();
     }
 
     @Test
@@ -67,17 +68,12 @@
     }
 
     @SuppressWarnings("all")
-    public static int test2Snippet(int a) {
+    public static int test2Snippet() {
         return const1() + const1() + const1() + const1() + const1() + const1() + const1();
     }
 
     private void test(String snippet) {
         StructuredGraph graph = parse(snippet);
-        LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
-        ConstantNode constant = ConstantNode.forInt(0, graph);
-        for (Node n : local.usages().filter(isNotA(FrameState.class)).snapshot()) {
-            n.replaceFirstInput(local, constant);
-        }
         Collection<Invoke> hints = new ArrayList<>();
         for (Invoke invoke : graph.getInvokes()) {
             hints.add(invoke);
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,10 +26,7 @@
 
 import java.util.*;
 
-import junit.framework.*;
-
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.*;
 
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
@@ -43,7 +40,7 @@
  * Then canonicalization is applied and it is verified that the resulting graph is equal to the
  * graph of the method that just has a "return 1" statement in it.
  */
-public class MonitorTest extends GraphTest {
+public class MonitorTest extends GraalCompilerTest {
 
     private static final String REFERENCE_SNIPPET = "referenceSnippet";
 
@@ -56,7 +53,7 @@
         return 1;
     }
 
-    @Test(expected = AssertionFailedError.class)
+    @Test(expected = AssertionError.class)
     public void test1() {
         test("test1Snippet");
     }
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NestedLoopTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NestedLoopTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -29,7 +29,7 @@
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 
-public class NestedLoopTest extends GraphTest {
+public class NestedLoopTest extends GraalCompilerTest {
 
     @Test
     public void test1() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewInstanceTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2011, 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.compiler.tests;
+
+import java.util.*;
+
+import org.junit.*;
+
+/**
+ * Tests the implementation of {@code NEW}.
+ */
+public class NewInstanceTest extends GraalCompilerTest {
+
+    @Override
+    protected void assertEquals(Object expected, Object actual) {
+        Assert.assertTrue(expected != null);
+        Assert.assertTrue(actual != null);
+        super.assertEquals(expected.getClass(), actual.getClass());
+        if (expected.getClass() != Object.class) {
+            try {
+                expected.getClass().getDeclaredMethod("equals", Object.class);
+                super.assertEquals(expected, actual);
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    @Test
+    public void test1() {
+        test("newObject");
+        test("newBigObject");
+        test("newSomeObject");
+        test("newEmptyString");
+        test("newString", "value");
+        test("newHashMap", 31);
+        test("newRegression", true);
+    }
+
+    public static Object newObject() {
+        return new Object();
+    }
+
+    public static BigObject newBigObject() {
+        return new BigObject();
+    }
+
+    public static SomeObject newSomeObject() {
+        return new SomeObject();
+    }
+
+    public static String newEmptyString() {
+        return new String();
+    }
+
+    public static String newString(String value) {
+        return new String(value);
+    }
+
+    public static HashMap newHashMap(int initialCapacity) {
+        return new HashMap(initialCapacity);
+    }
+
+    static class SomeObject {
+        String name = "o1";
+        HashMap<String, Object> map = new HashMap<>();
+
+
+        public SomeObject() {
+            map.put(name, this.getClass());
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof SomeObject) {
+                SomeObject so = (SomeObject) obj;
+                return so.name.equals(name) && so.map.equals(map);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return name.hashCode();
+        }
+    }
+
+    static class BigObject {
+        Object f01;
+        Object f02;
+        Object f03;
+        Object f04;
+        Object f05;
+        Object f06;
+        Object f07;
+        Object f08;
+        Object f09;
+        Object f10;
+        Object f12;
+        Object f13;
+        Object f14;
+        Object f15;
+        Object f16;
+        Object f17;
+        Object f18;
+        Object f19;
+        Object f20;
+        Object f21;
+        Object f22;
+        Object f23;
+        Object f24;
+        Object f25;
+        Object f26;
+        Object f27;
+        Object f28;
+        Object f29;
+        Object f30;
+        Object f31;
+        Object f32;
+        Object f33;
+        Object f34;
+        Object f35;
+        Object f36;
+        Object f37;
+        Object f38;
+        Object f39;
+        Object f40;
+        Object f41;
+        Object f42;
+        Object f43;
+        Object f44;
+        Object f45;
+    }
+
+    /**
+     * Tests that an earlier bug does not occur. The issue was that the loading of the TLAB
+     * 'top' and 'end' values was being GVN'ed from each branch of the 'if' statement.
+     * This meant that the allocated B object in the true branch overwrote the allocated
+     * array. The cause is that RegisterNode was a floating node and the reads from it
+     * were UnsafeLoads which are also floating. The fix was to make RegisterNode a fixed
+     * node (which it should have been in the first place).
+     */
+    public static Object newRegression(boolean condition) {
+        Object result;
+        if (condition) {
+            Object[] arr = {0, 1, 2, 3, 4, 5};
+            result = new B();
+            for (int i = 0; i < arr.length; ++i) {
+                // If the bug exists, the values of arr will now be deadbeef values
+                // and the virtual dispatch will cause a segfault. This can result in
+                // either a VM crash or a spurious NullPointerException.
+                if (arr[i].equals(Integer.valueOf(i))) {
+                    return false;
+                }
+            }
+        } else {
+            result = new B();
+        }
+        return result;
+    }
+
+    static class B {
+        long f1 = 0xdeadbeefdeadbe01L;
+        long f2 = 0xdeadbeefdeadbe02L;
+        long f3 = 0xdeadbeefdeadbe03L;
+        long f4 = 0xdeadbeefdeadbe04L;
+        long f5 = 0xdeadbeefdeadbe05L;
+    }
+}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/PhiCreationTests.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/PhiCreationTests.java	Wed Jun 27 17:35:32 2012 +0200
@@ -30,7 +30,7 @@
 /**
  * In the following tests, the correct removal of redundant phis during graph building is tested.
  */
-public class PhiCreationTests extends GraphTest {
+public class PhiCreationTests extends GraalCompilerTest {
 
     /**
      * Dummy method to avoid javac dead code elimination.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ReassociateAndCanonicalTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2011, 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.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+
+public class ReassociateAndCanonicalTest extends GraalCompilerTest {
+    public static int rnd = (int) (Math.random() * 100);
+
+    @Test
+    public void test1() {
+        test("test1Snippet", "ref1Snippet");
+    }
+
+    public static int test1Snippet() {
+        return 1 + (rnd + 2);
+    }
+
+    public static int ref1Snippet() {
+        return rnd + 3;
+    }
+
+    @Test
+    public void test2() {
+        test("test2Snippet", "ref2Snippet");
+    }
+
+    public static int test2Snippet() {
+        return rnd + 3;
+    }
+
+    public static int ref2Snippet() {
+        return (rnd + 2) + 1;
+    }
+
+    @Test
+    public void test3() {
+        test("test3Snippet", "ref3Snippet");
+    }
+
+    public static int test3Snippet() {
+        return rnd + 3;
+    }
+
+    public static int ref3Snippet() {
+        return 1 + (2 + rnd);
+    }
+
+    @Test
+    public void test4() {
+        test("test4Snippet", "ref4Snippet");
+    }
+
+    public static int test4Snippet() {
+        return rnd + 3;
+    }
+
+    public static int ref4Snippet() {
+        return (2 + rnd) + 1;
+    }
+
+    @Test
+    public void test5() {
+        test("test5Snippet", "ref5Snippet");
+    }
+
+    public static int test5Snippet() {
+        return -1 - rnd;
+    }
+
+    public static int ref5Snippet() {
+        return 1 - (rnd + 2);
+    }
+
+    @Test
+    public void test6() {
+        test("test6Snippet", "ref6Snippet");
+    }
+
+    public static int test6Snippet() {
+        return rnd + 1;
+    }
+
+    public static int ref6Snippet() {
+        return (rnd + 2) - 1;
+    }
+
+    @Test
+    public void test7() {
+        test("test7Snippet", "ref7Snippet");
+    }
+
+    public static int test7Snippet() {
+        return -1 - rnd;
+    }
+
+    public static int ref7Snippet() {
+        return 1 - (2 + rnd);
+    }
+
+    @Test
+    public void test8() {
+        test("test8Snippet", "ref8Snippet");
+    }
+
+    public static int test8Snippet() {
+        return rnd + 1;
+    }
+
+    public static int ref8Snippet() {
+        return (2 + rnd) - 1;
+    }
+
+    @Test
+    public void test9() {
+        test("test9Snippet", "ref9Snippet");
+    }
+
+    public static int test9Snippet() {
+        return rnd - 1;
+    }
+
+    public static int ref9Snippet() {
+        return 1 + (rnd - 2);
+    }
+
+    @Test
+    public void test10() {
+        test("test10Snippet", "ref10Snippet");
+    }
+
+    public static int test10Snippet() {
+        return rnd - 1;
+    }
+
+    public static int ref10Snippet() {
+        return (rnd - 2) + 1;
+    }
+
+    @Test
+    public void test11() {
+        test("test11Snippet", "ref11Snippet");
+    }
+
+    public static int test11Snippet() {
+        return -rnd + 3;
+    }
+
+    public static int ref11Snippet() {
+        return 1 + (2 - rnd);
+    }
+
+    @Test
+    public void test12() {
+        test("test12Snippet", "ref12Snippet");
+    }
+
+    public static int test12Snippet() {
+        return -rnd + 3;
+    }
+
+    public static int ref12Snippet() {
+        return (2 - rnd) + 1;
+    }
+
+    @Test
+    public void test13() {
+        test("test13Snippet", "ref13Snippet");
+    }
+
+    public static int test13Snippet() {
+        return -rnd + 3;
+    }
+
+    public static int ref13Snippet() {
+        return 1 - (rnd - 2);
+    }
+
+    @Test
+    public void test14() {
+        test("test14Snippet", "ref14Snippet");
+    }
+
+    public static int test14Snippet() {
+        return rnd - 3;
+    }
+
+    public static int ref14Snippet() {
+        return (rnd - 2) - 1;
+    }
+
+    @Test
+    public void test15() {
+        test("test15Snippet", "ref15Snippet");
+    }
+
+    public static int test15Snippet() {
+        return rnd + -1;
+    }
+
+    public static int ref15Snippet() {
+        return 1 - (2 - rnd);
+    }
+
+    @Test
+    public void test16() {
+        test("test16Snippet", "ref16Snippet");
+    }
+
+    public static int test16Snippet() {
+        return -rnd + 1;
+    }
+
+    public static int ref16Snippet() {
+        return (2 - rnd) - 1;
+    }
+
+    private <T extends Node & Node.IterableNodeType> void test(String test, String ref) {
+        StructuredGraph testGraph = parse(test);
+        new CanonicalizerPhase(null, runtime(), null).apply(testGraph);
+        StructuredGraph refGraph = parse(ref);
+        new CanonicalizerPhase(null, runtime(), null).apply(refGraph);
+        assertEquals(testGraph, refGraph);
+    }
+}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ScalarTypeSystemTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ScalarTypeSystemTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,19 +22,16 @@
  */
 package com.oracle.graal.compiler.tests;
 
-import junit.framework.AssertionFailedError;
-
 import org.junit.*;
 
 import com.oracle.graal.compiler.phases.*;
-import com.oracle.graal.compiler.types.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 
 /**
  * In the following tests, the scalar type system of the compiler should be complete enough to see the relation between the different conditions.
  */
-public class ScalarTypeSystemTest extends GraphTest {
+public class ScalarTypeSystemTest extends GraalCompilerTest {
 
     public static int referenceSnippet1(int a) {
         if (a > 0) {
@@ -44,7 +41,7 @@
         }
     }
 
-    @Test
+    @Test(expected = AssertionError.class)
     public void test1() {
         test("test1Snippet", "referenceSnippet1");
     }
@@ -61,7 +58,7 @@
         }
     }
 
-    @Test
+    @Test(expected = AssertionError.class)
     public void test2() {
         test("test2Snippet", "referenceSnippet1");
     }
@@ -78,7 +75,7 @@
         }
     }
 
-    @Test
+    @Test(expected = AssertionError.class)
     public void test3() {
         test("test3Snippet", "referenceSnippet2");
     }
@@ -145,7 +142,7 @@
         }
     }
 
-    @Test(expected = AssertionFailedError.class)
+    @Test(expected = AssertionError.class)
     public void test6() {
         test("test6Snippet", "referenceSnippet3");
     }
@@ -162,13 +159,14 @@
         }
     }
 
-    private void test(String snippet, String referenceSnippet) {
-
+    private void test(final String snippet, final String referenceSnippet) {
+        // No debug scope to reduce console noise for @Test(expected = ...) tests
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
-        System.out.println("==================== " + snippet);
+//        TypeSystemTest.outputGraph(graph);
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        new PropagateTypeCachePhase(null, null, null).apply(graph);
+        new CheckCastEliminationPhase().apply(graph);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
         StructuredGraph referenceGraph = parse(referenceSnippet);
         assertEquals(referenceGraph, graph);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/StampCanonicalizerTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,104 @@
+/*
+ * 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.compiler.tests;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * This class tests some specific patterns the stamp system should be able to canonicalize away using
+ * {@link IntegerStamp#mask()}.
+ */
+public class StampCanonicalizerTest extends GraalCompilerTest {
+
+    public static int andStamp(int a, int b) {
+        int v = (a & 0xffff00) & (b & 0xff0000f);
+        return v & 1;
+    }
+
+    @Test
+    public void testAnd() {
+        testZeroReturn("andStamp");
+    }
+
+    public static int shiftLeftStamp1(int a) {
+        int v = a << 1;
+        return v & 1;
+    }
+
+    public static int shiftLeftStamp2(int a) {
+        int v = a << 1;
+        if (a == 17) {
+            v = a * 4;
+        }
+        return v & 1;
+    }
+
+    @Test
+    public void testShift() {
+        testZeroReturn("shiftLeftStamp1");
+        testZeroReturn("shiftLeftStamp2");
+    }
+
+    public static int upperBoundShiftStamp1(int a) {
+        int v = a & 0xffff;
+        return (v << 4) & 0xff00000;
+    }
+
+    public static int upperBoundShiftStamp2(int a) {
+        int v = a & 0xffff;
+        return (v >> 4) & 0xf000;
+    }
+
+    @Test
+    public void testUpperBoundShift() {
+        testZeroReturn("upperBoundShiftStamp1");
+        testZeroReturn("upperBoundShiftStamp2");
+    }
+
+    public static int divStamp1(int[] a) {
+        int v = a.length / 4;
+        return v & 0x80000000;
+    }
+
+    public static int divStamp2(int[] a) {
+        int v = a.length / 5;
+        return v & 0x80000000;
+    }
+
+    @Test
+    public void testDiv() {
+        testZeroReturn("divStamp1");
+        testZeroReturn("divStamp2");
+    }
+
+    private void testZeroReturn(String methodName) {
+        StructuredGraph graph = parse(methodName);
+        new CanonicalizerPhase(null, runtime(), null).apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
+        assertConstantReturn(graph, 0);
+    }
+}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/StraighteningTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/StraighteningTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,15 +22,13 @@
  */
 package com.oracle.graal.compiler.tests;
 
-import junit.framework.AssertionFailedError;
-
 import org.junit.*;
 
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 
-public class StraighteningTest extends GraphTest {
+public class StraighteningTest extends GraalCompilerTest {
 
     private static final String REFERENCE_SNIPPET = "ref";
 
@@ -71,22 +69,23 @@
         return c == 1;
     }
 
-    @Test(expected = AssertionFailedError.class)
+    @Test(expected = AssertionError.class)
     public void test1() {
         test("test1Snippet");
     }
 
-    @Test(expected = AssertionFailedError.class)
+    @Test(expected = AssertionError.class)
     public void test2() {
         test("test2Snippet");
     }
 
-    @Test(expected = AssertionFailedError.class)
+    @Test(expected = AssertionError.class)
     public void test3() {
         test("test3Snippet");
     }
 
-    private void test(String snippet) {
+    private void test(final String snippet) {
+        // No debug scope to reduce console noise for @Test(expected = ...) tests
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/TypeCheckTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011, 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.compiler.tests;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaTypeProfile.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Base class for checkcast and instanceof test classes.
+ */
+public abstract class TypeCheckTest extends GraalCompilerTest {
+
+    protected abstract void replaceProfile(StructuredGraph graph, JavaTypeProfile profile);
+
+    protected JavaTypeProfile currentProfile;
+
+    @Override
+    protected InstalledCode getCode(final ResolvedJavaMethod method, final StructuredGraph graph) {
+        boolean forceCompile = false;
+        if (currentProfile != null) {
+            replaceProfile(graph, currentProfile);
+            forceCompile = true;
+        }
+        return super.getCode(method, graph, forceCompile);
+    }
+
+    protected JavaTypeProfile profile(Class... types) {
+        if (types.length == 0) {
+            return null;
+        }
+        ProfiledType[] ptypes = new ProfiledType[types.length];
+        for (int i = 0; i < types.length; i++) {
+            ptypes[i] = new ProfiledType(runtime.getResolvedJavaType(types[i]), 1.0D / types.length);
+        }
+        return new JavaTypeProfile(0.0D, ptypes);
+    }
+
+    protected void test(String name, JavaTypeProfile profile, Object... args) {
+        assert currentProfile == null;
+        currentProfile = profile;
+        try {
+            super.test(name, args);
+        } finally {
+            currentProfile = null;
+        }
+    }
+}
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/TypeSystemTest.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/TypeSystemTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,7 +26,7 @@
 
 import junit.framework.Assert;
 
-import org.junit.*;
+import org.junit.Test;
 
 import com.oracle.graal.compiler.phases.*;
 import com.oracle.graal.compiler.schedule.*;
@@ -36,12 +36,11 @@
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.printer.*;
 
 /**
  * In the following tests, the scalar type system of the compiler should be complete enough to see the relation between the different conditions.
  */
-public class TypeSystemTest extends GraphTest {
+public class TypeSystemTest extends GraalCompilerTest {
 
     @Test
     public void test1() {
@@ -184,31 +183,33 @@
         return ((InputStream) o).available();
     }
 
+    @SuppressWarnings("unused")
     private void test(String snippet, String referenceSnippet) {
-
-        StructuredGraph graph = parse(snippet);
-        Debug.dump(graph, "Graph");
-        System.out.println("==================== " + snippet);
-        new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        new PropagateTypeCachePhase(null, runtime(), null).apply(graph);
-        new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        new GlobalValueNumberingPhase().apply(graph);
-        StructuredGraph referenceGraph = parse(referenceSnippet);
-        new CanonicalizerPhase(null, runtime(), null).apply(referenceGraph);
-        new GlobalValueNumberingPhase().apply(referenceGraph);
-        assertEquals(referenceGraph, graph);
+        // TODO(ls) temporarily disabled, reintroduce when a proper type system is available
+        if (false) {
+            StructuredGraph graph = parse(snippet);
+            Debug.dump(graph, "Graph");
+            new CanonicalizerPhase(null, runtime(), null).apply(graph);
+            new PropagateTypeCachePhase(null, runtime(), null).apply(graph);
+            new CanonicalizerPhase(null, runtime(), null).apply(graph);
+            new GlobalValueNumberingPhase().apply(graph);
+            StructuredGraph referenceGraph = parse(referenceSnippet);
+            new CanonicalizerPhase(null, runtime(), null).apply(referenceGraph);
+            new GlobalValueNumberingPhase().apply(referenceGraph);
+            assertEquals(referenceGraph, graph);
+        }
     }
 
     @Override
     protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
         if (expected.getNodeCount() != graph.getNodeCount()) {
-            Debug.dump(expected, "Node count not matching - expected");
-            Debug.dump(graph, "Node count not matching - actual");
-            System.out.println("================ expected");
-            outputGraph(expected);
-            System.out.println("================ actual");
-            outputGraph(graph);
-            new IdealGraphPrinterDumpHandler().dump(graph, "asdf");
+//            Debug.dump(expected, "Node count not matching - expected");
+//            Debug.dump(graph, "Node count not matching - actual");
+//            System.out.println("================ expected");
+//            outputGraph(expected);
+//            System.out.println("================ actual");
+//            outputGraph(graph);
+//            new IdealGraphPrinterDumpHandler().dump(graph, "asdf");
             Assert.fail("Graphs do not have the same number of nodes: " + expected.getNodeCount() + " vs. " + graph.getNodeCount());
         }
     }
@@ -232,16 +233,17 @@
         }
     }
 
-
+    @SuppressWarnings("unused")
     private <T extends Node & Node.IterableNodeType> void test(String snippet, Class<T> clazz) {
-        StructuredGraph graph = parse(snippet);
-        Debug.dump(graph, "Graph");
-        new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        new PropagateTypeCachePhase(null, runtime(), null).apply(graph);
-        Debug.dump(graph, "Graph");
-        if (graph.getNodes(clazz).iterator().hasNext()) {
-            outputGraph(graph);
+        // TODO(ls) temporarily disabled, reintroduce when a proper type system is available
+        if (false) {
+            StructuredGraph graph = parse(snippet);
+            Debug.dump(graph, "Graph");
+            new CanonicalizerPhase(null, runtime(), null).apply(graph);
+            new PropagateTypeCachePhase(null, runtime(), null).apply(graph);
+            new CanonicalizerPhase(null, runtime(), null).apply(graph);
+            Debug.dump(graph, "Graph");
+            Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes(clazz).iterator().hasNext());
         }
-        Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes(clazz).iterator().hasNext());
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/cfg/SimpleCFGTest.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, 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.compiler.tests.cfg;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.graal.lir.cfg.*;
+import com.oracle.graal.nodes.*;
+
+public class SimpleCFGTest {
+
+    @Test
+    public void testImplies() {
+        StructuredGraph graph = new StructuredGraph();
+
+        EndNode trueEnd = graph.add(new EndNode());
+        EndNode falseEnd = graph.add(new EndNode());
+
+        BeginNode trueBegin = graph.add(new BeginNode());
+        trueBegin.setNext(trueEnd);
+        BeginNode falseBegin = graph.add(new BeginNode());
+        falseBegin.setNext(falseEnd);
+
+        IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5, graph.graphId()));
+        graph.start().setNext(ifNode);
+
+        MergeNode merge = graph.add(new MergeNode());
+        merge.addForwardEnd(trueEnd);
+        merge.addForwardEnd(falseEnd);
+        ReturnNode returnNode = graph.add(new ReturnNode(null));
+        merge.setNext(returnNode);
+
+        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
+
+        Block[] blocks = cfg.getBlocks();
+        // check number of blocks
+        assertEquals(4, blocks.length);
+
+        // check block - node assignment
+        assertEquals(blocks[0], cfg.blockFor(graph.start()));
+        assertEquals(blocks[0], cfg.blockFor(ifNode));
+        assertEquals(blocks[1], cfg.blockFor(trueBegin));
+        assertEquals(blocks[1], cfg.blockFor(trueEnd));
+        assertEquals(blocks[2], cfg.blockFor(falseBegin));
+        assertEquals(blocks[2], cfg.blockFor(falseEnd));
+        assertEquals(blocks[3], cfg.blockFor(merge));
+        assertEquals(blocks[3], cfg.blockFor(returnNode));
+
+        // check dominators
+        assertDominator(blocks[0], null);
+        assertDominator(blocks[1], blocks[0]);
+        assertDominator(blocks[2], blocks[0]);
+        assertDominator(blocks[3], blocks[0]);
+
+        // check dominated
+        assertDominatedSize(blocks[0], 3);
+        assertDominatedSize(blocks[1], 0);
+        assertDominatedSize(blocks[2], 0);
+        assertDominatedSize(blocks[3], 0);
+
+        // check postdominators
+        assertPostdominator(blocks[0], blocks[3]);
+        assertPostdominator(blocks[1], blocks[3]);
+        assertPostdominator(blocks[2], blocks[3]);
+        assertPostdominator(blocks[3], null);
+    }
+
+    public static void assertDominator(Block block, Block expectedDominator) {
+        assertEquals("dominator of " + block, expectedDominator, block.getDominator());
+    }
+
+    public static void assertDominatedSize(Block block, int size) {
+        assertEquals("number of dominated blocks of " + block, size, block.getDominated().size());
+    }
+
+    public static void assertPostdominator(Block block, Block expectedPostdominator) {
+        assertEquals("postdominator of " + block, expectedPostdominator, block.getPostdominator());
+    }
+
+}
--- a/graal/com.oracle.max.asm/src/com/oracle/max/asm/AbstractAssembler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/AbstractAssembler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,17 +22,17 @@
  */
 package com.oracle.max.asm;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiArchitecture.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Architecture.*;
 
 /**
  * The platform-independent base class for the assembler.
  */
 public abstract class AbstractAssembler {
-    public final CiTarget target;
+    public final TargetDescription target;
     public final Buffer codeBuffer;
 
-    public AbstractAssembler(CiTarget target) {
+    public AbstractAssembler(TargetDescription target) {
         this.target = target;
 
         if (target.arch.byteOrder == ByteOrder.BigEndian) {
--- a/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,67 +22,67 @@
  */
 package com.oracle.max.asm.target.amd64;
 
-import static com.oracle.max.cri.ci.CiKind.*;
-import static com.oracle.max.cri.ci.CiRegister.RegisterFlag.*;
+import static com.oracle.graal.api.code.Register.RegisterFlag.*;
+import static com.oracle.graal.api.meta.Kind.*;
 import static com.oracle.max.cri.util.MemoryBarriers.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Register.*;
 
 /**
  * Represents the AMD64 architecture.
  */
-public class AMD64 extends CiArchitecture {
+public class AMD64 extends Architecture {
 
     // General purpose CPU registers
-    public static final CiRegister rax = new CiRegister(0, 0, 8, "rax", CPU, RegisterFlag.Byte);
-    public static final CiRegister rcx = new CiRegister(1, 1, 8, "rcx", CPU, RegisterFlag.Byte);
-    public static final CiRegister rdx = new CiRegister(2, 2, 8, "rdx", CPU, RegisterFlag.Byte);
-    public static final CiRegister rbx = new CiRegister(3, 3, 8, "rbx", CPU, RegisterFlag.Byte);
-    public static final CiRegister rsp = new CiRegister(4, 4, 8, "rsp", CPU, RegisterFlag.Byte);
-    public static final CiRegister rbp = new CiRegister(5, 5, 8, "rbp", CPU, RegisterFlag.Byte);
-    public static final CiRegister rsi = new CiRegister(6, 6, 8, "rsi", CPU, RegisterFlag.Byte);
-    public static final CiRegister rdi = new CiRegister(7, 7, 8, "rdi", CPU, RegisterFlag.Byte);
+    public static final Register rax = new Register(0, 0, 8, "rax", CPU, RegisterFlag.Byte);
+    public static final Register rcx = new Register(1, 1, 8, "rcx", CPU, RegisterFlag.Byte);
+    public static final Register rdx = new Register(2, 2, 8, "rdx", CPU, RegisterFlag.Byte);
+    public static final Register rbx = new Register(3, 3, 8, "rbx", CPU, RegisterFlag.Byte);
+    public static final Register rsp = new Register(4, 4, 8, "rsp", CPU, RegisterFlag.Byte);
+    public static final Register rbp = new Register(5, 5, 8, "rbp", CPU, RegisterFlag.Byte);
+    public static final Register rsi = new Register(6, 6, 8, "rsi", CPU, RegisterFlag.Byte);
+    public static final Register rdi = new Register(7, 7, 8, "rdi", CPU, RegisterFlag.Byte);
 
-    public static final CiRegister r8  = new CiRegister(8,  8,  8, "r8", CPU, RegisterFlag.Byte);
-    public static final CiRegister r9  = new CiRegister(9,  9,  8, "r9", CPU, RegisterFlag.Byte);
-    public static final CiRegister r10 = new CiRegister(10, 10, 8, "r10", CPU, RegisterFlag.Byte);
-    public static final CiRegister r11 = new CiRegister(11, 11, 8, "r11", CPU, RegisterFlag.Byte);
-    public static final CiRegister r12 = new CiRegister(12, 12, 8, "r12", CPU, RegisterFlag.Byte);
-    public static final CiRegister r13 = new CiRegister(13, 13, 8, "r13", CPU, RegisterFlag.Byte);
-    public static final CiRegister r14 = new CiRegister(14, 14, 8, "r14", CPU, RegisterFlag.Byte);
-    public static final CiRegister r15 = new CiRegister(15, 15, 8, "r15", CPU, RegisterFlag.Byte);
+    public static final Register r8  = new Register(8,  8,  8, "r8", CPU, RegisterFlag.Byte);
+    public static final Register r9  = new Register(9,  9,  8, "r9", CPU, RegisterFlag.Byte);
+    public static final Register r10 = new Register(10, 10, 8, "r10", CPU, RegisterFlag.Byte);
+    public static final Register r11 = new Register(11, 11, 8, "r11", CPU, RegisterFlag.Byte);
+    public static final Register r12 = new Register(12, 12, 8, "r12", CPU, RegisterFlag.Byte);
+    public static final Register r13 = new Register(13, 13, 8, "r13", CPU, RegisterFlag.Byte);
+    public static final Register r14 = new Register(14, 14, 8, "r14", CPU, RegisterFlag.Byte);
+    public static final Register r15 = new Register(15, 15, 8, "r15", CPU, RegisterFlag.Byte);
 
-    public static final CiRegister[] cpuRegisters = {
+    public static final Register[] cpuRegisters = {
         rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
         r8, r9, r10, r11, r12, r13, r14, r15
     };
 
     // XMM registers
-    public static final CiRegister xmm0 = new CiRegister(16, 0, 8, "xmm0", FPU);
-    public static final CiRegister xmm1 = new CiRegister(17, 1, 8, "xmm1", FPU);
-    public static final CiRegister xmm2 = new CiRegister(18, 2, 8, "xmm2", FPU);
-    public static final CiRegister xmm3 = new CiRegister(19, 3, 8, "xmm3", FPU);
-    public static final CiRegister xmm4 = new CiRegister(20, 4, 8, "xmm4", FPU);
-    public static final CiRegister xmm5 = new CiRegister(21, 5, 8, "xmm5", FPU);
-    public static final CiRegister xmm6 = new CiRegister(22, 6, 8, "xmm6", FPU);
-    public static final CiRegister xmm7 = new CiRegister(23, 7, 8, "xmm7", FPU);
+    public static final Register xmm0 = new Register(16, 0, 8, "xmm0", FPU);
+    public static final Register xmm1 = new Register(17, 1, 8, "xmm1", FPU);
+    public static final Register xmm2 = new Register(18, 2, 8, "xmm2", FPU);
+    public static final Register xmm3 = new Register(19, 3, 8, "xmm3", FPU);
+    public static final Register xmm4 = new Register(20, 4, 8, "xmm4", FPU);
+    public static final Register xmm5 = new Register(21, 5, 8, "xmm5", FPU);
+    public static final Register xmm6 = new Register(22, 6, 8, "xmm6", FPU);
+    public static final Register xmm7 = new Register(23, 7, 8, "xmm7", FPU);
 
-    public static final CiRegister xmm8 =  new CiRegister(24,  8, 8, "xmm8",  FPU);
-    public static final CiRegister xmm9 =  new CiRegister(25,  9, 8, "xmm9",  FPU);
-    public static final CiRegister xmm10 = new CiRegister(26, 10, 8, "xmm10", FPU);
-    public static final CiRegister xmm11 = new CiRegister(27, 11, 8, "xmm11", FPU);
-    public static final CiRegister xmm12 = new CiRegister(28, 12, 8, "xmm12", FPU);
-    public static final CiRegister xmm13 = new CiRegister(29, 13, 8, "xmm13", FPU);
-    public static final CiRegister xmm14 = new CiRegister(30, 14, 8, "xmm14", FPU);
-    public static final CiRegister xmm15 = new CiRegister(31, 15, 8, "xmm15", FPU);
+    public static final Register xmm8 =  new Register(24,  8, 8, "xmm8",  FPU);
+    public static final Register xmm9 =  new Register(25,  9, 8, "xmm9",  FPU);
+    public static final Register xmm10 = new Register(26, 10, 8, "xmm10", FPU);
+    public static final Register xmm11 = new Register(27, 11, 8, "xmm11", FPU);
+    public static final Register xmm12 = new Register(28, 12, 8, "xmm12", FPU);
+    public static final Register xmm13 = new Register(29, 13, 8, "xmm13", FPU);
+    public static final Register xmm14 = new Register(30, 14, 8, "xmm14", FPU);
+    public static final Register xmm15 = new Register(31, 15, 8, "xmm15", FPU);
 
-    public static final CiRegister[] xmmRegisters = {
+    public static final Register[] xmmRegisters = {
         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
         xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
     };
 
-    public static final CiRegister[] cpuxmmRegisters = {
+    public static final Register[] cpuxmmRegisters = {
         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
         r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
@@ -92,9 +92,9 @@
     /**
      * Register used to construct an instruction-relative address.
      */
-    public static final CiRegister rip = new CiRegister(32, -1, 0, "rip");
+    public static final Register rip = new Register(32, -1, 0, "rip");
 
-    public static final CiRegister[] allRegisters = {
+    public static final Register[] allRegisters = {
         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
         r8,   r9,   r10,   r11,   r12,   r13,   r14,   r15,
         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
@@ -102,7 +102,7 @@
         rip
     };
 
-    public static final CiRegisterValue RSP = rsp.asValue(Long);
+    public static final RegisterValue RSP = rsp.asValue(Long);
 
     public AMD64() {
         super("AMD64",
--- a/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64Assembler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64Assembler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,14 +22,14 @@
  */
 package com.oracle.max.asm.target.amd64;
 
+import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.max.asm.NumUtil.*;
 import static com.oracle.max.asm.target.amd64.AMD64.*;
-import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.max.cri.util.MemoryBarriers.*;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 
 /**
  * This class implements an assembler that can encode most X86 instructions.
@@ -38,7 +38,7 @@
     /**
      * The kind for pointers and raw registers.  Since we know we are 64 bit here, we can hardcode it.
      */
-    private static final CiKind Word = CiKind.Long;
+    private static final Kind Word = Kind.Long;
 
     private static final int MinEncodingNeedsRex = 8;
 
@@ -46,34 +46,60 @@
      * The x86 condition codes used for conditional jumps/moves.
      */
     public enum ConditionFlag {
-        zero(0x4),
-        notZero(0x5),
-        equal(0x4),
-        notEqual(0x5),
-        less(0xc),
-        lessEqual(0xe),
-        greater(0xf),
-        greaterEqual(0xd),
-        below(0x2),
-        belowEqual(0x6),
-        above(0x7),
-        aboveEqual(0x3),
-        overflow(0x0),
-        noOverflow(0x1),
-        carrySet(0x2),
-        carryClear(0x3),
-        negative(0x8),
-        positive(0x9),
-        parity(0xa),
-        noParity(0xb);
+        zero(0x4, "|zero|"),
+        notZero(0x5, "|nzero|"),
+        equal(0x4, "="),
+        notEqual(0x5, "!="),
+        less(0xc, "<"),
+        lessEqual(0xe, "<="),
+        greater(0xf, ">"),
+        greaterEqual(0xd, ">="),
+        below(0x2, "|<|"),
+        belowEqual(0x6, "|<=|"),
+        above(0x7, "|>|"),
+        aboveEqual(0x3, "|>=|"),
+        overflow(0x0, "|of|"),
+        noOverflow(0x1, "|nof|"),
+        carrySet(0x2, "|carry|"),
+        carryClear(0x3, "|ncarry|"),
+        negative(0x8, "|neg|"),
+        positive(0x9, "|pos|"),
+        parity(0xa, "|par|"),
+        noParity(0xb, "|npar|");
 
         public final int value;
-
-        private ConditionFlag(int value) {
+        public final String operator;
+
+        private ConditionFlag(int value, String operator) {
             this.value = value;
+            this.operator = operator;
         }
 
-        public static final ConditionFlag[] values = values();
+        public ConditionFlag negate() {
+            switch(this) {
+                case zero: return notZero;
+                case notZero: return zero;
+                case equal: return notEqual;
+                case notEqual: return equal;
+                case less: return greaterEqual;
+                case lessEqual: return greater;
+                case greater: return lessEqual;
+                case greaterEqual: return less;
+                case below: return aboveEqual;
+                case belowEqual: return above;
+                case above: return belowEqual;
+                case aboveEqual: return below;
+                case overflow: return noOverflow;
+                case noOverflow: return overflow;
+                case carrySet: return carryClear;
+                case carryClear: return carrySet;
+                case negative: return positive;
+                case positive: return negative;
+                case parity: return noParity;
+                case noParity: return parity;
+            }
+            throw new IllegalArgumentException();
+        }
     }
 
     /**
@@ -99,28 +125,28 @@
     }
 
     /**
-     * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
+     * The register to which {@link Register#Frame} and {@link Register#CallerFrame} are bound.
      */
-    public final CiRegister frameRegister;
+    public final Register frameRegister;
 
     /**
      * Constructs an assembler for the AMD64 architecture.
      *
-     * @param registerConfig the register configuration used to bind {@link CiRegister#Frame} and
-     *            {@link CiRegister#CallerFrame} to physical registers. This value can be null if this assembler
+     * @param registerConfig the register configuration used to bind {@link Register#Frame} and
+     *            {@link Register#CallerFrame} to physical registers. This value can be null if this assembler
      *            instance will not be used to assemble instructions using these logical registers.
      */
-    public AMD64Assembler(CiTarget target, RiRegisterConfig registerConfig) {
+    public AMD64Assembler(TargetDescription target, RegisterConfig registerConfig) {
         super(target);
         this.frameRegister = registerConfig == null ? null : registerConfig.getFrameRegister();
     }
 
-    private static int encode(CiRegister r) {
+    private static int encode(Register r) {
         assert r.encoding < 16 && r.encoding >= 0 : "encoding out of range: " + r.encoding;
         return r.encoding & 0x7;
     }
 
-    private void emitArithB(int op1, int op2, CiRegister dst, int imm8) {
+    private void emitArithB(int op1, int op2, Register dst, int imm8) {
         assert dst.isByte() : "must have byte register";
         assert isUByte(op1) && isUByte(op2) : "wrong opcode";
         assert isUByte(imm8) : "not a byte";
@@ -130,7 +156,7 @@
         emitByte(imm8);
     }
 
-    private void emitArith(int op1, int op2, CiRegister dst, int imm32) {
+    private void emitArith(int op1, int op2, Register dst, int imm32) {
         assert isUByte(op1) && isUByte(op2) : "wrong opcode";
         assert (op1 & 0x01) == 1 : "should be 32bit operation";
         assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
@@ -146,7 +172,7 @@
     }
 
     // immediate-to-memory forms
-    private void emitArithOperand(int op1, CiRegister rm, CiAddress adr, int imm32) {
+    private void emitArithOperand(int op1, Register rm, Address adr, int imm32) {
         assert (op1 & 0x01) == 1 : "should be 32bit operation";
         assert (op1 & 0x02) == 0 : "sign-extension bit should not be set";
         if (isByte(imm32)) {
@@ -160,21 +186,21 @@
         }
     }
 
-    private void emitArith(int op1, int op2, CiRegister dst, CiRegister src) {
+    private void emitArith(int op1, int op2, Register dst, Register src) {
         assert isUByte(op1) && isUByte(op2) : "wrong opcode";
         emitByte(op1);
         emitByte(op2 | encode(dst) << 3 | encode(src));
     }
 
-    private void emitOperandHelper(CiRegister reg, CiAddress addr) {
-        CiRegister base = isLegal(addr.base) ? asRegister(addr.base) : CiRegister.None;
-        CiRegister index = isLegal(addr.index) ? asRegister(addr.index) : CiRegister.None;
-
-        CiAddress.Scale scale = addr.scale;
-        int disp = addr.displacement;
-
-        if (base == CiRegister.Frame) {
-            assert frameRegister != null : "cannot use register " + CiRegister.Frame + " in assembler with null register configuration";
+    private void emitOperandHelper(Register reg, Address addr) {
+        Register base = isLegal(addr.getBase()) ? asRegister(addr.getBase()) : Register.None;
+        Register index = isLegal(addr.getIndex()) ? asRegister(addr.getIndex()) : Register.None;
+
+        Address.Scale scale = addr.getScale();
+        int disp = addr.getDisplacement();
+
+        if (base == Register.Frame) {
+            assert frameRegister != null : "cannot use register " + Register.Frame + " in assembler with null register configuration";
             base = frameRegister;
 //        } else if (base == CiRegister.CallerFrame) {
 //            assert frameRegister != null : "cannot use register " + CiRegister.Frame + " in assembler with null register configuration";
@@ -184,14 +210,14 @@
 
         // Encode the registers as needed in the fields they are used in
 
-        assert reg != CiRegister.None;
+        assert reg != Register.None;
         int regenc = encode(reg) << 3;
 
         if (base == AMD64.rip) {
             // [00 000 101] disp32
             emitByte(0x05 | regenc);
             emitInt(disp);
-        } else if (addr == CiAddress.Placeholder) {
+        } else if (addr == Address.Placeholder) {
             // [00 000 101] disp32
             emitByte(0x05 | regenc);
             emitInt(0);
@@ -280,29 +306,29 @@
         }
     }
 
-    public final void addl(CiAddress dst, int imm32) {
+    public final void addl(Address dst, int imm32) {
         prefix(dst);
         emitArithOperand(0x81, rax, dst, imm32);
     }
 
-    public final void addl(CiAddress dst, CiRegister src) {
+    public final void addl(Address dst, Register src) {
         prefix(dst, src);
         emitByte(0x01);
         emitOperandHelper(src, dst);
     }
 
-    public final void addl(CiRegister dst, int imm32) {
+    public final void addl(Register dst, int imm32) {
         prefix(dst);
         emitArith(0x81, 0xC0, dst, imm32);
     }
 
-    public final void addl(CiRegister dst, CiAddress src) {
+    public final void addl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x03);
         emitOperandHelper(dst, src);
     }
 
-    public final void addl(CiRegister dst, CiRegister src) {
+    public final void addl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x03, 0xC0, dst, src);
     }
@@ -341,7 +367,7 @@
         emitInt(0); // 32-bits offset (4 bytes)
     }
 
-    public final void addsd(CiRegister dst, CiRegister src) {
+    public final void addsd(Register dst, Register src) {
         assert dst.isFpu() && src.isFpu();
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -350,7 +376,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void addsd(CiRegister dst, CiAddress src) {
+    public final void addsd(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF2);
         prefix(src, dst);
@@ -359,7 +385,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void addss(CiRegister dst, CiRegister src) {
+    public final void addss(Register dst, Register src) {
         assert dst.isFpu() && src.isFpu();
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -368,7 +394,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void addss(CiRegister dst, CiAddress src) {
+    public final void addss(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF3);
         prefix(src, dst);
@@ -377,36 +403,36 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void andl(CiRegister dst, int imm32) {
+    public final void andl(Register dst, int imm32) {
         prefix(dst);
         emitArith(0x81, 0xE0, dst, imm32);
     }
 
-    public final void andl(CiRegister dst, CiAddress src) {
+    public final void andl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x23);
         emitOperandHelper(dst, src);
     }
 
-    public final void andl(CiRegister dst, CiRegister src) {
+    public final void andl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x23, 0xC0, dst, src);
     }
 
-    public final void bsfq(CiRegister dst, CiRegister src) {
+    public final void bsfq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xBC);
         emitByte(0xC0 | encode);
     }
 
-    public final void bsfq(CiRegister dst, CiAddress src) {
+    public final void bsfq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0xBC);
         emitOperandHelper(dst, src);
     }
 
-    public final void bsrq(CiRegister dst, CiRegister src) {
+    public final void bsrq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xBD);
@@ -414,19 +440,19 @@
     }
 
 
-    public final void bsrq(CiRegister dst, CiAddress src) {
+    public final void bsrq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0xBD);
         emitOperandHelper(dst, src);
     }
 
-    public final void bswapl(CiRegister reg) { // bswap
+    public final void bswapl(Register reg) { // bswap
         int encode = prefixAndEncode(reg.encoding);
         emitByte(0x0F);
         emitByte(0xC8 | encode);
     }
 
-    public final void btli(CiAddress src, int imm8) {
+    public final void btli(Address src, int imm8) {
         prefixq(src);
         emitByte(0x0F);
         emitByte(0xBA);
@@ -438,45 +464,45 @@
         emitByte(0x99);
     }
 
-    public final void cmovl(ConditionFlag cc, CiRegister dst, CiRegister src) {
+    public final void cmovl(ConditionFlag cc, Register dst, Register src) {
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0x40 | cc.value);
         emitByte(0xC0 | encode);
     }
 
-    public final void cmovl(ConditionFlag cc, CiRegister dst, CiAddress src) {
+    public final void cmovl(ConditionFlag cc, Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0x40 | cc.value);
         emitOperandHelper(dst, src);
     }
 
-    public final void cmpb(CiAddress dst, int imm8) {
+    public final void cmpb(Address dst, int imm8) {
         prefix(dst);
         emitByte(0x80);
         emitOperandHelper(rdi, dst);
         emitByte(imm8);
     }
 
-    public final void cmpl(CiAddress dst, int imm32) {
+    public final void cmpl(Address dst, int imm32) {
         prefix(dst);
         emitByte(0x81);
         emitOperandHelper(rdi, dst);
         emitInt(imm32);
     }
 
-    public final void cmpl(CiRegister dst, int imm32) {
+    public final void cmpl(Register dst, int imm32) {
         prefix(dst);
         emitArith(0x81, 0xF8, dst, imm32);
     }
 
-    public final void cmpl(CiRegister dst, CiRegister src) {
+    public final void cmpl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x3B, 0xC0, dst, src);
     }
 
-    public final void cmpl(CiRegister dst, CiAddress src) {
+    public final void cmpl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x3B);
         emitOperandHelper(dst, src);
@@ -485,7 +511,7 @@
     // The 32-bit cmpxchg compares the value at adr with the contents of X86.rax,
     // and stores reg into adr if so; otherwise, the value at adr is loaded into X86.rax,.
     // The ZF is set if the compared values were equal, and cleared otherwise.
-    public final void cmpxchgl(CiRegister reg, CiAddress adr) { // cmpxchg
+    public final void cmpxchgl(Register reg, Address adr) { // cmpxchg
         if ((AsmOptions.Atomics & 2) != 0) {
             // caveat: no instructionmark, so this isn't relocatable.
             // Emit a synthetic, non-atomic, CAS equivalent.
@@ -508,7 +534,7 @@
         }
     }
 
-    public final void comisd(CiRegister dst, CiAddress src) {
+    public final void comisd(Register dst, Address src) {
         assert dst.isFpu();
         // NOTE: dbx seems to decode this as comiss even though the
         // 0x66 is there. Strangly ucomisd comes out correct
@@ -516,7 +542,7 @@
         comiss(dst, src);
     }
 
-    public final void comiss(CiRegister dst, CiAddress src) {
+    public final void comiss(Register dst, Address src) {
         assert dst.isFpu();
 
         prefix(src, dst);
@@ -525,7 +551,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void cvtdq2pd(CiRegister dst, CiRegister src) {
+    public final void cvtdq2pd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
 
@@ -536,7 +562,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvtdq2ps(CiRegister dst, CiRegister src) {
+    public final void cvtdq2ps(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -545,7 +571,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvtsd2ss(CiRegister dst, CiRegister src) {
+    public final void cvtsd2ss(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF2);
@@ -555,7 +581,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvtsi2sdl(CiRegister dst, CiRegister src) {
+    public final void cvtsi2sdl(Register dst, Register src) {
         assert dst.isFpu();
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -564,7 +590,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvtsi2ssl(CiRegister dst, CiRegister src) {
+    public final void cvtsi2ssl(Register dst, Register src) {
         assert dst.isFpu();
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -573,7 +599,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvtss2sd(CiRegister dst, CiRegister src) {
+    public final void cvtss2sd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF3);
@@ -583,7 +609,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvttsd2sil(CiRegister dst, CiRegister src) {
+    public final void cvttsd2sil(Register dst, Register src) {
         assert src.isFpu();
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -592,7 +618,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvttss2sil(CiRegister dst, CiRegister src) {
+    public final void cvttss2sil(Register dst, Register src) {
         assert src.isFpu();
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -601,14 +627,14 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void decl(CiAddress dst) {
+    public final void decl(Address dst) {
         // Don't use it directly. Use Macrodecrement() instead.
         prefix(dst);
         emitByte(0xFF);
         emitOperandHelper(rcx, dst);
     }
 
-    public final void divsd(CiRegister dst, CiAddress src) {
+    public final void divsd(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF2);
         prefix(src, dst);
@@ -617,7 +643,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void divsd(CiRegister dst, CiRegister src) {
+    public final void divsd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF2);
@@ -627,7 +653,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void divss(CiRegister dst, CiAddress src) {
+    public final void divss(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF3);
         prefix(src, dst);
@@ -636,7 +662,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void divss(CiRegister dst, CiRegister src) {
+    public final void divss(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF3);
@@ -650,26 +676,26 @@
         emitByte(0xF4);
     }
 
-    public final void idivl(CiRegister src) {
+    public final void idivl(Register src) {
         int encode = prefixAndEncode(src.encoding);
         emitByte(0xF7);
         emitByte(0xF8 | encode);
     }
 
-    public final void divl(CiRegister src) {
+    public final void divl(Register src) {
         int encode = prefixAndEncode(src.encoding);
         emitByte(0xF7);
         emitByte(0xF0 | encode);
     }
 
-    public final void imull(CiRegister dst, CiRegister src) {
+    public final void imull(Register dst, Register src) {
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xAF);
         emitByte(0xC0 | encode);
     }
 
-    public final void imull(CiRegister dst, CiRegister src, int value) {
+    public final void imull(Register dst, Register src, int value) {
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         if (isByte(value)) {
             emitByte(0x6B);
@@ -682,7 +708,7 @@
         }
     }
 
-    public final void incl(CiAddress dst) {
+    public final void incl(Address dst) {
         // Don't use it directly. Use Macroincrement() instead.
         prefix(dst);
         emitByte(0xFF);
@@ -740,7 +766,7 @@
         }
     }
 
-    public final void jmp(CiAddress adr) {
+    public final void jmp(Address adr) {
         prefix(adr);
         emitByte(0xFF);
         emitOperandHelper(rsp, adr);
@@ -775,7 +801,7 @@
         }
     }
 
-    public final void jmp(CiRegister entry) {
+    public final void jmp(Register entry) {
         int encode = prefixAndEncode(entry.encoding);
         emitByte(0xFF);
         emitByte(0xE0 | encode);
@@ -797,7 +823,7 @@
         }
     }
 
-    public final void leaq(CiRegister dst, CiAddress src) {
+    public final void leaq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x8D);
         emitOperandHelper(dst, src);
@@ -829,11 +855,11 @@
         emitByte(0xF0);
     }
 
-    public final void mov(CiRegister dst, CiRegister src) {
+    public final void mov(Register dst, Register src) {
         movq(dst, src);
     }
 
-    public final void movapd(CiRegister dst, CiRegister src) {
+    public final void movapd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         int dstenc = dst.encoding;
@@ -858,7 +884,7 @@
         emitByte(0xC0 | dstenc << 3 | srcenc);
     }
 
-    public final void movaps(CiRegister dst, CiRegister src) {
+    public final void movaps(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         int dstenc = dst.encoding;
@@ -882,27 +908,27 @@
         emitByte(0xC0 | dstenc << 3 | srcenc);
     }
 
-    public final void movb(CiRegister dst, CiAddress src) {
+    public final void movb(Register dst, Address src) {
         prefix(src, dst); // , true)
         emitByte(0x8A);
         emitOperandHelper(dst, src);
     }
 
-    public final void movb(CiAddress dst, int imm8) {
+    public final void movb(Address dst, int imm8) {
         prefix(dst);
         emitByte(0xC6);
         emitOperandHelper(rax, dst);
         emitByte(imm8);
     }
 
-    public final void movb(CiAddress dst, CiRegister src) {
+    public final void movb(Address dst, Register src) {
         assert src.isByte() : "must have byte register";
         prefix(dst, src); // , true)
         emitByte(0x88);
         emitOperandHelper(src, dst);
     }
 
-    public final void movdl(CiRegister dst, CiRegister src) {
+    public final void movdl(Register dst, Register src) {
         if (dst.isFpu()) {
             assert !src.isFpu() : "does this hold?";
             emitByte(0x66);
@@ -921,7 +947,7 @@
         }
     }
 
-    public final void movdqa(CiRegister dst, CiAddress src) {
+    public final void movdqa(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0x66);
         prefix(src, dst);
@@ -930,7 +956,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void movdqa(CiRegister dst, CiRegister src) {
+    public final void movdqa(Register dst, Register src) {
         assert dst.isFpu();
         emitByte(0x66);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
@@ -939,7 +965,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void movdqa(CiAddress dst, CiRegister src) {
+    public final void movdqa(Address dst, Register src) {
         assert src.isFpu();
         emitByte(0x66);
         prefix(dst, src);
@@ -948,7 +974,7 @@
         emitOperandHelper(src, dst);
     }
 
-    public final void movdqu(CiRegister dst, CiAddress src) {
+    public final void movdqu(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF3);
         prefix(src, dst);
@@ -957,7 +983,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void movdqu(CiRegister dst, CiRegister src) {
+    public final void movdqu(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
 
@@ -968,7 +994,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void movdqu(CiAddress dst, CiRegister src) {
+    public final void movdqu(Address dst, Register src) {
         assert src.isFpu();
 
         emitByte(0xF3);
@@ -978,32 +1004,32 @@
         emitOperandHelper(src, dst);
     }
 
-    public final void movl(CiRegister dst, int imm32) {
+    public final void movl(Register dst, int imm32) {
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0xB8 | encode);
         emitInt(imm32);
     }
 
-    public final void movl(CiRegister dst, CiRegister src) {
+    public final void movl(Register dst, Register src) {
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x8B);
         emitByte(0xC0 | encode);
     }
 
-    public final void movl(CiRegister dst, CiAddress src) {
+    public final void movl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x8B);
         emitOperandHelper(dst, src);
     }
 
-    public final void movl(CiAddress dst, int imm32) {
+    public final void movl(Address dst, int imm32) {
         prefix(dst);
         emitByte(0xC7);
         emitOperandHelper(rax, dst);
         emitInt(imm32);
     }
 
-    public final void movl(CiAddress dst, CiRegister src) {
+    public final void movl(Address dst, Register src) {
         prefix(dst, src);
         emitByte(0x89);
         emitOperandHelper(src, dst);
@@ -1012,10 +1038,10 @@
     /**
      * New CPUs require use of movsd and movss to avoid partial register stall
      * when loading from memory. But for old Opteron use movlpd instead of movsd.
-     * The selection is done in {@link AMD64MacroAssembler#movdbl(CiRegister, CiAddress)}
-     * and {@link AMD64MacroAssembler#movflt(CiRegister, CiRegister)}.
+     * The selection is done in {@link AMD64MacroAssembler#movdbl(Register, Address)}
+     * and {@link AMD64MacroAssembler#movflt(Register, Register)}.
      */
-    public final void movlpd(CiRegister dst, CiAddress src) {
+    public final void movlpd(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0x66);
         prefix(src, dst);
@@ -1024,7 +1050,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void movlpd(CiAddress dst, CiRegister src) {
+    public final void movlpd(Address dst, Register src) {
         assert src.isFpu();
         emitByte(0x66);
         prefix(dst, src);
@@ -1033,7 +1059,7 @@
         emitOperandHelper(src, dst);
     }
 
-    public final void movq(CiRegister dst, CiAddress src) {
+    public final void movq(Register dst, Address src) {
         if (dst.isFpu()) {
             emitByte(0xF3);
             prefixq(src, dst);
@@ -1047,13 +1073,13 @@
         }
     }
 
-    public final void movq(CiRegister dst, CiRegister src) {
+    public final void movq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x8B);
         emitByte(0xC0 | encode);
     }
 
-    public final void movq(CiAddress dst, CiRegister src) {
+    public final void movq(Address dst, Register src) {
         if (src.isFpu()) {
             emitByte(0x66);
             prefixq(dst, src);
@@ -1067,21 +1093,21 @@
         }
     }
 
-    public final void movsxb(CiRegister dst, CiAddress src) { // movsxb
+    public final void movsxb(Register dst, Address src) { // movsxb
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0xBE);
         emitOperandHelper(dst, src);
     }
 
-    public final void movsxb(CiRegister dst, CiRegister src) { // movsxb
+    public final void movsxb(Register dst, Register src) { // movsxb
         int encode = prefixAndEncode(dst.encoding, src.encoding, true);
         emitByte(0x0F);
         emitByte(0xBE);
         emitByte(0xC0 | encode);
     }
 
-    public final void movsd(CiRegister dst, CiRegister src) {
+    public final void movsd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF2);
@@ -1091,7 +1117,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void movsd(CiRegister dst, CiAddress src) {
+    public final void movsd(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF2);
         prefix(src, dst);
@@ -1100,7 +1126,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void movsd(CiAddress dst, CiRegister src) {
+    public final void movsd(Address dst, Register src) {
         assert src.isFpu();
         emitByte(0xF2);
         prefix(dst, src);
@@ -1109,7 +1135,7 @@
         emitOperandHelper(src, dst);
     }
 
-    public final void movss(CiRegister dst, CiRegister src) {
+    public final void movss(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF3);
@@ -1119,7 +1145,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void movss(CiRegister dst, CiAddress src) {
+    public final void movss(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF3);
         prefix(src, dst);
@@ -1128,7 +1154,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void movss(CiAddress dst, CiRegister src) {
+    public final void movss(Address dst, Register src) {
         assert src.isFpu();
         emitByte(0xF3);
         prefix(dst, src);
@@ -1137,40 +1163,40 @@
         emitOperandHelper(src, dst);
     }
 
-    public final void movswl(CiRegister dst, CiAddress src) {
+    public final void movswl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0xBF);
         emitOperandHelper(dst, src);
     }
 
-    public final void movsxw(CiRegister dst, CiRegister src) { // movsxw
+    public final void movsxw(Register dst, Register src) { // movsxw
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xBF);
         emitByte(0xC0 | encode);
     }
 
-    public final void movsxw(CiRegister dst, CiAddress src) { // movsxw
+    public final void movsxw(Register dst, Address src) { // movsxw
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0xBF);
         emitOperandHelper(dst, src);
     }
 
-    public final void movzxd(CiRegister dst, CiRegister src) { // movzxd
+    public final void movzxd(Register dst, Register src) { // movzxd
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x63);
         emitByte(0xC0 | encode);
     }
 
-    public final void movzxd(CiRegister dst, CiAddress src) { // movzxd
+    public final void movzxd(Register dst, Address src) { // movzxd
         prefix(src, dst);
         emitByte(0x63);
         emitOperandHelper(dst, src);
     }
 
-    public final void movw(CiAddress dst, int imm16) {
+    public final void movw(Address dst, int imm16) {
         emitByte(0x66); // switch to 16-bit mode
         prefix(dst);
         emitByte(0xC7);
@@ -1178,55 +1204,55 @@
         emitShort(imm16);
     }
 
-    public final void movw(CiRegister dst, CiAddress src) {
+    public final void movw(Register dst, Address src) {
         emitByte(0x66);
         prefix(src, dst);
         emitByte(0x8B);
         emitOperandHelper(dst, src);
     }
 
-    public final void movw(CiAddress dst, CiRegister src) {
+    public final void movw(Address dst, Register src) {
         emitByte(0x66);
         prefix(dst, src);
         emitByte(0x89);
         emitOperandHelper(src, dst);
     }
 
-    public final void movzxb(CiRegister dst, CiAddress src) { // movzxb
+    public final void movzxb(Register dst, Address src) { // movzxb
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0xB6);
         emitOperandHelper(dst, src);
     }
 
-    public final void movzxb(CiRegister dst, CiRegister src) { // movzxb
+    public final void movzxb(Register dst, Register src) { // movzxb
         int encode = prefixAndEncode(dst.encoding, src.encoding, true);
         emitByte(0x0F);
         emitByte(0xB6);
         emitByte(0xC0 | encode);
     }
 
-    public final void movzxl(CiRegister dst, CiAddress src) { // movzxw
+    public final void movzxl(Register dst, Address src) { // movzxw
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0xB7);
         emitOperandHelper(dst, src);
     }
 
-    public final void movzxl(CiRegister dst, CiRegister src) { // movzxw
+    public final void movzxl(Register dst, Register src) { // movzxw
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xB7);
         emitByte(0xC0 | encode);
     }
 
-    public final void mull(CiAddress src) {
+    public final void mull(Address src) {
         prefix(src);
         emitByte(0xF7);
         emitOperandHelper(rsp, src);
     }
 
-    public final void mulsd(CiRegister dst, CiAddress src) {
+    public final void mulsd(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0xF2);
         prefix(src, dst);
@@ -1235,7 +1261,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void mulsd(CiRegister dst, CiRegister src) {
+    public final void mulsd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
 
@@ -1246,7 +1272,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void mulss(CiRegister dst, CiAddress src) {
+    public final void mulss(Register dst, Address src) {
         assert dst.isFpu();
 
         emitByte(0xF3);
@@ -1256,7 +1282,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void mulss(CiRegister dst, CiRegister src) {
+    public final void mulss(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF3);
@@ -1266,7 +1292,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void negl(CiRegister dst) {
+    public final void negl(Register dst) {
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0xF7);
         emitByte(0xD8 | encode);
@@ -1482,84 +1508,84 @@
         }
     }
 
-    public final void notl(CiRegister dst) {
+    public final void notl(Register dst) {
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0xF7);
         emitByte(0xD0 | encode);
     }
 
-    public final void orl(CiAddress dst, int imm32) {
+    public final void orl(Address dst, int imm32) {
         prefix(dst);
         emitByte(0x81);
         emitOperandHelper(rcx, dst);
         emitInt(imm32);
     }
 
-    public final void orl(CiRegister dst, int imm32) {
+    public final void orl(Register dst, int imm32) {
         prefix(dst);
         emitArith(0x81, 0xC8, dst, imm32);
     }
 
-    public final void orl(CiRegister dst, CiAddress src) {
+    public final void orl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x0B);
         emitOperandHelper(dst, src);
     }
 
-    public final void orl(CiRegister dst, CiRegister src) {
+    public final void orl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x0B, 0xC0, dst, src);
     }
 
     // generic
-    public final void pop(CiRegister dst) {
+    public final void pop(Register dst) {
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0x58 | encode);
     }
 
-    public final void prefetchPrefix(CiAddress src) {
+    public final void prefetchPrefix(Address src) {
         prefix(src);
         emitByte(0x0F);
     }
 
-    public final void prefetchnta(CiAddress src) {
+    public final void prefetchnta(Address src) {
         prefetchPrefix(src);
         emitByte(0x18);
         emitOperandHelper(rax, src); // 0, src
     }
 
-    public final void prefetchr(CiAddress src) {
+    public final void prefetchr(Address src) {
         prefetchPrefix(src);
         emitByte(0x0D);
         emitOperandHelper(rax, src); // 0, src
     }
 
-    public final void prefetcht0(CiAddress src) {
+    public final void prefetcht0(Address src) {
         prefetchPrefix(src);
         emitByte(0x18);
         emitOperandHelper(rcx, src); // 1, src
 
     }
 
-    public final void prefetcht1(CiAddress src) {
+    public final void prefetcht1(Address src) {
         prefetchPrefix(src);
         emitByte(0x18);
         emitOperandHelper(rdx, src); // 2, src
     }
 
-    public final void prefetcht2(CiAddress src) {
+    public final void prefetcht2(Address src) {
         prefetchPrefix(src);
         emitByte(0x18);
         emitOperandHelper(rbx, src); // 3, src
     }
 
-    public final void prefetchw(CiAddress src) {
+    public final void prefetchw(Address src) {
         prefetchPrefix(src);
         emitByte(0x0D);
         emitOperandHelper(rcx, src); // 1, src
     }
 
-    public final void pshufd(CiRegister dst, CiRegister src, int mode) {
+    public final void pshufd(Register dst, Register src, int mode) {
         assert dst.isFpu();
         assert src.isFpu();
         assert isUByte(mode) : "invalid value";
@@ -1572,7 +1598,7 @@
         emitByte(mode & 0xFF);
     }
 
-    public final void pshufd(CiRegister dst, CiAddress src, int mode) {
+    public final void pshufd(Register dst, Address src, int mode) {
         assert dst.isFpu();
         assert isUByte(mode) : "invalid value";
 
@@ -1585,7 +1611,7 @@
 
     }
 
-    public final void pshuflw(CiRegister dst, CiRegister src, int mode) {
+    public final void pshuflw(Register dst, Register src, int mode) {
         assert dst.isFpu();
         assert src.isFpu();
         assert isUByte(mode) : "invalid value";
@@ -1598,7 +1624,7 @@
         emitByte(mode & 0xFF);
     }
 
-    public final void pshuflw(CiRegister dst, CiAddress src, int mode) {
+    public final void pshuflw(Register dst, Address src, int mode) {
         assert dst.isFpu();
         assert isUByte(mode) : "invalid value";
 
@@ -1610,7 +1636,7 @@
         emitByte(mode & 0xFF);
     }
 
-    public final void psrlq(CiRegister dst, int shift) {
+    public final void psrlq(Register dst, int shift) {
         assert dst.isFpu();
         // HMM Table D-1 says sse2 or mmx
 
@@ -1622,7 +1648,7 @@
         emitByte(shift);
     }
 
-    public final void punpcklbw(CiRegister dst, CiRegister src) {
+    public final void punpcklbw(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0x66);
@@ -1639,7 +1665,7 @@
         emitInt(imm32);
     }
 
-    public final void push(CiRegister src) {
+    public final void push(Register src) {
         int encode = prefixAndEncode(src.encoding);
         emitByte(0x50 | encode);
     }
@@ -1648,7 +1674,7 @@
         emitByte(0x9C);
     }
 
-    public final void pxor(CiRegister dst, CiAddress src) {
+    public final void pxor(Register dst, Address src) {
         assert dst.isFpu();
 
         emitByte(0x66);
@@ -1658,7 +1684,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void pxor(CiRegister dst, CiRegister src) {
+    public final void pxor(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
 
@@ -1670,7 +1696,7 @@
 
     }
 
-    public final void rcll(CiRegister dst, int imm8) {
+    public final void rcll(Register dst, int imm8) {
         assert isShiftCount(imm8) : "illegal shift count";
         int encode = prefixAndEncode(dst.encoding);
         if (imm8 == 1) {
@@ -1737,7 +1763,7 @@
         }
     }
 
-    public final void sarl(CiRegister dst, int imm8) {
+    public final void sarl(Register dst, int imm8) {
         int encode = prefixAndEncode(dst.encoding);
         assert isShiftCount(imm8) : "illegal shift count";
         if (imm8 == 1) {
@@ -1750,34 +1776,34 @@
         }
     }
 
-    public final void sarl(CiRegister dst) {
+    public final void sarl(Register dst) {
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0xD3);
         emitByte(0xF8 | encode);
     }
 
-    public final void sbbl(CiAddress dst, int imm32) {
+    public final void sbbl(Address dst, int imm32) {
         prefix(dst);
         emitArithOperand(0x81, rbx, dst, imm32);
     }
 
-    public final void sbbl(CiRegister dst, int imm32) {
+    public final void sbbl(Register dst, int imm32) {
         prefix(dst);
         emitArith(0x81, 0xD8, dst, imm32);
     }
 
-    public final void sbbl(CiRegister dst, CiAddress src) {
+    public final void sbbl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x1B);
         emitOperandHelper(dst, src);
     }
 
-    public final void sbbl(CiRegister dst, CiRegister src) {
+    public final void sbbl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x1B, 0xC0, dst, src);
     }
 
-    public final void setb(ConditionFlag cc, CiRegister dst) {
+    public final void setb(ConditionFlag cc, Register dst) {
         assert 0 <= cc.value && cc.value < 16 : "illegal cc";
         int encode = prefixAndEncode(dst.encoding, true);
         emitByte(0x0F);
@@ -1785,7 +1811,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void shll(CiRegister dst, int imm8) {
+    public final void shll(Register dst, int imm8) {
         assert isShiftCount(imm8) : "illegal shift count";
         int encode = prefixAndEncode(dst.encoding);
         if (imm8 == 1) {
@@ -1798,13 +1824,13 @@
         }
     }
 
-    public final void shll(CiRegister dst) {
+    public final void shll(Register dst) {
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0xD3);
         emitByte(0xE0 | encode);
     }
 
-    public final void shrl(CiRegister dst, int imm8) {
+    public final void shrl(Register dst, int imm8) {
         assert isShiftCount(imm8) : "illegal shift count";
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0xC1);
@@ -1812,7 +1838,7 @@
         emitByte(imm8);
     }
 
-    public final void shrl(CiRegister dst) {
+    public final void shrl(Register dst) {
         int encode = prefixAndEncode(dst.encoding);
         emitByte(0xD3);
         emitByte(0xE8 | encode);
@@ -1823,7 +1849,7 @@
         emitByte(0xA5);
     }
 
-    public final void sqrtsd(CiRegister dst, CiRegister src) {
+    public final void sqrtsd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         // HMM Table D-1 says sse2
@@ -1835,7 +1861,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void subl(CiAddress dst, int imm32) {
+    public final void subl(Address dst, int imm32) {
         prefix(dst);
         if (isByte(imm32)) {
             emitByte(0x83);
@@ -1848,29 +1874,29 @@
         }
     }
 
-    public final void subl(CiRegister dst, int imm32) {
+    public final void subl(Register dst, int imm32) {
         prefix(dst);
         emitArith(0x81, 0xE8, dst, imm32);
     }
 
-    public final void subl(CiAddress dst, CiRegister src) {
+    public final void subl(Address dst, Register src) {
         prefix(dst, src);
         emitByte(0x29);
         emitOperandHelper(src, dst);
     }
 
-    public final void subl(CiRegister dst, CiAddress src) {
+    public final void subl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x2B);
         emitOperandHelper(dst, src);
     }
 
-    public final void subl(CiRegister dst, CiRegister src) {
+    public final void subl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x2B, 0xC0, dst, src);
     }
 
-    public final void subsd(CiRegister dst, CiRegister src) {
+    public final void subsd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF2);
@@ -1880,7 +1906,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void subsd(CiRegister dst, CiAddress src) {
+    public final void subsd(Register dst, Address src) {
         assert dst.isFpu();
 
         emitByte(0xF2);
@@ -1890,7 +1916,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void subss(CiRegister dst, CiRegister src) {
+    public final void subss(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0xF3);
@@ -1900,7 +1926,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void subss(CiRegister dst, CiAddress src) {
+    public final void subss(Register dst, Address src) {
         assert dst.isFpu();
 
         emitByte(0xF3);
@@ -1910,12 +1936,12 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void testb(CiRegister dst, int imm8) {
+    public final void testb(Register dst, int imm8) {
         prefixAndEncode(dst.encoding, true);
         emitArithB(0xF6, 0xC0, dst, imm8);
     }
 
-    public final void testl(CiRegister dst, int imm32) {
+    public final void testl(Register dst, int imm32) {
         // not using emitArith because test
         // doesn't support sign-extension of
         // 8bit operands
@@ -1930,31 +1956,31 @@
         emitInt(imm32);
     }
 
-    public final void testl(CiRegister dst, CiRegister src) {
+    public final void testl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x85, 0xC0, dst, src);
     }
 
-    public final void testl(CiRegister dst, CiAddress src) {
+    public final void testl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x85);
         emitOperandHelper(dst, src);
     }
 
-    public final void ucomisd(CiRegister dst, CiAddress src) {
+    public final void ucomisd(Register dst, Address src) {
         assert dst.isFpu();
         emitByte(0x66);
         ucomiss(dst, src);
     }
 
-    public final void ucomisd(CiRegister dst, CiRegister src) {
+    public final void ucomisd(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         emitByte(0x66);
         ucomiss(dst, src);
     }
 
-    public final void ucomiss(CiRegister dst, CiAddress src) {
+    public final void ucomiss(Register dst, Address src) {
         assert dst.isFpu();
 
         prefix(src, dst);
@@ -1963,7 +1989,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void ucomiss(CiRegister dst, CiRegister src) {
+    public final void ucomiss(Register dst, Register src) {
         assert dst.isFpu();
         assert src.isFpu();
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -1972,7 +1998,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void xaddl(CiAddress dst, CiRegister src) {
+    public final void xaddl(Address dst, Register src) {
         assert src.isFpu();
 
         prefix(dst, src);
@@ -1981,45 +2007,45 @@
         emitOperandHelper(src, dst);
     }
 
-    public final void xchgl(CiRegister dst, CiAddress src) { // xchg
+    public final void xchgl(Register dst, Address src) { // xchg
         prefix(src, dst);
         emitByte(0x87);
         emitOperandHelper(dst, src);
     }
 
-    public final void xchgl(CiRegister dst, CiRegister src) {
+    public final void xchgl(Register dst, Register src) {
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x87);
         emitByte(0xc0 | encode);
     }
 
-    public final void xorl(CiRegister dst, int imm32) {
+    public final void xorl(Register dst, int imm32) {
         prefix(dst);
         emitArith(0x81, 0xF0, dst, imm32);
     }
 
-    public final void xorl(CiRegister dst, CiAddress src) {
+    public final void xorl(Register dst, Address src) {
         prefix(src, dst);
         emitByte(0x33);
         emitOperandHelper(dst, src);
     }
 
-    public final void xorl(CiRegister dst, CiRegister src) {
+    public final void xorl(Register dst, Register src) {
         prefixAndEncode(dst.encoding, src.encoding);
         emitArith(0x33, 0xC0, dst, src);
     }
 
-    public final void andpd(CiRegister dst, CiRegister src) {
+    public final void andpd(Register dst, Register src) {
         emitByte(0x66);
         andps(dst, src);
     }
 
-    public final void andpd(CiRegister dst, CiAddress src) {
+    public final void andpd(Register dst, Address src) {
         emitByte(0x66);
         andps(dst, src);
     }
 
-    public final void andps(CiRegister dst, CiRegister src) {
+    public final void andps(Register dst, Register src) {
         assert dst.isFpu() && src.isFpu();
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -2027,7 +2053,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void andps(CiRegister dst, CiAddress src) {
+    public final void andps(Register dst, Address src) {
         assert dst.isFpu();
         prefix(src, dst);
         emitByte(0x0F);
@@ -2035,17 +2061,17 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void orpd(CiRegister dst, CiRegister src) {
+    public final void orpd(Register dst, Register src) {
         emitByte(0x66);
         orps(dst, src);
     }
 
-    public final void orpd(CiRegister dst, CiAddress src) {
+    public final void orpd(Register dst, Address src) {
         emitByte(0x66);
         orps(dst, src);
     }
 
-    public final void orps(CiRegister dst, CiRegister src) {
+    public final void orps(Register dst, Register src) {
         assert dst.isFpu() && src.isFpu();
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -2053,7 +2079,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void orps(CiRegister dst, CiAddress src) {
+    public final void orps(Register dst, Address src) {
         assert dst.isFpu();
         prefix(src, dst);
         emitByte(0x0F);
@@ -2061,17 +2087,17 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void xorpd(CiRegister dst, CiRegister src) {
+    public final void xorpd(Register dst, Register src) {
         emitByte(0x66);
         xorps(dst, src);
     }
 
-    public final void xorpd(CiRegister dst, CiAddress src) {
+    public final void xorpd(Register dst, Address src) {
         emitByte(0x66);
         xorps(dst, src);
     }
 
-    public final void xorps(CiRegister dst, CiRegister src) {
+    public final void xorps(Register dst, Register src) {
         assert dst.isFpu() && src.isFpu();
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -2079,7 +2105,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void xorps(CiRegister dst, CiAddress src) {
+    public final void xorps(Register dst, Address src) {
         assert dst.isFpu();
         prefix(src, dst);
         emitByte(0x0F);
@@ -2089,7 +2115,7 @@
 
     // 32bit only pieces of the assembler
 
-    public final void decl(CiRegister dst) {
+    public final void decl(Register dst) {
         // Don't use it directly. Use Macrodecrementl() instead.
         // Use two-byte form (one-byte form is a REX prefix in 64-bit mode)
         int encode = prefixAndEncode(dst.encoding);
@@ -2097,7 +2123,7 @@
         emitByte(0xC8 | encode);
     }
 
-    public final void incl(CiRegister dst) {
+    public final void incl(Register dst) {
         // Don't use it directly. Use Macroincrementl() instead.
         // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
         int encode = prefixAndEncode(dst.encoding);
@@ -2185,40 +2211,40 @@
         return regEnc << 3 | rmEnc;
     }
 
-    private void prefix(CiRegister reg) {
+    private void prefix(Register reg) {
         if (reg.encoding >= 8) {
             emitByte(Prefix.REXB);
         }
     }
 
-    private static boolean needsRex(CiValue value) {
+    private static boolean needsRex(Value value) {
         return isRegister(value) && asRegister(value).encoding >= MinEncodingNeedsRex;
     }
 
 
-    private void prefix(CiAddress adr) {
-        if (needsRex(adr.base)) {
-            if (needsRex(adr.index)) {
+    private void prefix(Address adr) {
+        if (needsRex(adr.getBase())) {
+            if (needsRex(adr.getIndex())) {
                 emitByte(Prefix.REXXB);
             } else {
                 emitByte(Prefix.REXB);
             }
         } else {
-            if (needsRex(adr.index)) {
+            if (needsRex(adr.getIndex())) {
                 emitByte(Prefix.REXX);
             }
         }
     }
 
-    private void prefixq(CiAddress adr) {
-        if (needsRex(adr.base)) {
-            if (needsRex(adr.index)) {
+    private void prefixq(Address adr) {
+        if (needsRex(adr.getBase())) {
+            if (needsRex(adr.getIndex())) {
                 emitByte(Prefix.REXWXB);
             } else {
                 emitByte(Prefix.REXWB);
             }
         } else {
-            if (needsRex(adr.index)) {
+            if (needsRex(adr.getIndex())) {
                 emitByte(Prefix.REXWX);
             } else {
                 emitByte(Prefix.REXW);
@@ -2226,30 +2252,30 @@
         }
     }
 
-    private void prefix(CiAddress adr, CiRegister reg) {
+    private void prefix(Address adr, Register reg) {
         if (reg.encoding < 8) {
-            if (needsRex(adr.base)) {
-                if (needsRex(adr.index)) {
+            if (needsRex(adr.getBase())) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXXB);
                 } else {
                     emitByte(Prefix.REXB);
                 }
             } else {
-                if (needsRex(adr.index)) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXX);
                 } else if (reg.encoding >= 4) {
                     emitByte(Prefix.REX);
                 }
             }
         } else {
-            if (needsRex(adr.base)) {
-                if (needsRex(adr.index)) {
+            if (needsRex(adr.getBase())) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXRXB);
                 } else {
                     emitByte(Prefix.REXRB);
                 }
             } else {
-                if (needsRex(adr.index)) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXRX);
                 } else {
                     emitByte(Prefix.REXR);
@@ -2258,30 +2284,30 @@
         }
     }
 
-    private void prefixq(CiAddress adr, CiRegister src) {
+    private void prefixq(Address adr, Register src) {
         if (src.encoding < 8) {
-            if (needsRex(adr.base)) {
-                if (needsRex(adr.index)) {
+            if (needsRex(adr.getBase())) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXWXB);
                 } else {
                     emitByte(Prefix.REXWB);
                 }
             } else {
-                if (needsRex(adr.index)) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXWX);
                 } else {
                     emitByte(Prefix.REXW);
                 }
             }
         } else {
-            if (needsRex(adr.base)) {
-                if (needsRex(adr.index)) {
+            if (needsRex(adr.getBase())) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXWRXB);
                 } else {
                     emitByte(Prefix.REXWRB);
                 }
             } else {
-                if (needsRex(adr.index)) {
+                if (needsRex(adr.getIndex())) {
                     emitByte(Prefix.REXWRX);
                 } else {
                     emitByte(Prefix.REXWR);
@@ -2290,50 +2316,50 @@
         }
     }
 
-    public final void addq(CiAddress dst, int imm32) {
+    public final void addq(Address dst, int imm32) {
         prefixq(dst);
         emitArithOperand(0x81, rax, dst, imm32);
     }
 
-    public final void addq(CiAddress dst, CiRegister src) {
+    public final void addq(Address dst, Register src) {
         prefixq(dst, src);
         emitByte(0x01);
         emitOperandHelper(src, dst);
     }
 
-    public final void addq(CiRegister dst, int imm32) {
+    public final void addq(Register dst, int imm32) {
         prefixqAndEncode(dst.encoding);
         emitArith(0x81, 0xC0, dst, imm32);
     }
 
-    public final void addq(CiRegister dst, CiAddress src) {
+    public final void addq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x03);
         emitOperandHelper(dst, src);
     }
 
-    public final void addq(CiRegister dst, CiRegister src) {
+    public final void addq(Register dst, Register src) {
         prefixqAndEncode(dst.encoding, src.encoding);
         emitArith(0x03, 0xC0, dst, src);
     }
 
-    public final void andq(CiRegister dst, int imm32) {
+    public final void andq(Register dst, int imm32) {
         prefixqAndEncode(dst.encoding);
         emitArith(0x81, 0xE0, dst, imm32);
     }
 
-    public final void andq(CiRegister dst, CiAddress src) {
+    public final void andq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x23);
         emitOperandHelper(dst, src);
     }
 
-    public final void andq(CiRegister dst, CiRegister src) {
+    public final void andq(Register dst, Register src) {
         prefixqAndEncode(dst.encoding, src.encoding);
         emitArith(0x23, 0xC0, dst, src);
     }
 
-    public final void bswapq(CiRegister reg) {
+    public final void bswapq(Register reg) {
         int encode = prefixqAndEncode(reg.encoding);
         emitByte(0x0F);
         emitByte(0xC8 | encode);
@@ -2344,57 +2370,57 @@
         emitByte(0x99);
     }
 
-    public final void cmovq(ConditionFlag cc, CiRegister dst, CiRegister src) {
+    public final void cmovq(ConditionFlag cc, Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0x40 | cc.value);
         emitByte(0xC0 | encode);
     }
 
-    public final void cmovq(ConditionFlag cc, CiRegister dst, CiAddress src) {
+    public final void cmovq(ConditionFlag cc, Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x0F);
         emitByte(0x40 | cc.value);
         emitOperandHelper(dst, src);
     }
 
-    public final void cmpq(CiAddress dst, int imm32) {
+    public final void cmpq(Address dst, int imm32) {
         prefixq(dst);
         emitByte(0x81);
         emitOperandHelper(rdi, dst);
         emitInt(imm32);
     }
 
-    public final void cmpq(CiRegister dst, int imm32) {
+    public final void cmpq(Register dst, int imm32) {
         prefixqAndEncode(dst.encoding);
         emitArith(0x81, 0xF8, dst, imm32);
     }
 
-    public final void cmpq(CiAddress dst, CiRegister src) {
+    public final void cmpq(Address dst, Register src) {
         prefixq(dst, src);
         emitByte(0x3B);
         emitOperandHelper(src, dst);
     }
 
-    public final void cmpq(CiRegister dst, CiRegister src) {
+    public final void cmpq(Register dst, Register src) {
         prefixqAndEncode(dst.encoding, src.encoding);
         emitArith(0x3B, 0xC0, dst, src);
     }
 
-    public final void cmpq(CiRegister dst, CiAddress src) {
+    public final void cmpq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x3B);
         emitOperandHelper(dst, src);
     }
 
-    public final void cmpxchgq(CiRegister reg, CiAddress adr) {
+    public final void cmpxchgq(Register reg, Address adr) {
         prefixq(adr, reg);
         emitByte(0x0F);
         emitByte(0xB1);
         emitOperandHelper(reg, adr);
     }
 
-    public final void cvtsi2sdq(CiRegister dst, CiRegister src) {
+    public final void cvtsi2sdq(Register dst, Register src) {
         assert dst.isFpu();
         emitByte(0xF2);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
@@ -2403,7 +2429,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvtsi2ssq(CiRegister dst, CiRegister src) {
+    public final void cvtsi2ssq(Register dst, Register src) {
         assert dst.isFpu();
         emitByte(0xF3);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
@@ -2412,7 +2438,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvttsd2siq(CiRegister dst, CiRegister src) {
+    public final void cvttsd2siq(Register dst, Register src) {
         assert src.isFpu();
         emitByte(0xF2);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
@@ -2421,7 +2447,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void cvttss2siq(CiRegister dst, CiRegister src) {
+    public final void cvttss2siq(Register dst, Register src) {
         assert src.isFpu();
         emitByte(0xF3);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
@@ -2430,7 +2456,7 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void decq(CiRegister dst) {
+    public final void decq(Register dst) {
         // Don't use it directly. Use Macrodecrementq() instead.
         // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
         int encode = prefixqAndEncode(dst.encoding);
@@ -2438,33 +2464,33 @@
         emitByte(0xC8 | encode);
     }
 
-    public final void decq(CiAddress dst) {
+    public final void decq(Address dst) {
         // Don't use it directly. Use Macrodecrementq() instead.
         prefixq(dst);
         emitByte(0xFF);
         emitOperandHelper(rcx, dst);
     }
 
-    public final void divq(CiRegister src) {
+    public final void divq(Register src) {
         int encode = prefixqAndEncode(src.encoding);
         emitByte(0xF7);
         emitByte(0xF0 | encode);
     }
 
-    public final void idivq(CiRegister src) {
+    public final void idivq(Register src) {
         int encode = prefixqAndEncode(src.encoding);
         emitByte(0xF7);
         emitByte(0xF8 | encode);
     }
 
-    public final void imulq(CiRegister dst, CiRegister src) {
+    public final void imulq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xAF);
         emitByte(0xC0 | encode);
     }
 
-    public final void imulq(CiRegister dst, CiRegister src, int value) {
+    public final void imulq(Register dst, Register src, int value) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         if (isByte(value)) {
             emitByte(0x6B);
@@ -2477,7 +2503,7 @@
         }
     }
 
-    public final void incq(CiRegister dst) {
+    public final void incq(Register dst) {
         // Don't use it directly. Use Macroincrementq() instead.
         // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
         int encode = prefixqAndEncode(dst.encoding);
@@ -2485,20 +2511,20 @@
         emitByte(0xC0 | encode);
     }
 
-    public final void incq(CiAddress dst) {
+    public final void incq(Address dst) {
         // Don't use it directly. Use Macroincrementq() instead.
         prefixq(dst);
         emitByte(0xFF);
         emitOperandHelper(rax, dst);
     }
 
-    public final void movq(CiRegister dst, long imm64) {
+    public final void movq(Register dst, long imm64) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xB8 | encode);
         emitLong(imm64);
     }
 
-    public final void movdq(CiRegister dst, CiRegister src) {
+    public final void movdq(Register dst, Register src) {
 
         // table D-1 says MMX/SSE2
         emitByte(0x66);
@@ -2521,21 +2547,21 @@
         }
     }
 
-    public final void movsbq(CiRegister dst, CiAddress src) {
+    public final void movsbq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x0F);
         emitByte(0xBE);
         emitOperandHelper(dst, src);
     }
 
-    public final void movsbq(CiRegister dst, CiRegister src) {
+    public final void movsbq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xBE);
         emitByte(0xC0 | encode);
     }
 
-    public final void movslq(CiRegister dst, int imm32) {
+    public final void movslq(Register dst, int imm32) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xC7 | encode);
         emitInt(imm32);
@@ -2545,115 +2571,115 @@
         throw new InternalError("untested");
     }
 
-    public final void movslq(CiAddress dst, int imm32) {
+    public final void movslq(Address dst, int imm32) {
         prefixq(dst);
         emitByte(0xC7);
         emitOperandHelper(rax, dst);
         emitInt(imm32);
     }
 
-    public final void movslq(CiRegister dst, CiAddress src) {
+    public final void movslq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x63);
         emitOperandHelper(dst, src);
     }
 
-    public final void movslq(CiRegister dst, CiRegister src) {
+    public final void movslq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x63);
         emitByte(0xC0 | encode);
     }
 
-    public final void movswq(CiRegister dst, CiAddress src) {
+    public final void movswq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x0F);
         emitByte(0xBF);
         emitOperandHelper(dst, src);
     }
 
-    public final void movswq(CiRegister dst, CiRegister src) {
+    public final void movswq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xBF);
         emitByte(0xC0 | encode);
     }
 
-    public final void movzbq(CiRegister dst, CiAddress src) {
+    public final void movzbq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x0F);
         emitByte(0xB6);
         emitOperandHelper(dst, src);
     }
 
-    public final void movzbq(CiRegister dst, CiRegister src) {
+    public final void movzbq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xB6);
         emitByte(0xC0 | encode);
     }
 
-    public final void movzwq(CiRegister dst, CiAddress src) {
+    public final void movzwq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x0F);
         emitByte(0xB7);
         emitOperandHelper(dst, src);
     }
 
-    public final void movzwq(CiRegister dst, CiRegister src) {
+    public final void movzwq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0xB7);
         emitByte(0xC0 | encode);
     }
 
-    public final void negq(CiRegister dst) {
+    public final void negq(Register dst) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xF7);
         emitByte(0xD8 | encode);
     }
 
-    public final void notq(CiRegister dst) {
+    public final void notq(Register dst) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xF7);
         emitByte(0xD0 | encode);
     }
 
-    public final void orq(CiAddress dst, int imm32) {
+    public final void orq(Address dst, int imm32) {
         prefixq(dst);
         emitByte(0x81);
         emitOperandHelper(rcx, dst);
         emitInt(imm32);
     }
 
-    public final void orq(CiRegister dst, int imm32) {
+    public final void orq(Register dst, int imm32) {
         prefixqAndEncode(dst.encoding);
         emitArith(0x81, 0xC8, dst, imm32);
     }
 
-    public final void orq(CiRegister dst, CiAddress src) {
+    public final void orq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x0B);
         emitOperandHelper(dst, src);
     }
 
-    public final void orq(CiRegister dst, CiRegister src) {
+    public final void orq(Register dst, Register src) {
         prefixqAndEncode(dst.encoding, src.encoding);
         emitArith(0x0B, 0xC0, dst, src);
     }
 
-    public final void popq(CiAddress dst) {
+    public final void popq(Address dst) {
         prefixq(dst);
         emitByte(0x8F);
         emitOperandHelper(rax, dst);
     }
 
-    public final void pushq(CiAddress src) {
+    public final void pushq(Address src) {
         prefixq(src);
         emitByte(0xFF);
         emitOperandHelper(rsi, src);
     }
 
-    public final void rclq(CiRegister dst, int imm8) {
+    public final void rclq(Register dst, int imm8) {
         assert isShiftCount(imm8 >> 1) : "illegal shift count";
         int encode = prefixqAndEncode(dst.encoding);
         if (imm8 == 1) {
@@ -2666,7 +2692,7 @@
         }
     }
 
-    public final void sarq(CiRegister dst, int imm8) {
+    public final void sarq(Register dst, int imm8) {
         assert isShiftCount(imm8 >> 1) : "illegal shift count";
         int encode = prefixqAndEncode(dst.encoding);
         if (imm8 == 1) {
@@ -2679,13 +2705,13 @@
         }
     }
 
-    public final void sarq(CiRegister dst) {
+    public final void sarq(Register dst) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xD3);
         emitByte(0xF8 | encode);
     }
 
-    public final void shlq(CiRegister dst, int imm8) {
+    public final void shlq(Register dst, int imm8) {
         assert isShiftCount(imm8 >> 1) : "illegal shift count";
         int encode = prefixqAndEncode(dst.encoding);
         if (imm8 == 1) {
@@ -2698,13 +2724,13 @@
         }
     }
 
-    public final void shlq(CiRegister dst) {
+    public final void shlq(Register dst) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xD3);
         emitByte(0xE0 | encode);
     }
 
-    public final void shrq(CiRegister dst, int imm8) {
+    public final void shrq(Register dst, int imm8) {
         assert isShiftCount(imm8 >> 1) : "illegal shift count";
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xC1);
@@ -2712,13 +2738,13 @@
         emitByte(imm8);
     }
 
-    public final void shrq(CiRegister dst) {
+    public final void shrq(Register dst) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xD3);
         emitByte(0xE8 | encode);
     }
 
-    public final void sqrtsd(CiRegister dst, CiAddress src) {
+    public final void sqrtsd(Register dst, Address src) {
         assert dst.isFpu();
 
         emitByte(0xF2);
@@ -2728,7 +2754,7 @@
         emitOperandHelper(dst, src);
     }
 
-    public final void subq(CiAddress dst, int imm32) {
+    public final void subq(Address dst, int imm32) {
         prefixq(dst);
         if (isByte(imm32)) {
             emitByte(0x83);
@@ -2741,29 +2767,29 @@
         }
     }
 
-    public final void subq(CiRegister dst, int imm32) {
+    public final void subq(Register dst, int imm32) {
         prefixqAndEncode(dst.encoding);
         emitArith(0x81, 0xE8, dst, imm32);
     }
 
-    public final void subq(CiAddress dst, CiRegister src) {
+    public final void subq(Address dst, Register src) {
         prefixq(dst, src);
         emitByte(0x29);
         emitOperandHelper(src, dst);
     }
 
-    public final void subq(CiRegister dst, CiAddress src) {
+    public final void subq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x2B);
         emitOperandHelper(dst, src);
     }
 
-    public final void subq(CiRegister dst, CiRegister src) {
+    public final void subq(Register dst, Register src) {
         prefixqAndEncode(dst.encoding, src.encoding);
         emitArith(0x2B, 0xC0, dst, src);
     }
 
-    public final void testq(CiRegister dst, int imm32) {
+    public final void testq(Register dst, int imm32) {
         // not using emitArith because test
         // doesn't support sign-extension of
         // 8bit operands
@@ -2779,41 +2805,41 @@
         emitInt(imm32);
     }
 
-    public final void testq(CiRegister dst, CiRegister src) {
+    public final void testq(Register dst, Register src) {
         prefixqAndEncode(dst.encoding, src.encoding);
         emitArith(0x85, 0xC0, dst, src);
     }
 
-    public final void xaddq(CiAddress dst, CiRegister src) {
+    public final void xaddq(Address dst, Register src) {
         prefixq(dst, src);
         emitByte(0x0F);
         emitByte(0xC1);
         emitOperandHelper(src, dst);
     }
 
-    public final void xchgq(CiRegister dst, CiAddress src) {
+    public final void xchgq(Register dst, Address src) {
         prefixq(src, dst);
         emitByte(0x87);
         emitOperandHelper(dst, src);
     }
 
-    public final void xchgq(CiRegister dst, CiRegister src) {
+    public final void xchgq(Register dst, Register src) {
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x87);
         emitByte(0xc0 | encode);
     }
 
-    public final void xorq(CiRegister dst, int imm32) {
+    public final void xorq(Register dst, int imm32) {
         prefixqAndEncode(dst.encoding);
         emitArith(0x81, 0xF0, dst, imm32);
     }
 
-    public final void xorq(CiRegister dst, CiRegister src) {
+    public final void xorq(Register dst, Register src) {
         prefixqAndEncode(dst.encoding, src.encoding);
         emitArith(0x33, 0xC0, dst, src);
     }
 
-    public final void xorq(CiRegister dst, CiAddress src) {
+    public final void xorq(Register dst, Address src) {
 
         prefixq(src, dst);
         emitByte(0x33);
@@ -2834,7 +2860,7 @@
                 // the code where this idiom is used, in particular the
                 // orderAccess code.
                 lock();
-                addl(new CiAddress(Word, RSP, 0), 0); // Assert the lock# signal here
+                addl(new Address(Word, RSP, 0), 0); // Assert the lock# signal here
             }
         }
     }
@@ -2873,8 +2899,8 @@
         }
     }
 
-    public void nullCheck(CiRegister r) {
-        testl(AMD64.rax, new CiAddress(Word, r.asValue(Word), 0));
+    public void nullCheck(Register r) {
+        testl(AMD64.rax, new Address(Word, r.asValue(Word), 0));
     }
 
     @Override
@@ -2914,7 +2940,7 @@
         emitInt(0);
     }
 
-    public final void call(CiRegister src) {
+    public final void call(Register src) {
         int encode = prefixAndEncode(src.encoding);
         emitByte(0xFF);
         emitByte(0xD0 | encode);
@@ -2938,7 +2964,7 @@
         emitByte(b2 + i);
     }
 
-    public void fld(CiAddress src) {
+    public void fld(Address src) {
         emitByte(0xDD);
         emitOperandHelper(rax, src);
     }
@@ -2962,7 +2988,7 @@
         emitByte(0xF1);
     }
 
-    public void fstp(CiAddress src) {
+    public void fstp(Address src) {
         emitByte(0xDD);
         emitOperandHelper(rbx, src);
     }
@@ -2988,6 +3014,6 @@
 
     @Override
     public void bangStack(int disp) {
-        movq(new CiAddress(target.wordKind, AMD64.RSP, -disp), AMD64.rax);
+        movq(new Address(target.wordKind, AMD64.RSP, -disp), AMD64.rax);
     }
 }
--- a/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64MacroAssembler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.asm/src/com/oracle/max/asm/target/amd64/AMD64MacroAssembler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,39 +22,39 @@
  */
 package com.oracle.max.asm.target.amd64;
 
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 
 /**
  * This class implements commonly used X86 code patterns.
  */
 public class AMD64MacroAssembler extends AMD64Assembler {
 
-    public AMD64MacroAssembler(CiTarget target, RiRegisterConfig registerConfig) {
+    public AMD64MacroAssembler(TargetDescription target, RegisterConfig registerConfig) {
         super(target, registerConfig);
     }
 
-    public void pushptr(CiAddress src) {
+    public void pushptr(Address src) {
         pushq(src);
     }
 
-    public void popptr(CiAddress src) {
+    public void popptr(Address src) {
         popq(src);
     }
 
-    public void xorptr(CiRegister dst, CiRegister src) {
+    public void xorptr(Register dst, Register src) {
         xorq(dst, src);
     }
 
-    public void xorptr(CiRegister dst, CiAddress src) {
+    public void xorptr(Register dst, Address src) {
         xorq(dst, src);
     }
 
     // 64 bit versions
 
 
-    public void decrementq(CiRegister reg, int value) {
+    public void decrementq(Register reg, int value) {
         if (value == Integer.MIN_VALUE) {
             subq(reg, value);
             return;
@@ -73,7 +73,7 @@
         }
     }
 
-    public void incrementq(CiRegister reg, int value) {
+    public void incrementq(Register reg, int value) {
         if (value == Integer.MIN_VALUE) {
             addq(reg, value);
             return;
@@ -93,19 +93,19 @@
     }
 
     // These are mostly for initializing null
-    public void movptr(CiAddress dst, int src) {
+    public void movptr(Address dst, int src) {
         movslq(dst, src);
     }
 
-    public final void cmp32(CiRegister src1, int imm) {
+    public final void cmp32(Register src1, int imm) {
         cmpl(src1, imm);
     }
 
-    public final void cmp32(CiRegister src1, CiAddress src2) {
+    public final void cmp32(Register src1, Address src2) {
         cmpl(src1, src2);
     }
 
-    public void cmpsd2int(CiRegister opr1, CiRegister opr2, CiRegister dst, boolean unorderedIsLess) {
+    public void cmpsd2int(Register opr1, Register opr2, Register dst, boolean unorderedIsLess) {
         assert opr1.isFpu() && opr2.isFpu();
         ucomisd(opr1, opr2);
 
@@ -128,7 +128,7 @@
         bind(l);
     }
 
-    public void cmpss2int(CiRegister opr1, CiRegister opr2, CiRegister dst, boolean unorderedIsLess) {
+    public void cmpss2int(Register opr1, Register opr2, Register dst, boolean unorderedIsLess) {
         assert opr1.isFpu();
         assert opr2.isFpu();
         ucomiss(opr1, opr2);
@@ -152,23 +152,23 @@
         bind(l);
     }
 
-    public void cmpptr(CiRegister src1, CiRegister src2) {
+    public void cmpptr(Register src1, Register src2) {
         cmpq(src1, src2);
     }
 
-    public void cmpptr(CiRegister src1, CiAddress src2) {
+    public void cmpptr(Register src1, Address src2) {
         cmpq(src1, src2);
     }
 
-    public void cmpptr(CiRegister src1, int src2) {
+    public void cmpptr(Register src1, int src2) {
         cmpq(src1, src2);
     }
 
-    public void cmpptr(CiAddress src1, int src2) {
+    public void cmpptr(Address src1, int src2) {
         cmpq(src1, src2);
     }
 
-    public void decrementl(CiRegister reg, int value) {
+    public void decrementl(Register reg, int value) {
         if (value == Integer.MIN_VALUE) {
             subl(reg, value);
             return;
@@ -187,7 +187,7 @@
         }
     }
 
-    public void decrementl(CiAddress dst, int value) {
+    public void decrementl(Address dst, int value) {
         if (value == Integer.MIN_VALUE) {
             subl(dst, value);
             return;
@@ -206,7 +206,7 @@
         }
     }
 
-    public void incrementl(CiRegister reg, int value) {
+    public void incrementl(Register reg, int value) {
         if (value == Integer.MIN_VALUE) {
             addl(reg, value);
             return;
@@ -225,7 +225,7 @@
         }
     }
 
-    public void incrementl(CiAddress dst, int value) {
+    public void incrementl(Address dst, int value) {
         if (value == Integer.MIN_VALUE) {
             addl(dst, value);
             return;
@@ -244,7 +244,7 @@
         }
     }
 
-    public void signExtendByte(CiRegister reg) {
+    public void signExtendByte(Register reg) {
         if (reg.isByte()) {
             movsxb(reg, reg); // movsxb
         } else {
@@ -253,12 +253,12 @@
         }
     }
 
-    public void signExtendShort(CiRegister reg) {
+    public void signExtendShort(Register reg) {
         movsxw(reg, reg); // movsxw
     }
 
     // Support optimal SSE move instructions.
-    public void movflt(CiRegister dst, CiRegister src) {
+    public void movflt(Register dst, Register src) {
         assert dst.isFpu() && src.isFpu();
         if (AsmOptions.UseXmmRegToRegMoveAll) {
             movaps(dst, src);
@@ -267,17 +267,17 @@
         }
     }
 
-    public void movflt(CiRegister dst, CiAddress src) {
+    public void movflt(Register dst, Address src) {
         assert dst.isFpu();
         movss(dst, src);
     }
 
-    public void movflt(CiAddress dst, CiRegister src) {
+    public void movflt(Address dst, Register src) {
         assert src.isFpu();
         movss(dst, src);
     }
 
-    public void movdbl(CiRegister dst, CiRegister src) {
+    public void movdbl(Register dst, Register src) {
         assert dst.isFpu() && src.isFpu();
         if (AsmOptions.UseXmmRegToRegMoveAll) {
             movapd(dst, src);
@@ -286,7 +286,7 @@
         }
     }
 
-    public void movdbl(CiRegister dst, CiAddress src) {
+    public void movdbl(Register dst, Address src) {
         assert dst.isFpu();
         if (AsmOptions.UseXmmLoadAndClearUpper) {
             movsd(dst, src);
@@ -295,7 +295,7 @@
         }
     }
 
-    public void movdbl(CiAddress dst, CiRegister src) {
+    public void movdbl(Address dst, Register src) {
         assert src.isFpu();
         movsd(dst, src);
     }
@@ -304,20 +304,20 @@
      * Non-atomic write of a 64-bit constant to memory. Do not use
      * if the address might be a volatile field!
      */
-    public void movlong(CiAddress dst, long src) {
-        CiAddress high = new CiAddress(dst.kind, dst.base, dst.index, dst.scale, dst.displacement + 4);
+    public void movlong(Address dst, long src) {
+        Address high = new Address(dst.kind, dst.getBase(), dst.getIndex(), dst.getScale(), dst.getDisplacement() + 4);
         movl(dst, (int) (src & 0xFFFFFFFF));
         movl(high, (int) (src >> 32));
     }
 
-    public void xchgptr(CiRegister src1, CiRegister src2) {
+    public void xchgptr(Register src1, Register src2) {
         xchgq(src1, src2);
     }
 
-    public void flog(CiRegister dest, CiRegister value, boolean base10) {
+    public void flog(Register dest, Register value, boolean base10) {
         assert value.spillSlotSize == dest.spillSlotSize;
 
-        CiAddress tmp = new CiAddress(CiKind.Double, AMD64.RSP);
+        Address tmp = new Address(Kind.Double, AMD64.RSP);
         if (base10) {
             fldlg2();
         } else {
@@ -332,22 +332,22 @@
         addq(AMD64.rsp, dest.spillSlotSize);
     }
 
-    public void fsin(CiRegister dest, CiRegister value) {
+    public void fsin(Register dest, Register value) {
         ftrig(dest, value, 's');
     }
 
-    public void fcos(CiRegister dest, CiRegister value) {
+    public void fcos(Register dest, Register value) {
         ftrig(dest, value, 'c');
     }
 
-    public void ftan(CiRegister dest, CiRegister value) {
+    public void ftan(Register dest, Register value) {
         ftrig(dest, value, 't');
     }
 
-    private void ftrig(CiRegister dest, CiRegister value, char op) {
+    private void ftrig(Register dest, Register value, char op) {
         assert value.spillSlotSize == dest.spillSlotSize;
 
-        CiAddress tmp = new CiAddress(CiKind.Double, AMD64.RSP);
+        Address tmp = new Address(Kind.Double, AMD64.RSP);
         subq(AMD64.rsp, value.spillSlotSize);
         movsd(tmp, value);
         fld(tmp);
@@ -368,23 +368,23 @@
 
     /**
      * Emit code to save a given set of callee save registers in the
-     * {@linkplain CiCalleeSaveLayout CSA} within the frame.
+     * {@linkplain CalleeSaveLayout CSA} within the frame.
      * @param csl the description of the CSA
      * @param frameToCSA offset from the frame pointer to the CSA
      */
-    public void save(CiCalleeSaveLayout csl, int frameToCSA) {
-        CiRegisterValue frame = frameRegister.asValue();
-        for (CiRegister r : csl.registers) {
+    public void save(CalleeSaveLayout csl, int frameToCSA) {
+        RegisterValue frame = frameRegister.asValue();
+        for (Register r : csl.registers) {
             int offset = csl.offsetOf(r);
-            movq(new CiAddress(target.wordKind, frame, frameToCSA + offset), r);
+            movq(new Address(target.wordKind, frame, frameToCSA + offset), r);
         }
     }
 
-    public void restore(CiCalleeSaveLayout csl, int frameToCSA) {
-        CiRegisterValue frame = frameRegister.asValue();
-        for (CiRegister r : csl.registers) {
+    public void restore(CalleeSaveLayout csl, int frameToCSA) {
+        RegisterValue frame = frameRegister.asValue();
+        for (Register r : csl.registers) {
             int offset = csl.offsetOf(r);
-            movq(r, new CiAddress(target.wordKind, frame, frameToCSA + offset));
+            movq(r, new Address(target.wordKind, frame, frameToCSA + offset));
         }
     }
 }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAddress.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2010, 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.ci;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-/**
- * Represents an address in target machine memory, specified via some combination of a base register, an index register,
- * a displacement and a scale. Note that the base and index registers may be a variable that will get a register assigned
- * later by the register allocator.
- */
-public final class CiAddress extends CiValue {
-    private static final long serialVersionUID = -1003772042519945089L;
-
-    /**
-     * A sentinel value used as a place holder in an instruction stream for an address that will be patched.
-     */
-    public static final CiAddress Placeholder = new CiAddress(CiKind.Illegal, CiValue.IllegalValue);
-
-    /**
-     * Base register that defines the start of the address computation.
-     * If not present, is denoted by {@link CiValue#IllegalValue}.
-     */
-    public CiValue base;
-
-    /**
-     * Index register, the value of which (possibly scaled by {@link #scale}) is added to {@link #base}.
-     * If not present, is denoted by {@link CiValue#IllegalValue}.
-     */
-    public CiValue index;
-
-    /**
-     * Scaling factor for indexing, dependent on target operand size.
-     */
-    public final Scale scale;
-
-    /**
-     * Optional additive displacement.
-     */
-    public final int displacement;
-
-    /**
-     * Creates a {@code CiAddress} with given base register, no scaling and no displacement.
-     * @param kind the kind of the value being addressed
-     * @param base the base register
-     */
-    public CiAddress(CiKind kind, CiValue base) {
-        this(kind, base, IllegalValue, Scale.Times1, 0);
-    }
-
-    /**
-     * Creates a {@code CiAddress} with given base register, no scaling and a given displacement.
-     * @param kind the kind of the value being addressed
-     * @param base the base register
-     * @param displacement the displacement
-     */
-    public CiAddress(CiKind kind, CiValue base, int displacement) {
-        this(kind, base, IllegalValue, Scale.Times1, displacement);
-    }
-
-    /**
-     * Creates a {@code CiAddress} with given base and index registers, scaling and displacement.
-     * This is the most general constructor..
-     * @param kind the kind of the value being addressed
-     * @param base the base register
-     * @param index the index register
-     * @param scale the scaling factor
-     * @param displacement the displacement
-     */
-    public CiAddress(CiKind kind, CiValue base, CiValue index, Scale scale, int displacement) {
-        super(kind);
-        this.base = base;
-        this.index = index;
-        this.scale = scale;
-        this.displacement = displacement;
-
-        assert !isConstant(base) && !isStackSlot(base);
-        assert !isConstant(index) && !isStackSlot(index);
-    }
-
-    /**
-     * A scaling factor used in complex addressing modes such as those supported by x86 platforms.
-     */
-    public enum Scale {
-        Times1(1, 0),
-        Times2(2, 1),
-        Times4(4, 2),
-        Times8(8, 3);
-
-        private Scale(int value, int log2) {
-            this.value = value;
-            this.log2 = log2;
-        }
-
-        /**
-         * The value (or multiplier) of this scale.
-         */
-        public final int value;
-
-        /**
-         * The {@linkplain #value value} of this scale log 2.
-         */
-        public final int log2;
-
-        public static Scale fromInt(int scale) {
-            switch (scale) {
-                case 1:  return Times1;
-                case 2:  return Times2;
-                case 4:  return Times4;
-                case 8:  return Times8;
-                default: throw new IllegalArgumentException(String.valueOf(scale));
-            }
-        }
-    }
-
-    @Override
-    public String toString() {
-        if (this == Placeholder) {
-            return "[<placeholder>]";
-        }
-
-        StringBuilder s = new StringBuilder();
-        s.append(kind.javaName).append("[");
-        String sep = "";
-        if (isLegal(base)) {
-            s.append(base);
-            sep = " + ";
-        }
-        if (isLegal(index)) {
-            s.append(sep).append(index).append(" * ").append(scale.value);
-            sep = " + ";
-        }
-        if (displacement < 0) {
-            s.append(" - ").append(-displacement);
-        } else if (displacement > 0) {
-            s.append(sep).append(displacement);
-        }
-        s.append("]");
-        return s.toString();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof CiAddress) {
-            CiAddress addr = (CiAddress) obj;
-            return kind == addr.kind && displacement == addr.displacement && base.equals(addr.base) && scale == addr.scale && index.equals(addr.index);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return base.hashCode() ^ index.hashCode() ^ (displacement << 4) ^ (scale.value << 8) ^ (kind.ordinal() << 12);
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiArchitecture.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.CiRegister.*;
-import com.oracle.max.cri.util.*;
-
-
-/**
- * Represents a CPU architecture, including information such as its endianness, CPU
- * registers, word width, etc.
- */
-public abstract class CiArchitecture {
-
-    /**
-     * The endianness of the architecture.
-     */
-    public static enum ByteOrder {
-        LittleEndian,
-        BigEndian
-    }
-
-    /**
-     * The number of bits required in a bit map covering all the registers that may store references.
-     * The bit position of a register in the map is the register's {@linkplain CiRegister#number number}.
-     */
-    public final int registerReferenceMapBitCount;
-
-    /**
-     * Represents the natural size of words (typically registers and pointers) of this architecture, in bytes.
-     */
-    public final int wordSize;
-
-    /**
-     * The name of this architecture (e.g. "AMD64", "SPARCv9").
-     */
-    public final String name;
-
-    /**
-     * Array of all available registers on this architecture. The index of each register in this
-     * array is equal to its {@linkplain CiRegister#number number}.
-     */
-    public final CiRegister[] registers;
-
-    /**
-     * Map of all registers keyed by their {@linkplain CiRegister#name names}.
-     */
-    public final HashMap<String, CiRegister> registersByName;
-
-    /**
-     * The byte ordering can be either little or big endian.
-     */
-    public final ByteOrder byteOrder;
-
-    /**
-     * Mask of the barrier constants defined in {@link MemoryBarriers} denoting the barriers that
-     * are not required to be explicitly inserted under this architecture.
-     */
-    public final int implicitMemoryBarriers;
-
-    /**
-     * Determines the barriers in a given barrier mask that are explicitly required on this architecture.
-     *
-     * @param barriers a mask of the barrier constants defined in {@link MemoryBarriers}
-     * @return the value of {@code barriers} minus the barriers unnecessary on this architecture
-     */
-    public final int requiredBarriers(int barriers) {
-        return barriers & ~implicitMemoryBarriers;
-    }
-
-    /**
-     * Offset in bytes from the beginning of a call instruction to the displacement.
-     */
-    public final int machineCodeCallDisplacementOffset;
-
-    /**
-     * The size of the return address pushed to the stack by a call instruction.
-     * A value of 0 denotes that call linkage uses registers instead (e.g. SPARC).
-     */
-    public final int returnAddressSize;
-
-    private final EnumMap<RegisterFlag, CiRegister[]> registersByTypeAndEncoding;
-
-    /**
-     * Gets the register for a given {@linkplain CiRegister#encoding encoding} and type.
-     *
-     * @param encoding a register value as used in a machine instruction
-     * @param type the type of the register
-     */
-    public CiRegister registerFor(int encoding, RegisterFlag type) {
-        CiRegister[] regs = registersByTypeAndEncoding.get(type);
-        assert encoding >= 0 && encoding < regs.length;
-        CiRegister reg = regs[encoding];
-        assert reg != null;
-        return reg;
-    }
-
-    protected CiArchitecture(String name,
-                    int wordSize,
-                    ByteOrder byteOrder,
-                    CiRegister[] registers,
-                    int implicitMemoryBarriers,
-                    int nativeCallDisplacementOffset,
-                    int registerReferenceMapBitCount,
-                    int returnAddressSize) {
-        this.name = name;
-        this.registers = registers;
-        this.wordSize = wordSize;
-        this.byteOrder = byteOrder;
-        this.implicitMemoryBarriers = implicitMemoryBarriers;
-        this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
-        this.registerReferenceMapBitCount = registerReferenceMapBitCount;
-        this.returnAddressSize = returnAddressSize;
-
-        registersByName = new HashMap<>(registers.length);
-        for (CiRegister register : registers) {
-            registersByName.put(register.name, register);
-            assert registers[register.number] == register;
-        }
-
-        registersByTypeAndEncoding = new EnumMap<>(RegisterFlag.class);
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = CiRegister.categorize(registers);
-        for (RegisterFlag type : RegisterFlag.values()) {
-            CiRegister[] regs = categorizedRegs.get(type);
-            int max = CiRegister.maxRegisterEncoding(regs);
-            CiRegister[] regsByEnc = new CiRegister[max + 1];
-            for (CiRegister reg : regs) {
-                regsByEnc[reg.encoding] = reg;
-            }
-            registersByTypeAndEncoding.put(type, regsByEnc);
-        }
-    }
-
-    /**
-     * Converts this architecture to a string.
-     * @return the string representation of this architecture
-     */
-    @Override
-    public final String toString() {
-        return name.toLowerCase();
-    }
-
-    /**
-     * Checks whether this is a 32-bit architecture.
-     * @return {@code true} if this architecture is 32-bit
-     */
-    public final boolean is32bit() {
-        return wordSize == 4;
-    }
-
-    /**
-     * Checks whether this is a 64-bit architecture.
-     * @return {@code true} if this architecture is 64-bit
-     */
-    public final boolean is64bit() {
-        return wordSize == 8;
-    }
-
-    // The following methods are architecture specific and not dependent on state
-    // stored in this class. They have convenient default implementations.
-
-    /**
-     * Checks whether this architecture's normal arithmetic instructions use a two-operand form
-     * (e.g. x86 which overwrites one operand register with the result when adding).
-     * @return {@code true} if this architecture uses two-operand mode
-     */
-    public boolean twoOperandMode() {
-        return false;
-    }
-
-    // TODO: Why enumerate the concrete subclasses here rather
-    // than use instanceof comparisons in code that cares?
-
-    /**
-     * Checks whether the architecture is x86.
-     * @return {@code true} if the architecture is x86
-     */
-    public boolean isX86() {
-        return false;
-    }
-
-    /**
-     * Checks whether the architecture is SPARC.
-     * @return {@code true} if the architecture is SPARC
-     */
-    public boolean isSPARC() {
-        return false;
-    }
-
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiAssumptions.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2011, 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.ci;
-
-import java.io.*;
-import java.util.*;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * Class for recording optimistic assumptions made during compilation.
- * Recorded assumption can be visited for subsequent processing using
- * an implementation of the {@link CiAssumptionProcessor} interface.
- */
-public final class CiAssumptions implements Serializable, Iterable<CiAssumptions.Assumption> {
-
-    private static final long serialVersionUID = 5152062717588239131L;
-
-    public abstract static class Assumption implements Serializable {
-
-        private static final long serialVersionUID = -1936652569665112915L;
-    }
-
-    /**
-     * An assumption about a unique subtype of a given type.
-     */
-    public static final class ConcreteSubtype extends Assumption {
-
-        private static final long serialVersionUID = -1457173265437676252L;
-
-        /**
-         * Type the assumption is made about.
-         */
-        public final RiResolvedType context;
-
-        /**
-         * Assumed unique concrete sub-type of the context type.
-         */
-        public final RiResolvedType subtype;
-
-        public ConcreteSubtype(RiResolvedType context, RiResolvedType subtype) {
-            this.context = context;
-            this.subtype = subtype;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + context.hashCode();
-            result = prime * result + subtype.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof ConcreteSubtype) {
-                ConcreteSubtype other = (ConcreteSubtype) obj;
-                return other.context == context && other.subtype == subtype;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * An assumption about a unique implementation of a virtual method.
-     */
-    public static final class ConcreteMethod extends Assumption {
-
-        private static final long serialVersionUID = -7636746737947390059L;
-
-        /**
-         * A virtual (or interface) method whose unique implementation for the receiver type
-         * in {@link #context} is {@link #impl}.
-         */
-        public final RiResolvedMethod method;
-
-        /**
-         * A receiver type.
-         */
-        public final RiResolvedType context;
-
-        /**
-         * The unique implementation of {@link #method} for {@link #context}.
-         */
-        public final RiResolvedMethod impl;
-
-        public ConcreteMethod(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl) {
-            this.method = method;
-            this.context = context;
-            this.impl = impl;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + method.hashCode();
-            result = prime * result + context.hashCode();
-            result = prime * result + impl.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof ConcreteMethod) {
-                ConcreteMethod other = (ConcreteMethod) obj;
-                return other.method == method && other.context == context && other.impl == impl;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * An assumption that specified that a method was used during the compilation.
-     */
-    public static final class MethodContents extends Assumption {
-
-        private static final long serialVersionUID = -4821594103928571659L;
-
-        public final RiResolvedMethod method;
-
-        public MethodContents(RiResolvedMethod method) {
-            this.method = method;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + method.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof ConcreteMethod) {
-                ConcreteMethod other = (ConcreteMethod) obj;
-                return other.method == method;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Array with the assumptions. This field is directly accessed from C++ code in the Graal/HotSpot implementation.
-     */
-    private Assumption[] list;
-
-    private int count;
-
-    /**
-     * Returns whether any assumptions have been registered.
-     * @return {@code true} if at least one assumption has been registered, {@code false} otherwise.
-     */
-    public boolean isEmpty() {
-        return count == 0;
-    }
-
-    @Override
-    public Iterator<Assumption> iterator() {
-        return new Iterator<CiAssumptions.Assumption>() {
-            int index;
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-            public Assumption next() {
-                if (index >= count) {
-                    throw new NoSuchElementException();
-                }
-                return list[index++];
-            }
-            public boolean hasNext() {
-                return index < count;
-            }
-        };
-    }
-
-    /**
-     * Records an assumption that the specified type has no finalizable subclasses.
-     *
-     * @param receiverType the type that is assumed to have no finalizable subclasses
-     * @return {@code true} if the assumption was recorded and can be assumed; {@code false} otherwise
-     */
-    @SuppressWarnings("static-method")
-    public boolean recordNoFinalizableSubclassAssumption(RiResolvedType receiverType) {
-        // TODO (thomaswue): Record that assumption correctly.
-        return false;
-    }
-
-    /**
-     * Records that {@code subtype} is the only concrete subtype in the class hierarchy below {@code context}.
-     * @param context the root of the subtree of the class hierarchy that this assumptions is about
-     * @param subtype the one concrete subtype
-     */
-    public void recordConcreteSubtype(RiResolvedType context, RiResolvedType subtype) {
-        record(new ConcreteSubtype(context, subtype));
-    }
-
-    /**
-     * Records that {@code impl} is the only possible concrete target for a virtual call to
-     * {@code method} with a receiver of type {@code context}.
-     *
-     * @param method a method that is the target of a virtual call
-     * @param context the receiver type of a call to {@code method}
-     * @param impl the concrete method that is the only possible target for the virtual call
-     */
-    public void recordConcreteMethod(RiResolvedMethod method, RiResolvedType context, RiResolvedMethod impl) {
-        record(new ConcreteMethod(method, context, impl));
-    }
-
-    /**
-     * Records that {@code method} was used during the compilation.
-     *
-     * @param method a method whose contents were used
-     */
-    public void recordMethodContents(RiResolvedMethod method) {
-        record(new MethodContents(method));
-    }
-
-    private void record(Assumption assumption) {
-        if (list == null) {
-            list = new Assumption[4];
-        } else {
-            for (int i = 0; i < count; ++i) {
-                if (assumption.equals(list[i])) {
-                    return;
-                }
-            }
-        }
-        if (list.length == count) {
-            Assumption[] newList = new Assumption[list.length * 2];
-            for (int i = 0; i < list.length; ++i) {
-                newList[i] = list[i];
-            }
-            list = newList;
-        }
-        list[count] = assumption;
-        count++;
-    }
-
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiBailout.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import java.util.*;
-
-/**
- * {@code CiBailout} is thrown when the compiler refuses to compile a method because of problems with the method.
- * e.g. bytecode wouldn't verify, too big, JSR/ret too complicated, etc. This exception is <i>not</i>
- * meant to indicate problems with the compiler itself.
- */
-public class CiBailout extends RuntimeException {
-
-    public static final long serialVersionUID = 8974598793458772L;
-
-    /**
-     * Create a new {@code CiBailout}.
-     * @param reason a message indicating the reason
-     */
-    public CiBailout(String reason) {
-        super(reason);
-    }
-
-    /**
-     * Create a new {@code CiBailout}.
-     * @param reason a message indicating the reason with a String.format - syntax
-     * @param args parameters to the formatter
-     */
-    public CiBailout(String format, Object... args) {
-        this(String.format(Locale.ENGLISH, format, args));
-    }
-
-    /**
-     * Create a new {@code CiBailout} t due to an internal exception being thrown.
-     * @param reason a message indicating the reason
-     * @param cause the throwable that was the cause of the bailout
-     */
-    public CiBailout(String reason, Throwable cause) {
-        super(reason);
-        initCause(cause);
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiBitMap.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,682 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * Implements a bitmap that stores a single bit for a range of integers (0-n).
- */
-public final class CiBitMap implements Serializable {
-
-    private static final long serialVersionUID = 2471441272241401105L;
-    private static final int ADDRESS_BITS_PER_WORD = 6;
-    private static final int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
-    private static final int BIT_INDEX_MASK = BITS_PER_WORD - 1;
-
-    public static final int DEFAULT_LENGTH = BITS_PER_WORD;
-
-    public static int roundUpLength(int length) {
-        return ((length + (BITS_PER_WORD - 1)) >> ADDRESS_BITS_PER_WORD) << ADDRESS_BITS_PER_WORD;
-    }
-
-    private int size;
-    private long low;
-    private long[] extra;
-
-    /**
-     * Constructs a new bit map with the {@linkplain #DEFAULT_LENGTH default length}.
-     */
-    public CiBitMap() {
-        this(DEFAULT_LENGTH);
-    }
-
-    /**
-     * Constructs a new bit map from a byte array encoded bit map.
-     *
-     * @param bitmap the bit map to convert
-     */
-    public CiBitMap(byte[] bitmap) {
-        this(bitmap, 0, bitmap.length);
-    }
-
-    /**
-     * Constructs a copy of the given bit map.
-     *
-     * @param bitmap the bit map to copy.
-     */
-    public CiBitMap(CiBitMap bitmap) {
-        this.size = bitmap.size;
-        this.low = bitmap.low;
-        if (bitmap.extra != null) {
-            this.extra = Arrays.copyOf(bitmap.extra, bitmap.extra.length);
-        }
-    }
-
-    /**
-     * Constructs a new bit map from a byte array encoded bit map.
-     *
-     * @param arr the byte array containing the bit map to convert
-     * @param off the byte index in {@code arr} at which the bit map starts
-     * @param numberOfBytes the number of bytes worth of bits to copy from {@code arr}
-     */
-    public CiBitMap(byte[] arr, int off, int numberOfBytes) {
-        this(numberOfBytes * 8);
-        int byteIndex = off;
-        int end = off + numberOfBytes;
-        assert end <= arr.length;
-        while (byteIndex < end && (byteIndex - off) < 8) {
-            long bite = (long) arr[byteIndex] & 0xff;
-            low |= bite << ((byteIndex - off) * 8);
-            byteIndex++;
-        }
-        if (byteIndex < end) {
-            assert (byteIndex - off) == 8;
-            int remBytes = end - byteIndex;
-            int remWords = (remBytes + 7) / 8;
-            for (int word = 0; word < remWords; word++) {
-                long w = 0L;
-                for (int i = 0; i < 8 && byteIndex < end; i++) {
-                    long bite = (long) arr[byteIndex] & 0xff;
-                    w |= bite << (i * 8);
-                    byteIndex++;
-                }
-                extra[word] = w;
-            }
-        }
-    }
-
-    /**
-     * Converts a {@code long} to a {@link CiBitMap}.
-     */
-    public static CiBitMap fromLong(long bitmap) {
-        CiBitMap bm = new CiBitMap(64);
-        bm.low = bitmap;
-        return bm;
-    }
-
-    /**
-     * Constructs a new bit map with the specified length.
-     *
-     * @param length the length of the bitmap
-     */
-    public CiBitMap(int length) {
-        assert length >= 0;
-        this.size = length;
-        if (length > BITS_PER_WORD) {
-            extra = new long[length >> ADDRESS_BITS_PER_WORD];
-        }
-    }
-
-    /**
-     * Sets the bit at the specified index.
-     *
-     * @param i the index of the bit to set
-     */
-    public void set(int i) {
-        if (checkIndex(i) < BITS_PER_WORD) {
-            low |= 1L << i;
-        } else {
-            int pos = wordIndex(i);
-            int index = bitInWord(i);
-            extra[pos] |= 1L << index;
-        }
-    }
-
-    /**
-     * Grows this bitmap to a new size, appending necessary zero bits.
-     *
-     * @param newLength the new length of the bitmap
-     */
-    public void grow(int newLength) {
-        if (newLength > size) {
-            // grow this bitmap to the new length
-            int newSize = newLength >> ADDRESS_BITS_PER_WORD;
-            if (newLength > 0) {
-                if (extra == null) {
-                    // extra just needs to be allocated now
-                    extra = new long[newSize];
-                } else {
-                    if (extra.length < newSize) {
-                        // extra needs to be copied
-                        long[] newExtra = new long[newSize];
-                        for (int i = 0; i < extra.length; i++) {
-                            newExtra[i] = extra[i];
-                        }
-                        extra = newExtra;
-                    } else {
-                        // nothing to do, extra is already the right size
-                    }
-                }
-            }
-            size = newLength;
-        }
-    }
-
-    private static int bitInWord(int i) {
-        return i & BIT_INDEX_MASK;
-    }
-
-    private static int wordIndex(int i) {
-        return (i >> ADDRESS_BITS_PER_WORD) - 1;
-    }
-
-    /**
-     * Clears the bit at the specified index.
-     * @param i the index of the bit to clear
-     */
-    public void clear(int i) {
-        if (checkIndex(i) < BITS_PER_WORD) {
-            low &= ~(1L << i);
-        } else {
-            int pos = wordIndex(i);
-            int index = bitInWord(i);
-            extra[pos] &= ~(1L << index);
-        }
-    }
-
-    /**
-     * Sets all the bits in this bitmap.
-     */
-    public void setAll() {
-        low = -1;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] = -1;
-            }
-        }
-    }
-
-    /**
-     * Clears all the bits in this bitmap.
-     */
-    public void clearAll() {
-        low = 0;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] = 0;
-            }
-        }
-    }
-
-    /**
-     * Gets the value of the bit at the specified index.
-     *
-     * @param i the index of the bit to get
-     * @return {@code true} if the bit at the specified position is {@code 1}
-     */
-    public boolean get(int i) {
-        if (checkIndex(i) < BITS_PER_WORD) {
-            return ((low >> i) & 1) != 0;
-        }
-        int pos = wordIndex(i);
-        int index = bitInWord(i);
-        long bits = extra[pos];
-        return ((bits >> index) & 1) != 0;
-    }
-
-    /**
-     * Gets the value of the bit at the specified index, returning {@code false} if the
-     * bitmap does not cover the specified index.
-     *
-     * @param i the index of the bit to get
-     * @return {@code true} if the bit at the specified position is {@code 1}
-     */
-    public boolean getDefault(int i) {
-        if (i < 0 || i >= size) {
-            return false;
-        }
-        if (i < BITS_PER_WORD) {
-            return ((low >> i) & 1) != 0;
-        }
-        int pos = wordIndex(i);
-        int index = bitInWord(i);
-        long bits = extra[pos];
-        return ((bits >> index) & 1) != 0;
-    }
-
-    /**
-     * Performs the union operation on this bitmap with the specified bitmap. That is, all bits set in either of the two
-     * bitmaps will be set in this bitmap following this operation.
-     *
-     * @param other the other bitmap for the union operation
-     */
-    public void setUnion(CiBitMap other) {
-        low |= other.low;
-        if (extra != null && other.extra != null) {
-            for (int i = 0; i < extra.length && i < other.extra.length; i++) {
-                extra[i] |= other.extra[i];
-            }
-        }
-    }
-
-    /**
-     * Performs the union operation on this bitmap with the specified bitmap. That is, a bit is set in this
-     * bitmap if and only if it is set in both this bitmap and the specified bitmap.
-     *
-     * @param other the other bitmap for this operation
-     * @return {@code true} if any bits were cleared as a result of this operation
-     */
-    public boolean setIntersect(CiBitMap other) {
-        boolean same = true;
-        long intx = low & other.low;
-        if (low != intx) {
-            same = false;
-            low = intx;
-        }
-        long[] oxtra = other.extra;
-        if (extra != null && oxtra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                long a = extra[i];
-                if (i < oxtra.length) {
-                    // zero bits out of this map
-                    long ax = a & oxtra[i];
-                    if (a != ax) {
-                        same = false;
-                        extra[i] = ax;
-                    }
-                } else {
-                    // this bitmap is larger than the specified bitmap; zero remaining bits
-                    if (a != 0) {
-                        same = false;
-                        extra[i] = 0;
-                    }
-                }
-            }
-        }
-        return !same;
-    }
-
-    /**
-     * Gets the number of addressable bits in this bitmap.
-     *
-     * @return the size of this bitmap
-     */
-    public int size() {
-        return size;
-    }
-
-    private int checkIndex(int i) {
-        if (i < 0 || i >= size) {
-            throw new IndexOutOfBoundsException();
-        }
-        return i;
-    }
-
-    public void setFrom(CiBitMap other) {
-        assert this.size == other.size : "must have same size";
-
-        low = other.low;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] = other.extra[i];
-            }
-        }
-    }
-
-    public void setDifference(CiBitMap other) {
-        assert this.size == other.size : "must have same size";
-
-        low &= ~other.low;
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                extra[i] &= ~other.extra[i];
-            }
-        }
-    }
-
-    public boolean isSame(CiBitMap other) {
-        if (this.size != other.size || this.low != other.low) {
-            return false;
-        }
-
-        if (extra != null) {
-            for (int i = 0; i < extra.length; i++) {
-                if (extra[i] != other.extra[i]) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns the index of the first set bit that occurs on or after a specified start index.
-     * If no such bit exists then -1 is returned.
-     * <p>
-     * To iterate over the set bits in a {@code BitMap}, use the following loop:
-     *
-     * <pre>
-     * for (int i = bitMap.nextSetBit(0); i &gt;= 0; i = bitMap.nextSetBit(i + 1)) {
-     *     // operate on index i here
-     * }
-     * </pre>
-     *
-     * @param fromIndex the index to start checking from (inclusive)
-     * @return the index of the lowest set bit between {@code [fromIndex .. size())} or -1 if there is no set bit in this range
-     * @throws IndexOutOfBoundsException if the specified index is negative.
-     */
-    public int nextSetBit(int fromIndex) {
-        return nextSetBit(fromIndex, size());
-    }
-
-    /**
-     * Returns the index of the first set bit that occurs on or after a specified start index
-     * and before a specified end index. If no such bit exists then -1 is returned.
-     * <p>
-     * To iterate over the set bits in a {@code BitMap}, use the following loop:
-     *
-     * <pre>
-     * for (int i = bitMap.nextSetBit(0, bitMap.size()); i &gt;= 0; i = bitMap.nextSetBit(i + 1, bitMap.size())) {
-     *     // operate on index i here
-     * }
-     * </pre>
-     *
-     * @param fromIndex the index to start checking from (inclusive)
-     * @param toIndex the index at which to stop checking (exclusive)
-     * @return the index of the lowest set bit between {@code [fromIndex .. toIndex)} or -1 if there is no set bit in this range
-     * @throws IndexOutOfBoundsException if the specified index is negative.
-     */
-    public int nextSetBit(int fromIndex, int toIndex) {
-        assert fromIndex <= size() : "index out of bounds";
-        assert toIndex <= size() : "index out of bounds";
-        assert fromIndex <= toIndex : "fromIndex > toIndex";
-
-        if (fromIndex == toIndex) {
-            return -1;
-        }
-        int fromWordIndex = wordIndex(fromIndex);
-        int toWordIndex = wordIndex(toIndex - 1) + 1;
-        int resultIndex = fromIndex;
-
-        // check bits including and to the left_ of offset's position
-        int pos = bitInWord(resultIndex);
-        long res = map(fromWordIndex) >> pos;
-        if (res != 0) {
-            resultIndex += Long.numberOfTrailingZeros(res);
-            assert resultIndex >= fromIndex && resultIndex < toIndex : "just checking";
-            if (resultIndex < toIndex) {
-                return resultIndex;
-            }
-            return -1;
-        }
-        // skip over all word length 0-bit runs
-        for (fromWordIndex++; fromWordIndex < toWordIndex; fromWordIndex++) {
-            res = map(fromWordIndex);
-            if (res != 0) {
-                // found a 1, return the offset
-                resultIndex = bitIndex(fromWordIndex) + Long.numberOfTrailingZeros(res);
-                assert resultIndex >= fromIndex : "just checking";
-                if (resultIndex < toIndex) {
-                    return resultIndex;
-                }
-                return -1;
-            }
-        }
-        return -1;
-    }
-
-    private static int bitIndex(int index) {
-        return (index + 1) << ADDRESS_BITS_PER_WORD;
-    }
-
-    private long map(int index) {
-        if (index == -1) {
-            return low;
-        }
-        return extra[index];
-    }
-
-    private static boolean allZeros(int start, long[] arr) {
-        for (int i = start; i < arr.length; i++) {
-            if (arr[i] != 0) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Compares this object against the specified object.
-     * The result is {@code true} if and only if {@code obj} is
-     * not {@code null} and is a {@code CiBitMap} object that has
-     * exactly the same set of bits set to {@code true} as this bit
-     * set.
-     *
-     * @param   obj   the object to compare with.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof CiBitMap) {
-            CiBitMap bm = (CiBitMap) obj;
-            if (bm.low == low) {
-                if (bm.extra == null) {
-                    if (extra == null) {
-                        // Common case
-                        return true;
-                    }
-                    return allZeros(0, extra);
-                }
-                if (extra == null) {
-                    return allZeros(0, bm.extra);
-                }
-                // both 'extra' array non null:
-                int i = 0;
-                int length = Math.min(extra.length, bm.extra.length);
-                while (i < length) {
-                    if (extra[i] != bm.extra[i]) {
-                        return false;
-                    }
-                    i++;
-                }
-                if (extra.length > bm.extra.length) {
-                    return allZeros(length, extra);
-                }
-                if (extra.length < bm.extra.length) {
-                    return allZeros(length, bm.extra);
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return (int) low ^ size;
-    }
-
-    /**
-     * Returns a string representation of this bit map
-     * that is the same as the string returned by {@link BitSet#toString()}
-     * for a bit set with the same bits set as this bit map.
-     */
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(size * 2);
-        sb.append('{');
-
-        int bit = nextSetBit(0);
-        if (bit != -1) {
-            sb.append(bit);
-            for (bit = nextSetBit(bit + 1); bit >= 0; bit = nextSetBit(bit + 1)) {
-                sb.append(", ").append(bit);
-            }
-        }
-
-        sb.append('}');
-        return sb.toString();
-    }
-
-    public static int highestOneBitIndex(long value) {
-        int bit = Long.numberOfTrailingZeros(Long.highestOneBit(value));
-        if (bit == 64) {
-            return -1;
-        }
-        return bit;
-    }
-
-    /**
-     * Returns the number of bits set to {@code true} in this bit map.
-     */
-    public int cardinality() {
-        int sum = Long.bitCount(low);
-        if (extra != null) {
-            for (long word : extra) {
-                sum += Long.bitCount(word);
-            }
-        }
-        return sum;
-    }
-
-    /**
-     * Returns the "logical size" of this bit map: the index of
-     * the highest set bit in the bit map plus one. Returns zero
-     * if the bit map contains no set bits.
-     *
-     * @return  the logical size of this bit map
-     */
-    public int length() {
-        if (extra != null) {
-            for (int i = extra.length - 1; i >= 0; i--) {
-                if (extra[i] != 0) {
-                    return (highestOneBitIndex(extra[i]) + ((i + 1) * 64)) + 1;
-                }
-            }
-        }
-        return highestOneBitIndex(low) + 1;
-    }
-
-    /**
-     * Returns a string representation of this bit map with every set bit represented as {@code '1'}
-     * and every unset bit represented as {@code '0'}. The first character in the returned string represents
-     * bit 0 in this bit map.
-     *
-     * @param length the number of bits represented in the returned string. If {@code length < 0 || length > size()},
-     *            then the value of {@link #length()} is used.
-     */
-    public String toBinaryString() {
-        int length = length();
-        if (length == 0) {
-            return "";
-        }
-        StringBuilder sb = new StringBuilder(length);
-        for (int i = 0; i < length; ++i) {
-            sb.append(get(i) ? '1' : '0');
-        }
-        return sb.toString();
-    }
-
-    static final char[] hexDigits = {
-        '0', '1', '2', '3', '4', '5', '6', '7',
-        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-    };
-
-    /**
-     * Returns a string representation of this bit map in hex.
-     */
-    public String toHexString() {
-        if (size == 0) {
-            return "";
-        }
-        int hexSize = CiUtil.align(this.size, 4);
-        StringBuilder sb = new StringBuilder(hexSize / 4);
-        for (int i = 0; i < hexSize; i += 4) {
-            int nibble = get(i) ? 1 : 0;
-            if (get(i + 1)) {
-                nibble |= 2;
-            }
-            if (get(i + 2)) {
-                nibble |= 4;
-            }
-            if (get(i + 3)) {
-                nibble |= 8;
-            }
-
-            sb.append(hexDigits[nibble]);
-        }
-        return sb.toString();
-    }
-
-    public CiBitMap copy() {
-        CiBitMap n = new CiBitMap(BITS_PER_WORD);
-        n.low = low;
-        if (extra != null) {
-            n.extra = Arrays.copyOf(extra, extra.length);
-        }
-        n.size = size;
-        return n;
-    }
-
-    /**
-     * Copies this bit map into a given byte array.
-     *
-     * @param arr the destination
-     * @param off the byte index in {@code arr} at which to start writing
-     * @param numberOfBytes the number of bytes worth of bits to copy from this bit map.
-     *        The number of bits copied is {@code numberOfBytes * 8}. If {@code numberOfBytes}
-     *        is -1, then {@code ((size() + 7) / 8)} is used instead.
-     * @return the number of bytes written to {@code arr}
-     */
-    public int copyTo(byte[] arr, int off, int numberOfBytes) {
-        for (int i = 0; i < numberOfBytes; ++i) {
-            long word = low;
-            int byteInWord;
-            if (i >= 8) {
-                int wordIndex = (i - 8) / 8;
-                word = extra[wordIndex];
-                byteInWord = i & 0x7;
-            } else {
-                byteInWord = i;
-            }
-            assert byteInWord < 8;
-            byte b = (byte) (word >> (byteInWord * 8));
-            arr[off + i] = b;
-        }
-        return numberOfBytes;
-    }
-
-    /**
-     * Converts this bit map to a byte array. The length of the returned
-     * byte array is {@code ((size() + 7) / 8)}.
-     */
-    public byte[] toByteArray() {
-        byte[] arr = new byte[(size + 7) / 8];
-        copyTo(arr, 0, arr.length);
-        return arr;
-    }
-
-    /**
-     * Converts this bit map to a long.
-     *
-     * @throws IllegalArgumentException if {@code (size() > 64)}
-     */
-    public long toLong() {
-        if (size > 64) {
-            throw new IllegalArgumentException("bit map of size " + size + " cannot be converted to long");
-        }
-        return low;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCalleeSaveLayout.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.ci;
-
-import java.util.*;
-
-
-/**
- * The callee save area (CSA) is a contiguous space in a stack frame
- * used to save (and restore) the values of the caller's registers.
- * This class describes the layout of a CSA in terms of its
- * {@linkplain #size size}, {@linkplain #slotSize slot size} and
- * the {@linkplain #registers callee save registers} covered by the CSA.
- */
-public class CiCalleeSaveLayout {
-
-    /**
-     * The size (in bytes) of the CSA.
-     */
-    public final int size;
-
-    /**
-     * The size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA.
-     */
-    public final int slotSize;
-
-    /**
-     * Map from {@linkplain CiRegister#number register numbers} to slot indexes in the CSA.
-     */
-    private final int[] regNumToIndex;
-
-    private final CiRegister[] indexToReg;
-
-    /**
-     * The list of registers {@linkplain #contains(CiRegister) contained} by this CSA.
-     */
-    public final CiRegister[] registers;
-
-    /**
-     * The offset from the frame pointer to the CSA. If this is not known, then this field
-     * will have the value {@link Integer#MAX_VALUE}.
-     */
-    public final int frameOffsetToCSA;
-
-    /**
-     * Creates a CSA layout.
-     *
-     * @param size size (in bytes) of the CSA. If this is {@code -1}, then the CSA size will be computed from {@code registers}.
-     * @param slotSize the size (in bytes) of an {@linkplain #registerAtIndex(int) indexable} slot in the CSA
-     * @param registers the registers that can be saved in the CSA
-     */
-    public CiCalleeSaveLayout(int frameOffsetToCSA, int size, int slotSize, CiRegister... registers) {
-        this.frameOffsetToCSA = frameOffsetToCSA;
-        assert slotSize == 0 || CiUtil.isPowerOf2(slotSize);
-        this.slotSize = slotSize;
-        int maxRegNum = -1;
-        int maxOffset = 0;
-        this.registers = registers;
-        int offset = 0;
-        for (CiRegister reg : registers) {
-            assert offset % slotSize == 0;
-            assert reg.number >= 0;
-            if (reg.number > maxRegNum) {
-                maxRegNum = reg.number;
-            }
-            if (offset > maxOffset) {
-                maxOffset = offset;
-            }
-            offset += reg.spillSlotSize;
-        }
-        if (size == -1) {
-            this.size = offset;
-        } else {
-            assert offset <= size;
-            this.size = size;
-        }
-
-        this.regNumToIndex = new int[maxRegNum + 1];
-        this.indexToReg = offset == 0 ? new CiRegister[0] : new CiRegister[offset / slotSize];
-        Arrays.fill(regNumToIndex, -1);
-        offset = 0;
-        for (CiRegister reg : registers) {
-            int index = offset / slotSize;
-            regNumToIndex[reg.number] = index;
-            indexToReg[index] = reg;
-            offset += reg.spillSlotSize;
-        }
-    }
-
-    /**
-     * Gets the offset of a given register in the CSA.
-     *
-     * @return the offset (in bytes) of {@code reg} in the CSA
-     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
-     */
-    public int offsetOf(int reg) {
-        return indexOf(reg) * slotSize;
-    }
-
-    /**
-     * Gets the index of a given register in the CSA.
-     *
-     * @return the index of {@code reg} in the CSA
-     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
-     */
-    public int indexOf(int reg) {
-        if (!contains(reg)) {
-            throw new IllegalArgumentException(String.valueOf(reg));
-        }
-        return regNumToIndex[reg];
-    }
-
-    /**
-     * Gets the offset of a given register in the CSA.
-     *
-     * @return the offset (in bytes) of {@code reg} in the CSA
-     * @throws IllegalArgumentException if {@code reg} does not have a slot in the CSA
-     */
-    public int offsetOf(CiRegister reg) {
-        return offsetOf(reg.number);
-    }
-
-    /**
-     * Determines if the CSA includes a slot for a given register.
-     *
-     * @param reg the register to test
-     * @return true if the CSA contains a slot for {@code reg}
-     */
-    public boolean contains(int reg) {
-        return reg >= 0 && reg < regNumToIndex.length && regNumToIndex[reg] != -1;
-    }
-
-    /**
-     * Gets the register whose slot in the CSA is at a given index.
-     *
-     * @param index an index of a slot in the CSA
-     * @return the register whose slot in the CSA is at  {@code index} or {@code null} if {@code index} does not denote a
-     *         slot in the CSA aligned with a register
-     */
-    public CiRegister registerAt(int index) {
-        if (index < 0 || index >= indexToReg.length) {
-            return null;
-        }
-        return indexToReg[index];
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder("[");
-        for (CiRegister reg : registers) {
-            if (sb.length() != 1) {
-                sb.append(", ");
-            }
-            sb.append(reg).append("{+").append(offsetOf(reg)).append('}');
-        }
-        return sb.append("] size=").append(size).toString();
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCallingConvention.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ci;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import com.oracle.max.cri.ri.*;
-
-
-/**
- * A calling convention describes the locations in which the arguments for a call are placed.
- */
-public class CiCallingConvention {
-
-    /**
-     * Constants denoting the type of a call for which a calling convention is
-     * {@linkplain RiRegisterConfig#getCallingConvention(Type, CiKind[], CiTarget, boolean) requested}.
-     */
-    public enum Type {
-        /**
-         * A request for the outgoing argument locations at a call site to Java code.
-         */
-        JavaCall(true),
-
-        /**
-         * A request for the incoming argument locations.
-         */
-        JavaCallee(false),
-
-        /**
-         * A request for the outgoing argument locations at a call site to the runtime (which may be Java or native code).
-         */
-        RuntimeCall(true),
-
-        /**
-         * A request for the outgoing argument locations at a call site to
-         * external native code that complies with the platform ABI.
-         */
-        NativeCall(true);
-
-        /**
-         * Determines if this is a request for the outgoing argument locations at a call site.
-         */
-        public final boolean out;
-
-        public static final Type[] VALUES = values();
-
-        private Type(boolean out) {
-            this.out = out;
-        }
-    }
-
-    /**
-     * The amount of stack space (in bytes) required for the stack-based arguments of the call.
-     */
-    public final int stackSize;
-
-    /**
-     * The locations in which the arguments are placed. This array ordered by argument index.
-     */
-    public final CiValue[] locations;
-
-    public CiCallingConvention(CiValue[] locations, int stackSize) {
-        this.locations = locations;
-        this.stackSize = stackSize;
-        assert verify();
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("CallingConvention[");
-        for (CiValue op : locations) {
-            result.append(op.toString()).append(" ");
-        }
-        result.append("]");
-        return result.toString();
-    }
-
-    private boolean verify() {
-        for (int i = 0; i < locations.length; i++) {
-            CiValue location = locations[i];
-            assert isStackSlot(location) || isRegister(location);
-        }
-        return true;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCodePos.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import java.io.*;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * Represents a code position, that is, a chain of inlined methods with bytecode
- * locations, that is communicated from the compiler to the runtime system. A code position
- * can be used by the runtime system to reconstruct a source-level stack trace
- * for exceptions and to create {@linkplain CiFrame frames} for deoptimization.
- */
-public abstract class CiCodePos implements Serializable {
-
-    private static final long serialVersionUID = 8633885274526033515L;
-
-    /**
-     * The position where this position has been called, {@code null} if none.
-     */
-    public final CiCodePos caller;
-
-    /**
-     * The runtime interface method for this position.
-     */
-    public final RiResolvedMethod method;
-
-    /**
-     * The location within the method, as a bytecode index. The constant
-     * {@code -1} may be used to indicate the location is unknown, for example
-     * within code synthesized by the compiler.
-     */
-    public final int bci;
-
-    /**
-     * Constructs a new object representing a given parent/caller, a given method, and a given BCI.
-     *
-     * @param caller the parent position
-     * @param method the method
-     * @param bci a BCI within the method
-     */
-    public CiCodePos(CiCodePos caller, RiResolvedMethod method, int bci) {
-        assert method != null;
-        this.caller = caller;
-        this.method = method;
-        this.bci = bci;
-    }
-
-    /**
-     * Converts this code position to a string representation.
-     * @return a string representation of this code position
-     */
-    @Override
-    public String toString() {
-        return CiUtil.append(new StringBuilder(100), this).toString();
-    }
-
-    /**
-     * Deep equality test.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (obj instanceof CiCodePos) {
-            CiCodePos other = (CiCodePos) obj;
-            if (other.method.equals(method) && other.bci == bci) {
-                if (caller == null) {
-                    return other.caller == null;
-                }
-                return caller.equals(other.caller);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return bci;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCompilationStatistics.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +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.ci;
-
-import java.io.*;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.oracle.max.cri.ri.*;
-
-@SuppressWarnings("unused")
-public final class CiCompilationStatistics {
-
-    private static final long RESOLUTION = 100000000;
-    private static final boolean TIMELINE_ENABLED = System.getProperty("stats.timeline.file") != null;
-    private static final boolean COMPILATIONSTATS_ENABLED = System.getProperty("stats.compilations.file") != null;
-    private static final boolean ENABLED = TIMELINE_ENABLED || COMPILATIONSTATS_ENABLED;
-
-    private static final CiCompilationStatistics DUMMY = new CiCompilationStatistics(null);
-
-    private static ConcurrentLinkedDeque<CiCompilationStatistics> list = new ConcurrentLinkedDeque<>();
-
-    private static final ThreadLocal<Deque<CiCompilationStatistics>> current = new ThreadLocal<Deque<CiCompilationStatistics>>() {
-
-        @Override
-        protected Deque<CiCompilationStatistics> initialValue() {
-            return new ArrayDeque<>();
-        }
-    };
-
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.FIELD)
-    private static @interface AbsoluteTimeValue {
-    }
-
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.FIELD)
-    private static @interface TimeValue {
-    }
-
-    private static long zeroTime = System.nanoTime();
-
-    private final String holder;
-    private final String name;
-    private final String signature;
-    @AbsoluteTimeValue
-    private final long startTime;
-    @TimeValue
-    private long duration;
-    private int startInvCount;
-    private int endInvCount;
-    private int bytecodeCount;
-    private int codeSize;
-    private int deoptCount;
-
-    private CiCompilationStatistics(RiResolvedMethod method) {
-        if (method != null) {
-            holder = CiUtil.format("%H", method);
-            name = method.name();
-            signature = CiUtil.format("%p", method);
-            startTime = System.nanoTime();
-            startInvCount = method.invocationCount();
-            bytecodeCount = method.codeSize();
-        } else {
-            holder = "";
-            name = "";
-            signature = "";
-            startTime = 0;
-        }
-    }
-
-    public void finish(RiResolvedMethod method) {
-        if (ENABLED) {
-            duration = System.nanoTime() - startTime;
-            endInvCount = method.invocationCount();
-            codeSize = method.compiledCodeSize();
-            if (current.get().getLast() != this) {
-                throw new RuntimeException("mismatch in finish()");
-            }
-            current.get().removeLast();
-        }
-    }
-
-    public static CiCompilationStatistics current() {
-        return current.get().isEmpty() ? null : current.get().getLast();
-    }
-
-    public static CiCompilationStatistics create(RiResolvedMethod method) {
-        if (ENABLED) {
-            CiCompilationStatistics stats = new CiCompilationStatistics(method);
-            list.add(stats);
-            current.get().addLast(stats);
-            return stats;
-        } else {
-            return DUMMY;
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    public static void clear(String dumpName) {
-        if (!ENABLED) {
-            return;
-        }
-        try {
-            ConcurrentLinkedDeque<CiCompilationStatistics> snapshot = list;
-            long snapshotZeroTime = zeroTime;
-
-            list = new ConcurrentLinkedDeque<>();
-            zeroTime = System.nanoTime();
-
-            Date now = new Date();
-            String dateString = (now.getYear() + 1900) + "_" + (now.getMonth() + 1) + "_" + now.getDate() + " " + now.getHours() + "_" + now.getMinutes() + "_" + now.getSeconds();
-            try (PrintStream out = new PrintStream("compilations " + dateString + " " + dumpName + ".csv")) {
-                // output the list of all compilations
-
-                Field[] declaredFields = CiCompilationStatistics.class.getDeclaredFields();
-                ArrayList<Field> fields = new ArrayList<>();
-                for (Field field : declaredFields) {
-                    if (!Modifier.isStatic(field.getModifiers())) {
-                        fields.add(field);
-                    }
-                }
-                for (Field field : fields) {
-                    out.print(field.getName() + ";");
-                }
-                out.println();
-                for (CiCompilationStatistics stats : snapshot) {
-                    for (Field field : fields) {
-                        if (field.isAnnotationPresent(AbsoluteTimeValue.class)) {
-                            double value = (field.getLong(stats) - snapshotZeroTime) / 1000000d;
-                            out.print(String.format(Locale.ENGLISH, "%.3f", value) + ";");
-                        } else if (field.isAnnotationPresent(TimeValue.class)) {
-                            double value = field.getLong(stats) / 1000000d;
-                            out.print(String.format(Locale.ENGLISH, "%.3f", value) + ";");
-                        } else {
-                            out.print(field.get(stats) + ";");
-                        }
-                    }
-                    out.println();
-                }
-            }
-
-            String timelineFile = System.getProperty("stats.timeline.file");
-            if (timelineFile == null || timelineFile.isEmpty()) {
-                timelineFile = "timeline " + dateString;
-            }
-            try (FileOutputStream fos = new FileOutputStream(timelineFile + " " + dumpName + ".csv", true); PrintStream out = new PrintStream(fos)) {
-
-                long[] timeSpent = new long[10000];
-                int maxTick = 0;
-                for (CiCompilationStatistics stats : snapshot) {
-                    long start = stats.startTime - snapshotZeroTime;
-                    long duration = stats.duration;
-                    if (start < 0) {
-                        duration -= -start;
-                        start = 0;
-                    }
-
-                    int tick = (int) (start / RESOLUTION);
-                    long timeLeft = RESOLUTION - (start % RESOLUTION);
-
-                    while (tick < timeSpent.length && duration > 0) {
-                        if (tick > maxTick) {
-                            maxTick = tick;
-                        }
-                        timeSpent[tick] += Math.min(timeLeft, duration);
-                        duration -= timeLeft;
-                        tick++;
-                        timeLeft = RESOLUTION;
-                    }
-                }
-                String timelineName = System.getProperty("stats.timeline.name");
-                if (timelineName != null && !timelineName.isEmpty()) {
-                    out.print(timelineName + ";");
-                }
-                for (int i = 0; i <= maxTick; i++) {
-                    out.print((timeSpent[i] * 100 / RESOLUTION) + ";");
-                }
-                out.println();
-            }
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void setDeoptCount(int count) {
-        this.deoptCount = count;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiConstant.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,496 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ci;
-
-/**
- * Represents a constant (boxed) value, such as an integer, floating point number, or object reference,
- * within the compiler and across the compiler/runtime interface. Exports a set of {@code CiConstant}
- * instances that represent frequently used constant values, such as {@link #ZERO}.
- */
-public final class CiConstant extends CiValue {
-    private static final long serialVersionUID = -6355452536852663986L;
-
-    private static final CiConstant[] INT_CONSTANT_CACHE = new CiConstant[100];
-    static {
-        for (int i = 0; i < INT_CONSTANT_CACHE.length; ++i) {
-            INT_CONSTANT_CACHE[i] = new CiConstant(CiKind.Int, i);
-        }
-    }
-
-    public static final CiConstant NULL_OBJECT = new CiConstant(CiKind.Object, null);
-    public static final CiConstant INT_MINUS_1 = new CiConstant(CiKind.Int, -1);
-    public static final CiConstant INT_0 = forInt(0);
-    public static final CiConstant INT_1 = forInt(1);
-    public static final CiConstant INT_2 = forInt(2);
-    public static final CiConstant INT_3 = forInt(3);
-    public static final CiConstant INT_4 = forInt(4);
-    public static final CiConstant INT_5 = forInt(5);
-    public static final CiConstant LONG_0 = new CiConstant(CiKind.Long, 0L);
-    public static final CiConstant LONG_1 = new CiConstant(CiKind.Long, 1L);
-    public static final CiConstant FLOAT_0 = new CiConstant(CiKind.Float, Float.floatToRawIntBits(0.0F));
-    public static final CiConstant FLOAT_1 = new CiConstant(CiKind.Float, Float.floatToRawIntBits(1.0F));
-    public static final CiConstant FLOAT_2 = new CiConstant(CiKind.Float, Float.floatToRawIntBits(2.0F));
-    public static final CiConstant DOUBLE_0 = new CiConstant(CiKind.Double, Double.doubleToRawLongBits(0.0D));
-    public static final CiConstant DOUBLE_1 = new CiConstant(CiKind.Double, Double.doubleToRawLongBits(1.0D));
-    public static final CiConstant TRUE = new CiConstant(CiKind.Boolean, 1L);
-    public static final CiConstant FALSE = new CiConstant(CiKind.Boolean, 0L);
-
-    static {
-        assert NULL_OBJECT.isDefaultValue();
-        assert INT_0.isDefaultValue();
-        assert FLOAT_0.isDefaultValue();
-        assert DOUBLE_0.isDefaultValue();
-        assert FALSE.isDefaultValue();
-
-        // Ensure difference between 0.0f and -0.0f is preserved
-        assert FLOAT_0 != forFloat(-0.0F);
-        assert !forFloat(-0.0F).isDefaultValue();
-
-        // Ensure difference between 0.0d and -0.0d is preserved
-        assert DOUBLE_0 != forDouble(-0.0d);
-        assert !forDouble(-0.0D).isDefaultValue();
-
-        assert NULL_OBJECT.isNull();
-    }
-
-    /**
-     * The boxed object value. This is ignored iff {@code !kind.isObject()}.
-     */
-    private final Object object;
-
-    /**
-     * The boxed primitive value as a {@code long}. This is ignored iff {@code kind.isObject()}.
-     * For {@code float} and {@code double} values, this value is the result of
-     * {@link Float#floatToRawIntBits(float)} and {@link Double#doubleToRawLongBits(double)} respectively.
-     */
-    private final long primitive;
-
-    /**
-     * Create a new constant represented by the specified object reference.
-     *
-     * @param kind the type of this constant
-     * @param object the value of this constant
-     */
-    private CiConstant(CiKind kind, Object object) {
-        super(kind);
-        this.object = object;
-        this.primitive = 0L;
-    }
-
-    /**
-     * Create a new constant represented by the specified primitive.
-     *
-     * @param kind the type of this constant
-     * @param primitive the value of this constant
-     */
-    public CiConstant(CiKind kind, long primitive) {
-        super(kind);
-        this.object = null;
-        this.primitive = primitive;
-    }
-
-    /**
-     * Checks whether this constant is non-null.
-     * @return {@code true} if this constant is a primitive, or an object constant that is not null
-     */
-    public boolean isNonNull() {
-        return !kind.isObject() || object != null;
-    }
-
-    /**
-     * Checks whether this constant is null.
-     * @return {@code true} if this constant is the null constant
-     */
-    public boolean isNull() {
-        return kind.isObject() && object == null;
-    }
-
-    @Override
-    public String toString() {
-        return kind.javaName + "[" + kind.format(boxedValue()) + (kind != CiKind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]";
-    }
-
-    /**
-     * Gets this constant's value as a string.
-     *
-     * @return this constant's value as a string
-     */
-    public String valueString() {
-        if (kind.isPrimitive()) {
-            return boxedValue().toString();
-        } else if (kind.isObject()) {
-            if (object == null) {
-                return "null";
-            } else if (object instanceof String) {
-                return "\"" + object + "\"";
-            } else {
-                return "<object: " + kind.format(object) + ">";
-            }
-        } else if (kind.isJsr()) {
-            return "bci:" + boxedValue().toString();
-        } else {
-            return "???";
-        }
-    }
-
-    /**
-     * Returns the value of this constant as a boxed Java value.
-     * @return the value of this constant
-     */
-    public Object boxedValue() {
-        // Checkstyle: stop
-        switch (kind) {
-            case Byte: return (byte) asInt();
-            case Boolean: return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE;
-            case Short: return (short) asInt();
-            case Char: return (char) asInt();
-            case Jsr: return (int) primitive;
-            case Int: return asInt();
-            case Long: return asLong();
-            case Float: return asFloat();
-            case Double: return asDouble();
-            case Object: return object;
-        }
-        // Checkstyle: resume
-        throw new IllegalArgumentException();
-    }
-
-    private boolean valueEqual(CiConstant other, boolean ignoreKind) {
-        // must have equivalent kinds to be equal
-        if (!ignoreKind && kind != other.kind) {
-            return false;
-        }
-        if (kind.isObject()) {
-            return object == other.object;
-        }
-        return primitive == other.primitive;
-    }
-
-    /**
-     * Converts this constant to a primitive int.
-     * @return the int value of this constant
-     */
-    public int asInt() {
-        if (kind.stackKind().isInt() || kind.isJsr()) {
-            return (int) primitive;
-        }
-        throw new Error("Constant is not int: " + this);
-    }
-
-    /**
-     * Converts this constant to a primitive boolean.
-     * @return the boolean value of this constant
-     */
-    public boolean asBoolean() {
-        if (kind == CiKind.Boolean) {
-            return primitive != 0L;
-        }
-        throw new Error("Constant is not boolean: " + this);
-    }
-
-    /**
-     * Converts this constant to a primitive long.
-     * @return the long value of this constant
-     */
-    public long asLong() {
-        // Checkstyle: stop
-        switch (kind.stackKind()) {
-            case Jsr:
-            case Int:
-            case Long: return primitive;
-            case Float: return (long) asFloat();
-            case Double: return (long) asDouble();
-            default: throw new Error("Constant is not long: " + this);
-        }
-        // Checkstyle: resume
-    }
-
-    /**
-     * Converts this constant to a primitive float.
-     * @return the float value of this constant
-     */
-    public float asFloat() {
-        if (kind.isFloat()) {
-            return Float.intBitsToFloat((int) primitive);
-        }
-        throw new Error("Constant is not float: " + this);
-    }
-
-    /**
-     * Converts this constant to a primitive double.
-     * @return the double value of this constant
-     */
-    public double asDouble() {
-        if (kind.isFloat()) {
-            return Float.intBitsToFloat((int) primitive);
-        }
-        if (kind.isDouble()) {
-            return Double.longBitsToDouble(primitive);
-        }
-        throw new Error("Constant is not double: " + this);
-    }
-
-    /**
-     * Converts this constant to the object reference it represents.
-     * @return the object which this constant represents
-     */
-    public Object asObject() {
-        if (kind.isObject()) {
-            return object;
-        }
-        throw new Error("Constant is not object: " + this);
-    }
-
-    /**
-     * Converts this constant to the jsr reference it represents.
-     * @return the object which this constant represents
-     */
-    public int asJsr() {
-        if (kind.isJsr()) {
-            return (int) primitive;
-        }
-        throw new Error("Constant is not jsr: " + this);
-    }
-
-    /**
-     * Unchecked access to a primitive value.
-     * @return
-     */
-    public long asPrimitive() {
-        if (kind.isObject()) {
-            throw new Error("Constant is not primitive: " + this);
-        }
-        return primitive;
-    }
-
-    /**
-     * Computes the hashcode of this constant.
-     * @return a suitable hashcode for this constant
-     */
-    @Override
-    public int hashCode() {
-        if (kind.isObject()) {
-            return System.identityHashCode(object);
-        }
-        return (int) primitive;
-    }
-
-    /**
-     * Checks whether this constant equals another object. This is only
-     * true if the other object is a constant and has the same value.
-     * @param o the object to compare equality
-     * @return {@code true} if this constant is equivalent to the specified object
-     */
-    @Override
-    public boolean equals(Object o) {
-        return o == this || o instanceof CiConstant && valueEqual((CiConstant) o, false);
-    }
-
-    /**
-     * Checks whether this constant is identical to another constant or has the same value as it.
-     * @param other the constant to compare for equality against this constant
-     * @return {@code true} if this constant is equivalent to {@code other}
-     */
-    public boolean equivalent(CiConstant other) {
-        return other == this || valueEqual(other, false);
-    }
-
-    /**
-     * Checks whether this constant is the default value for its type.
-     * @return {@code true} if the value is the default value for its type; {@code false} otherwise
-     */
-    public boolean isDefaultValue() {
-        // Checkstyle: stop
-        switch (kind.stackKind()) {
-            case Int: return asInt() == 0;
-            case Long: return asLong() == 0;
-            case Float: return this == FLOAT_0;
-            case Double: return this == DOUBLE_0;
-            case Object: return object == null;
-        }
-        // Checkstyle: resume
-        throw new IllegalArgumentException("Cannot det default CiConstant for kind " + kind);
-    }
-
-    /**
-     * Gets the default value for a given kind.
-     *
-     * @return the default value for {@code kind}'s {@linkplain CiKind#stackKind() stack kind}
-     */
-    public static CiConstant defaultValue(CiKind kind) {
-        // Checkstyle: stop
-        switch (kind.stackKind()) {
-            case Int: return INT_0;
-            case Long: return LONG_0;
-            case Float: return FLOAT_0;
-            case Double: return DOUBLE_0;
-            case Object: return NULL_OBJECT;
-        }
-        // Checkstyle: resume
-        throw new IllegalArgumentException("Cannot get default CiConstant for kind " + kind);
-    }
-
-    /**
-     * Creates a boxed double constant.
-     * @param d the double value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forDouble(double d) {
-        if (Double.compare(0.0D, d) == 0) {
-            return DOUBLE_0;
-        }
-        if (Double.compare(d, 1.0D) == 0) {
-            return DOUBLE_1;
-        }
-        return new CiConstant(CiKind.Double, Double.doubleToRawLongBits(d));
-    }
-
-    /**
-     * Creates a boxed float constant.
-     * @param f the float value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forFloat(float f) {
-        if (Float.compare(f, 0.0F) == 0) {
-            return FLOAT_0;
-        }
-        if (Float.compare(f, 1.0F) == 0) {
-            return FLOAT_1;
-        }
-        if (Float.compare(f, 2.0F) == 0) {
-            return FLOAT_2;
-        }
-        return new CiConstant(CiKind.Float, Float.floatToRawIntBits(f));
-    }
-
-    /**
-     * Creates a boxed long constant.
-     * @param i the long value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forLong(long i) {
-        return i == 0 ? LONG_0 : i == 1 ? LONG_1 : new CiConstant(CiKind.Long, i);
-    }
-
-    /**
-     * Creates a boxed integer constant.
-     * @param i the integer value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forInt(int i) {
-        if (i == -1) {
-            return INT_MINUS_1;
-        }
-        if (i >= 0 && i < INT_CONSTANT_CACHE.length) {
-            return INT_CONSTANT_CACHE[i];
-        }
-        return new CiConstant(CiKind.Int, i);
-    }
-
-    /**
-     * Creates a boxed byte constant.
-     * @param i the byte value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forByte(byte i) {
-        return new CiConstant(CiKind.Byte, i);
-    }
-
-    /**
-     * Creates a boxed boolean constant.
-     * @param i the boolean value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forBoolean(boolean i) {
-        return i ? TRUE : FALSE;
-    }
-
-    /**
-     * Creates a boxed char constant.
-     * @param i the char value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forChar(char i) {
-        return new CiConstant(CiKind.Char, i);
-    }
-
-    /**
-     * Creates a boxed short constant.
-     * @param i the short value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forShort(short i) {
-        return new CiConstant(CiKind.Short, i);
-    }
-
-    /**
-     * Creates a boxed address (jsr/ret address) constant.
-     * @param i the address value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forJsr(int i) {
-        return new CiConstant(CiKind.Jsr, i);
-    }
-
-    /**
-     * Creates a boxed object constant.
-     * @param o the object value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static CiConstant forObject(Object o) {
-        if (o == null) {
-            return NULL_OBJECT;
-        }
-        return new CiConstant(CiKind.Object, o);
-    }
-
-    /**
-     * Creates a boxed constant for the given kind from an Object.
-     * The object needs to be of the Java boxed type corresponding to the kind.
-     * @param kind the kind of the constant to create
-     * @param value the Java boxed value: a Byte instance for CiKind Byte, etc.
-     * @return the boxed copy of {@code value}
-     */
-    public static CiConstant forBoxed(CiKind kind, Object value) {
-        switch (kind) {
-            case Byte:
-                return forByte((Byte) value);
-            case Char:
-                return forChar((Character) value);
-            case Short:
-                return forShort((Short) value);
-            case Int:
-                return forInt((Integer) value);
-            case Long:
-                return forLong((Long) value);
-            case Float:
-                return forFloat((Float) value);
-            case Double:
-                return forDouble((Double) value);
-            case Object:
-                return forObject(value);
-            default:
-                throw new RuntimeException("cannot create CiConstant for boxed " + kind + " value");
-        }
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiDebugInfo.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import java.io.*;
-
-/**
- * Represents the debugging information for a particular place in the code,
- * which includes the code position, a reference map, and deoptimization information.
- */
-public class CiDebugInfo implements Serializable {
-
-    /**
-     * 
-     */
-    private static final long serialVersionUID = -6047206624915812516L;
-
-    /**
-     * The code position (including all inlined methods) of this debug info.
-     * If this is a {@link CiFrame} instance, then it is also the deoptimization information for each inlined frame.
-     */
-    public final CiCodePos codePos;
-
-    /**
-     * The reference map for the registers at this point. The reference map is <i>packed</i> in that
-     * for bit {@code k} in byte {@code n}, it refers to the register whose
-     * {@linkplain CiRegister#number number} is {@code (k + n * 8)}.
-     */
-    public final CiBitMap registerRefMap;
-
-    /**
-     * The reference map for the stack frame at this point. A set bit at {@code k} in the map
-     * represents stack slot number {@code k}.
-     */
-    public final CiBitMap frameRefMap;
-
-    /**
-     * Creates a new {@code CiDebugInfo} from the given values.
-     *
-     * @param codePos the {@linkplain CiCodePos code position} or {@linkplain CiFrame frame} info
-     * @param registerRefMap the register map
-     * @param frameRefMap the reference map for {@code frame}, which may be {@code null}
-     */
-    public CiDebugInfo(CiCodePos codePos, CiBitMap registerRefMap, CiBitMap frameRefMap) {
-        this.codePos = codePos;
-        this.registerRefMap = registerRefMap;
-        this.frameRefMap = frameRefMap;
-    }
-
-    /**
-     * @return {@code true} if this debug information has a frame
-     */
-    public boolean hasFrame() {
-        return codePos instanceof CiFrame;
-    }
-
-    /**
-     * @return {@code true} if this debug info has a reference map for the registers
-     */
-    public boolean hasRegisterRefMap() {
-        return registerRefMap != null && registerRefMap.size() > 0;
-    }
-
-    /**
-     * @return {@code true} if this debug info has a reference map for the stack
-     */
-    public boolean hasStackRefMap() {
-        return frameRefMap != null && frameRefMap.size() > 0;
-    }
-
-
-    /**
-     * Gets the deoptimization information for each inlined frame (if available).
-     *
-     * @return {@code null} if no frame de-opt info is {@linkplain #hasDebugFrame available}
-     */
-    public CiFrame frame() {
-        if (hasFrame()) {
-            return (CiFrame) codePos;
-        }
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        return CiUtil.append(new StringBuilder(100), this, null).toString();
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiExceptionHandler.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * An implementation of the {@link RiExceptionHandler} interface.
- */
-public class CiExceptionHandler implements RiExceptionHandler {
-
-    public static final CiExceptionHandler[] NONE = {};
-
-    public final int startBCI;
-    public final int endBCI;
-    public final int handlerBCI;
-    public final int catchTypeCPI;
-    public final RiType catchType;
-
-    /**
-     * Creates a new exception handler with the specified ranges.
-     * @param startBCI the start index of the protected range
-     * @param endBCI the end index of the protected range
-     * @param catchBCI the index of the handler
-     * @param catchTypeCPI the index of the throwable class in the constant pool
-     * @param catchType the type caught by this exception handler
-     */
-    public CiExceptionHandler(int startBCI, int endBCI, int catchBCI, int catchTypeCPI, RiType catchType) {
-        this.startBCI = startBCI;
-        this.endBCI = endBCI;
-        this.handlerBCI = catchBCI;
-        this.catchTypeCPI = catchTypeCPI;
-        this.catchType = catchType;
-    }
-
-    public int startBCI() {
-        return startBCI;
-    }
-
-    public int endBCI() {
-        return endBCI;
-    }
-
-    public int handlerBCI() {
-        return handlerBCI;
-    }
-
-    public int catchTypeCPI() {
-        return catchTypeCPI;
-    }
-
-    public boolean isCatchAll() {
-        return catchTypeCPI == 0;
-    }
-
-    public RiType catchType() {
-        return catchType;
-    }
-
-    @Override
-    public String toString() {
-        return new StringBuilder(20).
-            append('[').
-            append(startBCI).
-            append(" - ").
-            append(endBCI).
-            append(") -> ").
-            append(handlerBCI).
-            append(" type=").
-            append(catchType == null ? "*any*" : catchType.name()).
-            toString();
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiFrame.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ci;
-
-import java.io.*;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * Represents the Java bytecode frame state(s) at a given position
- * including {@link CiValue locations} where to find the local variables,
- * operand stack values and locked objects of the bytecode frame(s).
- */
-public class CiFrame extends CiCodePos implements Serializable {
-    private static final long serialVersionUID = -345025397165977565L;
-
-    /**
-     * An array of values representing how to reconstruct the state of the Java frame.
-     * This is array is partitioned as follows:
-     * <p>
-     * <table border="1" cellpadding="5" frame="void", rules="all">
-     * <tr><th>Start index (inclusive)</th><th>End index (exclusive)</th><th>Description</th></tr>
-     * <tr><td>0</td>                   <td>numLocals</td>           <td>Local variables</td></tr>
-     * <tr><td>numLocals</td>           <td>numLocals + numStack</td><td>Operand stack</td></tr>
-     * <tr><td>numLocals + numStack</td><td>values.length</td>       <td>Locked objects</td></tr>
-     * </table>
-     * <p>
-     * Note that the number of locals and the number of stack slots may be smaller than the
-     * maximum number of locals and stack slots as specified in the compiled method.
-     */
-    public final CiValue[] values;
-
-    /**
-     * The number of locals in the values array.
-     */
-    public final int numLocals;
-
-    /**
-     * The number of stack slots in the values array.
-     */
-    public final int numStack;
-
-    /**
-     * The number of locks in the values array.
-     */
-    public final int numLocks;
-
-    public final long leafGraphId;
-
-    public final boolean rethrowException;
-
-    public final boolean duringCall;
-
-    /**
-     * Creates a new frame object.
-     *
-     * @param caller the caller frame (which may be {@code null})
-     * @param method the method
-     * @param bci a BCI within the method
-     * @param rethrowException specifies if the VM should re-throw the pending exception when deopt'ing using this frame
-     * @param values the frame state {@link #values}
-     * @param numLocals the number of local variables
-     * @param numStack the depth of the stack
-     * @param numLocks the number of locked objects
-     */
-    public CiFrame(CiFrame caller, RiResolvedMethod method, int bci, boolean rethrowException, boolean duringCall, CiValue[] values, int numLocals, int numStack, int numLocks, long leafGraphId) {
-        super(caller, method, bci);
-        assert values != null;
-        this.rethrowException = rethrowException;
-        this.duringCall = duringCall;
-        this.values = values;
-        this.numLocals = numLocals;
-        this.numStack = numStack;
-        this.numLocks = numLocks;
-        this.leafGraphId = leafGraphId;
-        assert !rethrowException || numStack == 1 : "must have exception on top of the stack";
-    }
-
-    /**
-     * Gets the value representing the specified local variable.
-     * @param i the local variable index
-     * @return the value that can be used to reconstruct the local's current value
-     */
-    public CiValue getLocalValue(int i) {
-        return values[i];
-    }
-
-    /**
-     * Gets the value representing the specified stack slot.
-     * @param i the stack index
-     * @return the value that can be used to reconstruct the stack slot's current value
-     */
-    public CiValue getStackValue(int i) {
-        return values[i + numLocals];
-    }
-
-    /**
-     * Gets the value representing the specified lock.
-     * @param i the lock index
-     * @return the value that can be used to reconstruct the lock's current value
-     */
-    public CiValue getLockValue(int i) {
-        return values[i + numLocals + numStack];
-    }
-
-    /**
-     * Gets the caller of this frame.
-     *
-     * @return {@code null} if this frame has no caller
-     */
-    public CiFrame caller() {
-        return (CiFrame) caller;
-    }
-
-    @Override
-    public String toString() {
-        return CiUtil.append(new StringBuilder(100), this).toString();
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiGenericCallback.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2011, 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.ci;
-
-/**
- * This interface is used for {@link CiRuntimeCall#GenericCallback} runtime calls.
- */
-public abstract class CiGenericCallback {
-
-    @SuppressWarnings("unused")
-    private Object callbackInternal(Object arg) {
-        try {
-            return callback(arg);
-        } catch (Throwable t) {
-            t.printStackTrace();
-            return null;
-        }
-    }
-
-    public abstract Object callback(Object arg);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiKind.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,341 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import static com.oracle.max.cri.ci.CiKind.Flags.*;
-import sun.misc.*;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * Denotes the basic kinds of types in CRI, including the all the Java primitive types,
- * for example, {@link CiKind#Int} for {@code int} and {@link CiKind#Object}
- * for all object types.
- * A kind has a single character short name, a Java name, and a set of flags
- * further describing its behavior.
- */
-public enum CiKind {
-    Boolean('z', "boolean", FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
-    Byte   ('b', "byte",    FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
-    Short  ('s', "short",   FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
-    Char   ('c', "char",    FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
-    Int    ('i', "int",     FIELD_TYPE | RETURN_TYPE | PRIMITIVE | STACK_INT),
-    Float  ('f', "float",   FIELD_TYPE | RETURN_TYPE | PRIMITIVE),
-    Long   ('j', "long",    FIELD_TYPE | RETURN_TYPE | PRIMITIVE),
-    Double ('d', "double",  FIELD_TYPE | RETURN_TYPE | PRIMITIVE),
-    Object ('a', "Object",  FIELD_TYPE | RETURN_TYPE),
-    Void   ('v', "void",    RETURN_TYPE),
-    /** Denote a bytecode address in a {@code JSR} bytecode. */
-    Jsr    ('r', "jsr",     0),
-    /** The non-type. */
-    Illegal('-', "illegal", 0);
-
-    public static final CiKind[] VALUES = values();
-    public static final CiKind[] JAVA_VALUES = new CiKind[] {CiKind.Boolean, CiKind.Byte, CiKind.Short, CiKind.Char, CiKind.Int, CiKind.Float, CiKind.Long, CiKind.Double, CiKind.Object};
-
-    CiKind(char ch, String name, int flags) {
-        this.typeChar = ch;
-        this.javaName = name;
-        this.flags = flags;
-    }
-
-    static class Flags {
-        /**
-         * Can be an object field type.
-         */
-        public static final int FIELD_TYPE  = 0x0001;
-        /**
-         * Can be result type of a method.
-         */
-        public static final int RETURN_TYPE = 0x0002;
-        /**
-         * Behaves as an integer when on Java evaluation stack.
-         */
-        public static final int STACK_INT   = 0x0004;
-        /**
-         * Represents a Java primitive type.
-         */
-        public static final int PRIMITIVE   = 0x0008;
-    }
-
-    /**
-     * The flags for this kind.
-     */
-    private final int flags;
-
-    /**
-     * The name of the kind as a single character.
-     */
-    public final char typeChar;
-
-    /**
-     * The name of this kind which will also be it Java programming language name if
-     * it is {@linkplain #isPrimitive() primitive} or {@code void}.
-     */
-    public final String javaName;
-
-    /**
-     * Checks whether this kind is valid as the type of a field.
-     * @return {@code true} if this kind is valid as the type of a Java field
-     */
-    public boolean isValidFieldType() {
-        return (flags & FIELD_TYPE) != 0;
-    }
-
-    /**
-     * Checks whether this kind is valid as the return type of a method.
-     * @return {@code true} if this kind is valid as the return type of a Java method
-     */
-    public boolean isValidReturnType() {
-        return (flags & RETURN_TYPE) != 0;
-    }
-
-    /**
-     * Checks whether this type is valid as an {@code int} on the Java operand stack.
-     * @return {@code true} if this type is represented by an {@code int} on the operand stack
-     */
-    public boolean isInt() {
-        return (flags & STACK_INT) != 0;
-    }
-
-    /**
-     * Checks whether this type is a Java primitive type.
-     * @return {@code true} if this is {@link #Boolean}, {@link #Byte}, {@link #Char}, {@link #Short},
-     *                                 {@link #Int}, {@link #Long}, {@link #Float} or {@link #Double}.
-     */
-    public boolean isPrimitive() {
-        return (flags & PRIMITIVE) != 0;
-    }
-
-    /**
-     * Gets the kind that represents this kind when on the Java operand stack.
-     * @return the kind used on the operand stack
-     */
-    public CiKind stackKind() {
-        if (isInt()) {
-            return Int;
-        }
-        return this;
-    }
-
-    public static CiKind fromTypeString(String typeString) {
-        assert typeString.length() > 0;
-        final char first = typeString.charAt(0);
-        if (first == '[' || first == 'L') {
-            return CiKind.Object;
-        }
-        return CiKind.fromPrimitiveOrVoidTypeChar(first);
-    }
-
-    /**
-     * Gets the kind from the character describing a primitive or void.
-     * @param ch the character
-     * @return the kind
-     */
-    public static CiKind fromPrimitiveOrVoidTypeChar(char ch) {
-        // Checkstyle: stop
-        switch (ch) {
-            case 'Z': return Boolean;
-            case 'C': return Char;
-            case 'F': return Float;
-            case 'D': return Double;
-            case 'B': return Byte;
-            case 'S': return Short;
-            case 'I': return Int;
-            case 'J': return Long;
-            case 'V': return Void;
-        }
-        // Checkstyle: resume
-        throw new IllegalArgumentException("unknown primitive or void type character: " + ch);
-    }
-
-    public Class< ? > toJavaClass() {
-        // Checkstyle: stop
-        switch(this) {
-            case Void:      return java.lang.Void.TYPE;
-            case Long:      return java.lang.Long.TYPE;
-            case Int:       return java.lang.Integer.TYPE;
-            case Byte:      return java.lang.Byte.TYPE;
-            case Char:      return java.lang.Character.TYPE;
-            case Double:    return java.lang.Double.TYPE;
-            case Float:     return java.lang.Float.TYPE;
-            case Short:     return java.lang.Short.TYPE;
-            case Boolean:   return java.lang.Boolean.TYPE;
-            default:        return null;
-        }
-        // Checkstyle: resume
-    }
-
-    public Class< ? > toUnboxedJavaClass() {
-        // Checkstyle: stop
-        switch(this) {
-            case Void:      return null;
-            case Long:      return java.lang.Long.class;
-            case Int:       return java.lang.Integer.class;
-            case Byte:      return java.lang.Byte.class;
-            case Char:      return java.lang.Character.class;
-            case Double:    return java.lang.Double.class;
-            case Float:     return java.lang.Float.class;
-            case Short:     return java.lang.Short.class;
-            case Boolean:   return java.lang.Boolean.class;
-            default:        return null;
-        }
-        // Checkstyle: resume
-    }
-
-    /**
-     * Checks whether this value type is void.
-     * @return {@code true} if this type is void
-     */
-    public final boolean isVoid() {
-        return this == CiKind.Void;
-    }
-
-    /**
-     * Checks whether this value type is long.
-     * @return {@code true} if this type is long
-     */
-    public final boolean isLong() {
-        return this == CiKind.Long;
-    }
-
-    /**
-     * Checks whether this value type is float.
-     * @return {@code true} if this type is float
-     */
-    public final boolean isFloat() {
-        return this == CiKind.Float;
-    }
-
-    /**
-     * Checks whether this value type is double.
-     * @return {@code true} if this type is double
-     */
-    public final boolean isDouble() {
-        return this == CiKind.Double;
-    }
-
-    /**
-     * Checks whether this value type is float or double.
-     * @return {@code true} if this type is float or double
-     */
-    public final boolean isFloatOrDouble() {
-        return this == CiKind.Double || this == CiKind.Float;
-    }
-
-   /**
-     * Checks whether this value type is an object type.
-     * @return {@code true} if this type is an object
-     */
-    public final boolean isObject() {
-        return this == CiKind.Object;
-    }
-
-    /**
-     * Checks whether this value type is an address type.
-     * @return {@code true} if this type is an address
-     */
-    public boolean isJsr() {
-        return this == CiKind.Jsr;
-    }
-
-    /**
-     * Converts this value type to a string.
-     */
-    @Override
-    public String toString() {
-        return javaName;
-    }
-
-    /**
-     * Marker interface for types that should be {@linkplain CiKind#format(Object) formatted}
-     * with their {@link Object#toString()} value.
-     */
-    public interface FormatWithToString {}
-
-    /**
-     * Gets a formatted string for a given value of this kind.
-     *
-     * @param value a value of this kind
-     * @return a formatted string for {@code value} based on this kind
-     */
-    public String format(Object value) {
-        if (isObject()) {
-            if (value == null) {
-                return "null";
-            } else {
-                if (value instanceof String) {
-                    String s = (String) value;
-                    if (s.length() > 50) {
-                        return "\"" + s.substring(0, 30) + "...\"";
-                    } else {
-                        return " \"" + s + '"';
-                    }
-                } else if (value instanceof RiType) {
-                    return "class " + CiUtil.toJavaName((RiType) value);
-                } else if (value instanceof Enum || value instanceof FormatWithToString) {
-                    return String.valueOf(value);
-                } else if (value instanceof Class< ? >) {
-                    return ((Class< ? >) value).getName() + ".class";
-                } else {
-                    return CiUtil.getSimpleName(value.getClass(), true) + "@" + System.identityHashCode(value);
-                }
-            }
-        } else {
-            return value.toString();
-        }
-    }
-
-    public final char signatureChar() {
-        return Character.toUpperCase(typeChar);
-    }
-
-    public CiConstant readUnsafeConstant(Object value, long displacement) {
-        assert value != null;
-        Unsafe u = Unsafe.getUnsafe();
-        switch(this) {
-            case Boolean:
-                return CiConstant.forBoolean(u.getBoolean(value, displacement));
-            case Byte:
-                return CiConstant.forByte(u.getByte(value, displacement));
-            case Char:
-                return CiConstant.forChar(u.getChar(value, displacement));
-            case Short:
-                return CiConstant.forShort(u.getShort(value, displacement));
-            case Int:
-                return CiConstant.forInt(u.getInt(value, displacement));
-            case Long:
-                return CiConstant.forLong(u.getLong(value, displacement));
-            case Float:
-                return CiConstant.forFloat(u.getFloat(value, displacement));
-            case Double:
-                return CiConstant.forDouble(u.getDouble(value, displacement));
-            case Object:
-                return CiConstant.forObject(u.getObject(value, displacement));
-            default:
-                assert false : "unexpected kind: " + this;
-                return null;
-        }
-    }
-
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiMonitorValue.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.cri.ci;
-
-public final class CiMonitorValue extends CiValue {
-    private static final long serialVersionUID = 8241681800464483691L;
-
-    public CiValue owner;
-    public final CiValue lockData;
-    public final boolean eliminated;
-
-    public CiMonitorValue(CiValue owner, CiValue lockData, boolean eliminated) {
-        super(CiKind.Illegal);
-        this.owner = owner;
-        this.lockData = lockData;
-        this.eliminated = eliminated;
-    }
-
-    @Override
-    public String toString() {
-        return "monitor[" + owner + (lockData != null ? ", " + lockData : "") + (eliminated ? ", eliminated" : "") + "]";
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegister.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * Represents a target machine register.
- */
-public final class CiRegister implements Comparable<CiRegister>, Serializable {
-
-    /**
-     * 
-     */
-    private static final long serialVersionUID = -7213269157816016300L;
-
-    /**
-     * Invalid register.
-     */
-    public static final CiRegister None = new CiRegister(-1, -1, 0, "noreg");
-
-    /**
-     * Frame pointer of the current method. All spill slots and outgoing stack-based arguments
-     * are addressed relative to this register.
-     */
-    public static final CiRegister Frame = new CiRegister(-2, -2, 0, "framereg", RegisterFlag.CPU);
-
-    public static final CiRegister CallerFrame = new CiRegister(-3, -3, 0, "callerframereg", RegisterFlag.CPU);
-
-    /**
-     * The identifier for this register that is unique across all the registers in a {@link CiArchitecture}.
-     * A valid register has {@code number > 0}.
-     */
-    public final int number;
-
-    /**
-     * The mnemonic of this register.
-     */
-    public final String name;
-
-    /**
-     * The actual encoding in a target machine instruction for this register, which may or
-     * may not be the same as {@link #number}.
-     */
-    public final int encoding;
-
-    /**
-     * The size of the stack slot used to spill the value of this register.
-     */
-    public final int spillSlotSize;
-
-    /**
-     * The set of {@link RegisterFlag} values associated with this register.
-     */
-    private final int flags;
-
-    /**
-     * An array of {@link CiRegisterValue} objects, for this register, with one entry
-     * per {@link CiKind}, indexed by {@link CiKind#ordinal}.
-     */
-    private final CiRegisterValue[] values;
-
-    /**
-     * Attributes that characterize a register in a useful way.
-     *
-     */
-    public enum RegisterFlag {
-        /**
-         * Denotes an integral (i.e. non floating point) register.
-         */
-        CPU,
-
-        /**
-         * Denotes a register whose lowest order byte can be addressed separately.
-         */
-        Byte,
-
-        /**
-         * Denotes a floating point register.
-         */
-        FPU;
-
-        public final int mask = 1 << (ordinal() + 1);
-    }
-
-    /**
-     * Creates a {@code CiRegister} instance.
-     *
-     * @param number unique identifier for the register
-     * @param encoding the target machine encoding for the register
-     * @param spillSlotSize the size of the stack slot used to spill the value of the register
-     * @param name the mnemonic name for the register
-     * @param flags the set of {@link RegisterFlag} values for the register
-     */
-    public CiRegister(int number, int encoding, int spillSlotSize, String name, RegisterFlag... flags) {
-        this.number = number;
-        this.name = name;
-        this.spillSlotSize = spillSlotSize;
-        this.flags = createMask(flags);
-        this.encoding = encoding;
-
-        values = new CiRegisterValue[CiKind.VALUES.length];
-        for (CiKind kind : CiKind.VALUES) {
-            values[kind.ordinal()] = new CiRegisterValue(kind, this);
-        }
-    }
-
-    private static int createMask(RegisterFlag... flags) {
-        int result = 0;
-        for (RegisterFlag f : flags) {
-            result |= f.mask;
-        }
-        return result;
-    }
-
-    public boolean isSet(RegisterFlag f) {
-        return (flags & f.mask) != 0;
-    }
-
-    /**
-     * Gets this register as a {@linkplain CiRegisterValue value} with a specified kind.
-     * @param kind the specified kind
-     * @return the {@link CiRegisterValue}
-     */
-    public CiRegisterValue asValue(CiKind kind) {
-        return values[kind.ordinal()];
-    }
-
-    /**
-     * Gets this register as a {@linkplain CiRegisterValue value} with no particular kind.
-     * @return a {@link CiRegisterValue} with {@link CiKind#Illegal} kind.
-     */
-    public CiRegisterValue asValue() {
-        return asValue(CiKind.Illegal);
-    }
-
-    /**
-     * Determines if this is a valid register.
-     * @return {@code true} iff this register is valid
-     */
-    public boolean isValid() {
-        return number >= 0;
-    }
-
-    /**
-     * Determines if this a floating point register.
-     */
-    public boolean isFpu() {
-        return isSet(RegisterFlag.FPU);
-    }
-
-    /**
-     * Determines if this a general purpose register.
-     */
-    public boolean isCpu() {
-        return isSet(RegisterFlag.CPU);
-    }
-
-    /**
-     * Determines if this register has the {@link RegisterFlag#Byte} attribute set.
-     * @return {@code true} iff this register has the {@link RegisterFlag#Byte} attribute set.
-     */
-    public boolean isByte() {
-        return isSet(RegisterFlag.Byte);
-    }
-
-    /**
-     * Categorizes a set of registers by {@link RegisterFlag}.
-     *
-     * @param registers a list of registers to be categorized
-     * @return a map from each {@link RegisterFlag} constant to the list of registers for which the flag is
-     *         {@linkplain #isSet(RegisterFlag) set}
-     */
-    public static EnumMap<RegisterFlag, CiRegister[]> categorize(CiRegister[] registers) {
-        EnumMap<RegisterFlag, CiRegister[]> result = new EnumMap<>(RegisterFlag.class);
-        for (RegisterFlag flag : RegisterFlag.values()) {
-            ArrayList<CiRegister> list = new ArrayList<>();
-            for (CiRegister r : registers) {
-                if (r.isSet(flag)) {
-                    list.add(r);
-                }
-            }
-            result.put(flag, list.toArray(new CiRegister[list.size()]));
-        }
-        return result;
-    }
-
-    /**
-     * Gets the maximum register {@linkplain #number number} in a given set of registers.
-     *
-     * @param registers the set of registers to process
-     * @return the maximum register number for any register in {@code registers}
-     */
-    public static int maxRegisterNumber(CiRegister[] registers) {
-        int max = Integer.MIN_VALUE;
-        for (CiRegister r : registers) {
-            if (r.number > max) {
-                max = r.number;
-            }
-        }
-        return max;
-    }
-
-    /**
-     * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
-     *
-     * @param registers the set of registers to process
-     * @return the maximum register encoding for any register in {@code registers}
-     */
-    public static int maxRegisterEncoding(CiRegister[] registers) {
-        int max = Integer.MIN_VALUE;
-        for (CiRegister r : registers) {
-            if (r.encoding > max) {
-                max = r.encoding;
-            }
-        }
-        return max;
-    }
-
-    @Override
-    public String toString() {
-        return name;
-    }
-
-    @Override
-    public int compareTo(CiRegister o) {
-        if (number < o.number) {
-            return -1;
-        }
-        if (number > o.number) {
-            return 1;
-        }
-        return 0;
-    }
-
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegisterConfig.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,298 +0,0 @@
-/*
- * Copyright (c) 2010, 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.ci;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.CiCallingConvention.*;
-import com.oracle.max.cri.ci.CiRegister.*;
-import com.oracle.max.cri.ri.*;
-
-/**
- * A default implementation of {@link RiRegisterConfig}.
- */
-public class CiRegisterConfig implements RiRegisterConfig {
-
-    /**
-     * The object describing the callee save area of this register configuration.
-     */
-    public CiCalleeSaveLayout csl;
-
-    /**
-     * The minimum register role identifier.
-     */
-    public final int minRole;
-
-    /**
-     * The map from register role IDs to registers.
-     */
-    public final CiRegister[] registersRoleMap;
-
-    /**
-     * The set of registers that can be used by the register allocator.
-     */
-    public final CiRegister[] allocatable;
-
-    /**
-     * The set of registers that can be used by the register allocator,
-     * {@linkplain CiRegister#categorize(CiRegister[]) categorized} by register
-     * {@linkplain RegisterFlag flags}.
-     */
-    public final EnumMap<RegisterFlag, CiRegister[]> categorized;
-
-    /**
-     * The ordered set of registers used to pass integral arguments.
-     */
-    public final CiRegister[] cpuParameters;
-
-    /**
-     * The ordered set of registers used to pass floating point arguments.
-     */
-    public final CiRegister[] fpuParameters;
-
-    /**
-     * The caller saved registers.
-     */
-    public final CiRegister[] callerSave;
-
-    /**
-     * The register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
-     */
-    public final CiRegister frame;
-
-    /**
-     * Register for returning an integral value.
-     */
-    public final CiRegister integralReturn;
-
-    /**
-     * Register for returning a floating point value.
-     */
-    public final CiRegister floatingPointReturn;
-
-    /**
-     * The map from register {@linkplain CiRegister#number numbers} to register
-     * {@linkplain RiRegisterAttributes attributes} for this register configuration.
-     */
-    public final RiRegisterAttributes[] attributesMap;
-
-    /**
-     * The scratch register.
-     */
-    public final CiRegister scratch;
-
-    /**
-     * The frame offset of the first stack argument for each calling convention {@link CiCallingConvention.Type}.
-     */
-    public final int[] stackArg0Offsets = new int[CiCallingConvention.Type.VALUES.length];
-
-    public CiRegisterConfig(
-                    CiRegister frame,
-                    CiRegister integralReturn,
-                    CiRegister floatingPointReturn,
-                    CiRegister scratch,
-                    CiRegister[] allocatable,
-                    CiRegister[] callerSave,
-                    CiRegister[] parameters,
-                    CiCalleeSaveLayout csl,
-                    CiRegister[] allRegisters,
-                    Map<Integer, CiRegister> roles) {
-        this.frame = frame;
-        this.csl = csl;
-        this.allocatable = allocatable;
-        this.callerSave = callerSave;
-        assert !Arrays.asList(allocatable).contains(scratch);
-        this.scratch = scratch;
-        EnumMap<RegisterFlag, CiRegister[]> categorizedParameters = CiRegister.categorize(parameters);
-        this.cpuParameters = categorizedParameters.get(RegisterFlag.CPU);
-        this.fpuParameters = categorizedParameters.get(RegisterFlag.FPU);
-        categorized = CiRegister.categorize(allocatable);
-        attributesMap = RiRegisterAttributes.createMap(this, allRegisters);
-        this.floatingPointReturn = floatingPointReturn;
-        this.integralReturn = integralReturn;
-        int minRoleId = Integer.MAX_VALUE;
-        int maxRoleId = Integer.MIN_VALUE;
-        for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
-            int id = e.getKey();
-            assert id >= 0;
-            if (minRoleId > id) {
-                minRoleId = id;
-            }
-            if (maxRoleId < id) {
-                maxRoleId = id;
-            }
-        }
-        registersRoleMap = new CiRegister[(maxRoleId - minRoleId) + 1];
-        for (Map.Entry<Integer, CiRegister> e : roles.entrySet()) {
-            int id = e.getKey();
-            registersRoleMap[id] = e.getValue();
-        }
-        minRole = minRoleId;
-    }
-
-    public CiRegisterConfig(CiRegisterConfig src, CiCalleeSaveLayout csl) {
-        this.frame = src.frame;
-        this.csl = csl;
-        this.allocatable = src.allocatable;
-        this.callerSave = src.callerSave;
-        this.scratch = src.scratch;
-        this.cpuParameters = src.cpuParameters;
-        this.fpuParameters = src.fpuParameters;
-        this.categorized = src.categorized;
-        this.attributesMap = src.attributesMap;
-        this.floatingPointReturn = src.floatingPointReturn;
-        this.integralReturn = src.integralReturn;
-        this.registersRoleMap = src.registersRoleMap;
-        this.minRole = src.minRole;
-        System.arraycopy(src.stackArg0Offsets, 0, stackArg0Offsets, 0, stackArg0Offsets.length);
-    }
-
-    public CiRegister getReturnRegister(CiKind kind) {
-        if (kind.isDouble() || kind.isFloat()) {
-            return floatingPointReturn;
-        }
-        return integralReturn;
-    }
-
-    public CiRegister getFrameRegister() {
-        return frame;
-    }
-
-    public CiRegister getScratchRegister() {
-        return scratch;
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * This implementation assigns all available registers to parameters before assigning
-     * any stack slots to parameters.
-     */
-    public CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly) {
-        CiValue[] locations = new CiValue[parameters.length];
-
-        int currentGeneral = 0;
-        int currentXMM = 0;
-        int currentStackOffset = stackArg0Offsets[type.ordinal()];
-
-        for (int i = 0; i < parameters.length; i++) {
-            final CiKind kind = parameters[i];
-
-            switch (kind) {
-                case Byte:
-                case Boolean:
-                case Short:
-                case Char:
-                case Int:
-                case Long:
-                case Object:
-                    if (!stackOnly && currentGeneral < cpuParameters.length) {
-                        CiRegister register = cpuParameters[currentGeneral++];
-                        locations[i] = register.asValue(kind);
-                    }
-                    break;
-
-                case Float:
-                case Double:
-                    if (!stackOnly && currentXMM < fpuParameters.length) {
-                        CiRegister register = fpuParameters[currentXMM++];
-                        locations[i] = register.asValue(kind);
-                    }
-                    break;
-
-                default:
-                    throw new InternalError("Unexpected parameter kind: " + kind);
-            }
-
-            if (locations[i] == null) {
-                locations[i] = CiStackSlot.get(kind.stackKind(), currentStackOffset, !type.out);
-                currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize);
-            }
-        }
-
-        return new CiCallingConvention(locations, currentStackOffset);
-    }
-
-    public CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
-        if (flag == RegisterFlag.CPU) {
-            return cpuParameters;
-        }
-        assert flag == RegisterFlag.FPU;
-        return fpuParameters;
-    }
-
-    public CiRegister[] getAllocatableRegisters() {
-        return allocatable;
-    }
-
-    public EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters() {
-        return categorized;
-    }
-
-    public CiRegister[] getCallerSaveRegisters() {
-        return callerSave;
-    }
-
-    public CiCalleeSaveLayout getCalleeSaveLayout() {
-        return csl;
-    }
-
-    public RiRegisterAttributes[] getAttributesMap() {
-        return attributesMap;
-    }
-
-    public CiRegister getRegisterForRole(int id) {
-        return registersRoleMap[id - minRole];
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder roleMap = new StringBuilder();
-        for (int i = 0; i < registersRoleMap.length; ++i) {
-            CiRegister reg = registersRoleMap[i];
-            if (reg != null) {
-                if (roleMap.length() != 0) {
-                    roleMap.append(", ");
-                }
-                roleMap.append(i + minRole).append(" -> ").append(reg);
-            }
-        }
-        StringBuilder stackArg0OffsetsMap = new StringBuilder();
-        for (Type t : Type.VALUES) {
-            if (stackArg0OffsetsMap.length() != 0) {
-                stackArg0OffsetsMap.append(", ");
-            }
-            stackArg0OffsetsMap.append(t).append(" -> ").append(stackArg0Offsets[t.ordinal()]);
-        }
-        String res = String.format(
-             "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" +
-             "CallerSave:  " + Arrays.toString(getCallerSaveRegisters()) + "%n" +
-             "CalleeSave:  " + getCalleeSaveLayout() + "%n" +
-             "CPU Params:  " + Arrays.toString(cpuParameters) + "%n" +
-             "FPU Params:  " + Arrays.toString(fpuParameters) + "%n" +
-             "VMRoles:     " + roleMap + "%n" +
-             "stackArg0:   " + stackArg0OffsetsMap + "%n" +
-             "Scratch:     " + getScratchRegister() + "%n");
-        return res;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRegisterValue.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ci;
-
-/**
- * Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance of {@code
- * CiRegisterValue} for each ({@link CiRegister}, {@link CiKind}) pair. Use {@link CiRegister#asValue(CiKind)} to
- * retrieve the canonical {@link CiRegisterValue} instance for a given (register,kind) pair.
- */
-public final class CiRegisterValue extends CiValue {
-    private static final long serialVersionUID = 7999341472196897163L;
-
-    /**
-     * The register.
-     */
-    public final CiRegister reg;
-
-    /**
-     * Should only be called from {@link CiRegister#CiRegister} to ensure canonicalization.
-     */
-    protected CiRegisterValue(CiKind kind, CiRegister register) {
-        super(kind);
-        this.reg = register;
-    }
-
-    @Override
-    public int hashCode() {
-        return (reg.number << 4) ^ kind.ordinal();
-    }
-
-    @Override
-    public String toString() {
-        return reg.name + kindSuffix();
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiRuntimeCall.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import static com.oracle.max.cri.ci.CiKind.*;
-
-/**
- * Enumerates the calls that must be provided by the runtime system. The compiler
- * may generate code that calls the runtime services for unresolved and slow cases of some
- * bytecodes.
- */
-public enum CiRuntimeCall {
-    UnwindException(Void, Object),
-    Deoptimize(Void),
-    RegisterFinalizer(Void, Object),
-    SetDeoptInfo(Void, Object),
-    CreateNullPointerException(Object),
-    CreateOutOfBoundsException(Object, Int),
-    JavaTimeMillis(Long),
-    JavaTimeNanos(Long),
-    Debug(Void),
-    ArithmeticFrem(Float, Float, Float),
-    ArithmeticDrem(Double, Double, Double),
-    ArithmeticCos(Double, Double),
-    ArithmeticTan(Double, Double),
-    ArithmeticSin(Double, Double),
-    GenericCallback(Object, Object, Object);
-
-    public final CiKind resultKind;
-    public final CiKind[] arguments;
-
-    private CiRuntimeCall(CiKind resultKind, CiKind... args) {
-        this.resultKind = resultKind;
-        this.arguments = args;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiStackSlot.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2010, 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.ci;
-
-import static com.oracle.max.cri.ci.CiKind.*;
-
-/**
- * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame
- * or an incoming stack-based argument in a method's {@linkplain #inCallerFrame() caller's frame}.
- */
-public final class CiStackSlot extends CiValue {
-    private static final long serialVersionUID = -7725071921307318433L;
-
-    private final int offset;
-    private final boolean addFrameSize;
-
-    /**
-     * Gets a {@link CiStackSlot} instance representing a stack slot at a given index
-     * holding a value of a given kind.
-     *
-     * @param kind The kind of the value stored in the stack slot.
-     * @param offset The offset of the stack slot (in bytes)
-     * @param inCallerFrame Specifies if the offset is relative to the stack pointer,
-     *        or the beginning of the frame (stack pointer + total frame size).
-     */
-    public static CiStackSlot get(CiKind kind, int offset, boolean addFrameSize) {
-        assert kind.stackKind() == kind;
-        assert addFrameSize || offset >= 0;
-
-        if (offset % CACHE_GRANULARITY == 0) {
-            CiStackSlot[][] cache;
-            int index = offset / CACHE_GRANULARITY;
-            if (!addFrameSize) {
-                cache = OUT_CACHE;
-            } else if (offset >= 0) {
-                cache = IN_CACHE;
-            } else {
-                cache = SPILL_CACHE;
-                index = -index;
-            }
-            CiStackSlot[] slots = cache[kind.ordinal()];
-            if (index < slots.length) {
-                CiStackSlot slot = slots[index];
-                assert slot.kind == kind && slot.offset == offset && slot.addFrameSize == addFrameSize;
-                return slot;
-            }
-        }
-        return new CiStackSlot(kind, offset, addFrameSize);
-    }
-
-    /**
-     * Private constructor to enforce use of {@link #get()} so that a cache can be used.
-     */
-    private CiStackSlot(CiKind kind, int offset, boolean addFrameSize) {
-        super(kind);
-        this.offset = offset;
-        this.addFrameSize = addFrameSize;
-    }
-
-    /**
-     * Gets the offset of this stack slot, relative to the stack pointer.
-     * @return The offset of this slot (in bytes).
-     */
-    public int offset(int totalFrameSize) {
-        assert totalFrameSize > 0 || !addFrameSize;
-        int result = offset + (addFrameSize ? totalFrameSize : 0);
-        assert result >= 0;
-        return result;
-    }
-
-    public boolean inCallerFrame() {
-        return addFrameSize && offset >= 0;
-    }
-
-    public int rawOffset() {
-        return offset;
-    }
-
-    public boolean rawAddFrameSize() {
-        return addFrameSize;
-    }
-
-    @Override
-    public int hashCode() {
-        return kind.ordinal() ^ (offset << 4) ^ (addFrameSize ? 15 : 0);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-        if (o instanceof CiStackSlot) {
-            CiStackSlot l = (CiStackSlot) o;
-            return l.kind == kind && l.offset == offset && l.addFrameSize == addFrameSize;
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        if (!addFrameSize) {
-            return "out:" + offset + kindSuffix();
-        } else if (offset >= 0) {
-            return "in:" + offset + kindSuffix();
-        } else {
-            return "stack:" + (-offset) + kindSuffix();
-        }
-    }
-
-    /**
-     * Gets this stack slot used to pass an argument from the perspective of a caller.
-     */
-    public CiStackSlot asOutArg() {
-        assert offset >= 0;
-        if (addFrameSize) {
-            return get(kind, offset, false);
-        }
-        return this;
-    }
-
-    /**
-     * Gets this stack slot used to pass an argument from the perspective of a callee.
-     */
-    public CiStackSlot asInArg() {
-        assert offset >= 0;
-        if (!addFrameSize) {
-            return get(kind, offset, true);
-        }
-        return this;
-    }
-
-
-    private static final int CACHE_GRANULARITY = 8;
-    private static final int SPILL_CACHE_PER_KIND_SIZE = 100;
-    private static final int PARAM_CACHE_PER_KIND_SIZE = 10;
-
-    private static final CiStackSlot[][] SPILL_CACHE = makeCache(SPILL_CACHE_PER_KIND_SIZE, -1, true);
-    private static final CiStackSlot[][] IN_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, true);
-    private static final CiStackSlot[][] OUT_CACHE = makeCache(PARAM_CACHE_PER_KIND_SIZE, 1, false);
-
-    private static CiStackSlot[][] makeCache(int cachePerKindSize, int sign, boolean addFrameSize) {
-        CiStackSlot[][] cache = new CiStackSlot[CiKind.VALUES.length][];
-        for (CiKind kind : new CiKind[] {Illegal, Int, Long, Float, Double, Object, Jsr}) {
-            CiStackSlot[] slots = new CiStackSlot[cachePerKindSize];
-            for (int i = 0; i < cachePerKindSize; i++) {
-                slots[i] = new CiStackSlot(kind, sign * i * CACHE_GRANULARITY, addFrameSize);
-            }
-            cache[kind.ordinal()] = slots;
-        }
-        return cache;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiTarget.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ci;
-
-
-/**
- * Represents the target machine for a compiler, including the CPU architecture, the size of pointers and references,
- * alignment of stacks, caches, etc.
- */
-public class CiTarget {
-    public final CiArchitecture arch;
-
-    /**
-     * The OS page size.
-     */
-    public final int pageSize;
-
-    /**
-     * Specifies if this is a multi-processor system.
-     */
-    public final boolean isMP;
-
-    /**
-     * Specifies if this target supports encoding objects inline in the machine code.
-     */
-    public final boolean inlineObjects;
-
-    /**
-     * The machine word size on this target.
-     */
-    public final int wordSize;
-
-    /**
-     * The CiKind to be used for representing raw pointers and CPU registers.
-     */
-    public final CiKind wordKind;
-
-    /**
-     * The stack alignment requirement of the platform. For example,
-     * from Appendix D of <a href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures Optimization Reference Manual</a>:
-     * <pre>
-     *     "It is important to ensure that the stack frame is aligned to a
-     *      16-byte boundary upon function entry to keep local __m128 data,
-     *      parameters, and XMM register spill locations aligned throughout
-     *      a function invocation."
-     * </pre>
-     */
-    public final int stackAlignment;
-
-    /**
-     * @see http://docs.sun.com/app/docs/doc/806-0477/6j9r2e2b9?a=view
-     */
-    public final int stackBias;
-
-    /**
-     * The cache alignment.
-     */
-    public final int cacheAlignment;
-
-    /**
-     * Specifies how {@code long} and {@code double} constants are to be stored
-     * in {@linkplain CiFrame frames}. This is useful for VMs such as HotSpot
-     * where convention the interpreter uses is that the second local
-     * holds the first raw word of the native long or double representation.
-     * This is actually reasonable, since locals and stack arrays
-     * grow downwards in all implementations.
-     * If, on some machine, the interpreter's Java locals or stack
-     * were to grow upwards, the embedded doubles would be word-swapped.)
-     */
-    public final boolean debugInfoDoubleWordsInSecondSlot;
-
-    /**
-     * Temporary flag to distinguish between the semantics necessary for HotSpot and Maxine.
-     */
-    // TODO This should go away when XIR goes away, and the logic be part of the VM-specific lowering.
-    public final boolean invokeSnippetAfterArguments;
-
-    public CiTarget(CiArchitecture arch,
-             boolean isMP,
-             int stackAlignment,
-             int pageSize,
-             int cacheAlignment,
-             boolean inlineObjects,
-             boolean debugInfoDoubleWordsInSecondSlot,
-             boolean invokeSnippetAfterArguments) {
-        this.arch = arch;
-        this.pageSize = pageSize;
-        this.isMP = isMP;
-        this.wordSize = arch.wordSize;
-        if (wordSize == 8) {
-            this.wordKind = CiKind.Long;
-        } else {
-            this.wordKind = CiKind.Int;
-        }
-        this.stackAlignment = stackAlignment;
-        this.stackBias = 0; // TODO: configure with param once SPARC port exists
-        this.cacheAlignment = cacheAlignment;
-        this.inlineObjects = inlineObjects;
-        this.debugInfoDoubleWordsInSecondSlot = debugInfoDoubleWordsInSecondSlot;
-        this.invokeSnippetAfterArguments = invokeSnippetAfterArguments;
-    }
-
-    /**
-     * Gets the size in bytes of the specified kind for this target.
-     *
-     * @param kind the kind for which to get the size
-     * @return the size in bytes of {@code kind}
-     */
-    public int sizeInBytes(CiKind kind) {
-        // Checkstyle: stop
-        switch (kind) {
-            case Boolean: return 1;
-            case Byte: return 1;
-            case Char: return 2;
-            case Short: return 2;
-            case Int: return 4;
-            case Long: return 8;
-            case Float: return 4;
-            case Double: return 8;
-            case Object: return wordSize;
-            case Jsr: return 4;
-            default: return 0;
-        }
-        // Checkstyle: resume
-    }
-
-    /**
-     * Aligns the given frame size (without return instruction pointer) to the stack
-     * alignment size and return the aligned size (without return instruction pointer).
-     * @param frameSize the initial frame size to be aligned
-     * @return the aligned frame size
-     */
-    public int alignFrameSize(int frameSize) {
-        int x = frameSize + arch.returnAddressSize + (stackAlignment - 1);
-        return (x / stackAlignment) * stackAlignment - arch.returnAddressSize;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiTargetMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,588 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.ci;
-
-import java.io.*;
-import java.util.*;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * Represents the output from compiling a method, including the compiled machine code, associated data and references,
- * relocation information, deoptimization information, etc. It is the essential component of a {@link CiResult}, which also includes
- * {@linkplain CiStatistics compilation statistics} and {@linkplain CiBailout failure information}.
- */
-public class CiTargetMethod implements Serializable {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = -1319947729753702434L;
-
-    /**
-     * Represents a code position with associated additional information.
-     */
-    public abstract static class Site implements Serializable {
-        /**
-         *
-         */
-        private static final long serialVersionUID = -8214214947651979102L;
-        /**
-         * The position (or offset) of this site with respect to the start of the target method.
-         */
-        public final int pcOffset;
-
-        public Site(int pos) {
-            this.pcOffset = pos;
-        }
-    }
-
-    /**
-     * Represents a safepoint with associated debug info.
-     */
-    public static class Safepoint extends Site implements Comparable<Safepoint> {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 2479806696381720162L;
-        public final CiDebugInfo debugInfo;
-
-        Safepoint(int pcOffset, CiDebugInfo debugInfo) {
-            super(pcOffset);
-            this.debugInfo = debugInfo;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(pcOffset);
-            sb.append("[<safepoint>]");
-            appendDebugInfo(sb, debugInfo);
-            return sb.toString();
-        }
-
-        @Override
-        public int compareTo(Safepoint o) {
-            if (pcOffset < o.pcOffset) {
-                return -1;
-            } else if (pcOffset > o.pcOffset) {
-                return 1;
-            }
-            return 0;
-        }
-    }
-
-    /**
-     * Represents a call in the code.
-     */
-    public static final class Call extends Safepoint {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 1440741241631046954L;
-
-        /**
-         * The target of the call.
-         */
-        public final Object target;
-
-        /**
-         * The size of the call instruction.
-         */
-        public final int size;
-
-        /**
-         * Specifies if this call is direct or indirect. A direct call has an immediate operand encoding
-         * the absolute or relative (to the call itself) address of the target. An indirect call has a
-         * register or memory operand specifying the target address of the call.
-         */
-        public final boolean direct;
-
-        Call(Object target, int pcOffset, int size, boolean direct, CiDebugInfo debugInfo) {
-            super(pcOffset, debugInfo);
-            this.size = size;
-            this.target = target;
-            this.direct = direct;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(pcOffset);
-            sb.append('[');
-            sb.append(target);
-            sb.append(']');
-
-            if (debugInfo != null) {
-                appendDebugInfo(sb, debugInfo);
-            }
-
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Represents a reference to data from the code. The associated data can be any constant.
-     */
-    public static final class DataPatch extends Site {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 5771730331604867476L;
-        public final CiConstant constant;
-        public final int alignment;
-
-        DataPatch(int pcOffset, CiConstant data, int alignment) {
-            super(pcOffset);
-            this.constant = data;
-            this.alignment = alignment;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("%d[<data patch referring to data %s>]", pcOffset, constant);
-        }
-    }
-
-    /**
-     * Provides extra information about instructions or data at specific positions in {@link CiTargetMethod#targetCode()}.
-     * This is optional information that can be used to enhance a disassembly of the code.
-     */
-    public abstract static class CodeAnnotation implements Serializable {
-        /**
-         *
-         */
-        private static final long serialVersionUID = -7903959680749520748L;
-        public final int position;
-
-        public CodeAnnotation(int position) {
-            this.position = position;
-        }
-    }
-
-    /**
-     * A string comment about one or more instructions at a specific position in the code.
-     */
-    public static final class CodeComment extends CodeAnnotation {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 6802287188701961401L;
-        public final String value;
-        public CodeComment(int position, String comment) {
-            super(position);
-            this.value = comment;
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName() + "@" + position + ": " + value;
-        }
-    }
-
-    /**
-     * Labels some inline data in the code.
-     */
-    public static final class InlineData extends CodeAnnotation {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 305997507263827108L;
-        public final int size;
-        public InlineData(int position, int size) {
-            super(position);
-            this.size = size;
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName() + "@" + position + ": size=" + size;
-        }
-    }
-
-    /**
-     * Describes a table of signed offsets embedded in the code. The offsets are relative to the starting
-     * address of the table. This type of table maybe generated when translating a multi-way branch
-     * based on a key value from a dense value set (e.g. the {@code tableswitch} JVM instruction).
-     *
-     * The table is indexed by the contiguous range of integers from {@link #low} to {@link #high} inclusive.
-     */
-    public static final class JumpTable extends CodeAnnotation {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 2222194398353801831L;
-
-        /**
-         * The low value in the key range (inclusive).
-         */
-        public final int low;
-
-        /**
-         * The high value in the key range (inclusive).
-         */
-        public final int high;
-
-        /**
-         * The size (in bytes) of each table entry.
-         */
-        public final int entrySize;
-
-        public JumpTable(int position, int low, int high, int entrySize) {
-            super(position);
-            this.low = low;
-            this.high = high;
-            this.entrySize = entrySize;
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName() + "@" + position + ": [" + low + " .. " + high + "]";
-        }
-    }
-
-    /**
-     * Describes a table of key and offset pairs. The offset in each table entry is relative to the address of
-     * the table. This type of table maybe generated when translating a multi-way branch
-     * based on a key value from a sparse value set (e.g. the {@code lookupswitch} JVM instruction).
-     */
-    public static final class LookupTable extends CodeAnnotation {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 8367952567559116160L;
-
-        /**
-         * The number of entries in the table.
-         */
-        public final int npairs;
-
-        /**
-         * The size (in bytes) of entry's key.
-         */
-        public final int keySize;
-
-        /**
-         * The size (in bytes) of entry's offset value.
-         */
-        public final int offsetSize;
-
-        public LookupTable(int position, int npairs, int keySize, int offsetSize) {
-            super(position);
-            this.npairs = npairs;
-            this.keySize = keySize;
-            this.offsetSize = offsetSize;
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName() + "@" + position + ": [npairs=" + npairs + ", keySize=" + keySize + ", offsetSize=" + offsetSize + "]";
-        }
-    }
-
-    /**
-     * Represents exception handler information for a specific code position. It includes the catch code position as
-     * well as the caught exception type.
-     */
-    public static final class ExceptionHandler extends Site {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 4897339464722665281L;
-        public final int handlerPos;
-
-        ExceptionHandler(int pcOffset, int handlerPos) {
-            super(pcOffset);
-            this.handlerPos = handlerPos;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("%d[<exception edge to %d>]", pcOffset, handlerPos);
-        }
-    }
-
-    public static final class Mark extends Site {
-        /**
-         *
-         */
-        private static final long serialVersionUID = 3612943150662354844L;
-        public final Object id;
-        public final Mark[] references;
-
-        Mark(int pcOffset, Object id, Mark[] references) {
-            super(pcOffset);
-            this.id = id;
-            this.references = references;
-        }
-
-        @Override
-        public String toString() {
-            if (id == null) {
-                return String.format("%d[<mark with %d references>]", pcOffset, references.length);
-            } else if (id instanceof Integer) {
-                return String.format("%d[<mark with %d references and id %s>]", pcOffset, references.length, Integer.toHexString((Integer) id));
-            } else {
-                return String.format("%d[<mark with %d references and id %s>]", pcOffset, references.length, id.toString());
-            }
-        }
-    }
-
-    /**
-     * List of safepoints, sorted by {@link Site#pcOffset}.
-     */
-    public final List<Safepoint> safepoints = new ArrayList<>();
-
-    /**
-     * List of data references.
-     */
-    public final List<DataPatch> dataReferences = new ArrayList<>();
-
-    /**
-     * List of exception handlers.
-     */
-    public final List<ExceptionHandler> exceptionHandlers = new ArrayList<>();
-
-    /**
-     * List of marks.
-     */
-    public final List<Mark> marks = new ArrayList<>();
-
-    private int frameSize = -1;
-    private int customStackAreaOffset = -1;
-    private int registerRestoreEpilogueOffset = -1;
-    /**
-     * The buffer containing the emitted machine code.
-     */
-    private byte[] targetCode;
-
-    /**
-     * The leading number of bytes in {@link #targetCode} containing the emitted machine code.
-     */
-    private int targetCodeSize;
-
-    private ArrayList<CodeAnnotation> annotations;
-
-    private CiAssumptions assumptions;
-
-    /**
-     * Constructs a new target method.
-     */
-    public CiTargetMethod() {
-    }
-
-    public void setAssumptions(CiAssumptions assumptions) {
-        this.assumptions = assumptions;
-    }
-
-    public CiAssumptions assumptions() {
-        return assumptions;
-    }
-
-    /**
-     * Sets the frame size in bytes. Does not include the return address pushed onto the
-     * stack, if any.
-     *
-     * @param size the size of the frame in bytes
-     */
-    public void setFrameSize(int size) {
-        frameSize = size;
-    }
-
-    /**
-     * Sets the machine that has been generated by the compiler.
-     *
-     * @param code the machine code generated
-     * @param size the size of the machine code
-     */
-    public void setTargetCode(byte[] code, int size) {
-        targetCode = code;
-        targetCodeSize = size;
-    }
-
-    /**
-     * Records a reference to the data section in the code section (e.g. to load an integer or floating point constant).
-     *
-     * @param codePos the position in the code where the data reference occurs
-     * @param data the data that is referenced
-     * @param alignment the alignment requirement of the data or 0 if there is no alignment requirement
-     */
-    public void recordDataReference(int codePos, CiConstant data, int alignment) {
-        assert codePos >= 0 && data != null;
-        dataReferences.add(new DataPatch(codePos, data, alignment));
-    }
-
-    /**
-     * Records a call in the code array.
-     *
-     * @param codePos the position of the call in the code array
-     * @param size the size of the call instruction
-     * @param target the {@link RiRuntime#asCallTarget(Object) target} being called
-     * @param debugInfo the debug info for the call
-     * @param direct specifies if this is a {@linkplain Call#direct direct} call
-     */
-    public void recordCall(int codePos, int size, Object target, CiDebugInfo debugInfo, boolean direct) {
-        final Call call = new Call(target, codePos, size, direct, debugInfo);
-        addSafepoint(call);
-    }
-
-    /**
-     * Records an exception handler for this method.
-     *
-     * @param codePos  the position in the code that is covered by the handler
-     * @param handlerPos    the position of the handler
-     * @param throwableType the type of exceptions handled by the handler
-     */
-    public void recordExceptionHandler(int codePos, int handlerPos) {
-        exceptionHandlers.add(new ExceptionHandler(codePos, handlerPos));
-    }
-
-    /**
-     * Records a safepoint in the code array.
-     *
-     * @param codePos the position of the safepoint in the code array
-     * @param debugInfo the debug info for the safepoint
-     */
-    public void recordSafepoint(int codePos, CiDebugInfo debugInfo) {
-        addSafepoint(new Safepoint(codePos, debugInfo));
-    }
-
-    private void addSafepoint(Safepoint safepoint) {
-        // The safepoints list must always be sorted
-        if (!safepoints.isEmpty() && safepoints.get(safepoints.size() - 1).pcOffset >= safepoint.pcOffset) {
-            // This re-sorting should be very rare
-            Collections.sort(safepoints);
-        }
-        safepoints.add(safepoint);
-    }
-
-    /**
-     * Records an instruction mark within this method.
-     *
-     * @param codePos the position in the code that is covered by the handler
-     * @param id the identifier for this mark
-     * @param references an array of other marks that this mark references
-     */
-    public Mark recordMark(int codePos, Object id, Mark[] references) {
-        Mark mark = new Mark(codePos, id, references);
-        marks.add(mark);
-        return mark;
-    }
-
-    /**
-     * Allows a method to specify the offset of the epilogue that restores the callee saved registers. Must be called
-     * iff the method is a callee saved method and stores callee registers on the stack.
-     *
-     * @param registerRestoreEpilogueOffset the offset in the machine code where the epilogue begins
-     */
-    public void setRegisterRestoreEpilogueOffset(int registerRestoreEpilogueOffset) {
-        assert this.registerRestoreEpilogueOffset == -1;
-        this.registerRestoreEpilogueOffset = registerRestoreEpilogueOffset;
-    }
-
-    /**
-     * The frame size of the method in bytes.
-     *
-     * @return the frame size
-     */
-    public int frameSize() {
-        assert frameSize != -1 : "frame size not yet initialized!";
-        return frameSize;
-    }
-
-    /**
-     * @return the code offset of the start of the epilogue that restores all callee saved registers, or -1 if this is
-     *         not a callee saved method
-     */
-    public int registerRestoreEpilogueOffset() {
-        return registerRestoreEpilogueOffset;
-    }
-
-    /**
-     * Offset in bytes for the custom stack area (relative to sp).
-     * @return the offset in bytes
-     */
-    public int customStackAreaOffset() {
-        return customStackAreaOffset;
-    }
-
-    /**
-     * @see #customStackAreaOffset()
-     * @param offset
-     */
-    public void setCustomStackAreaOffset(int offset) {
-        customStackAreaOffset = offset;
-    }
-
-    /**
-     * @return the machine code generated for this method
-     */
-    public byte[] targetCode() {
-        return targetCode;
-    }
-
-    /**
-     * @return the size of the machine code generated for this method
-     */
-    public int targetCodeSize() {
-        return targetCodeSize;
-    }
-
-    /**
-     * @return the code annotations or {@code null} if there are none
-     */
-    public List<CodeAnnotation> annotations() {
-        return annotations;
-    }
-
-    public void addAnnotation(CodeAnnotation annotation) {
-        assert annotation != null;
-        if (annotations == null) {
-            annotations = new ArrayList<>();
-        }
-        annotations.add(annotation);
-    }
-
-    private static void appendDebugInfo(StringBuilder sb, CiDebugInfo info) {
-        if (info != null) {
-            appendRefMap(sb, "stackMap", info.frameRefMap);
-            appendRefMap(sb, "registerMap", info.registerRefMap);
-            CiCodePos codePos = info.codePos;
-            if (codePos != null) {
-                CiUtil.appendLocation(sb.append(" "), codePos.method, codePos.bci);
-                if (info.hasFrame()) {
-                    sb.append(" #locals=").append(info.frame().numLocals).append(" #expr=").append(info.frame().numStack);
-                    if (info.frame().numLocks > 0) {
-                        sb.append(" #locks=").append(info.frame().numLocks);
-                    }
-                }
-            }
-        }
-    }
-
-    private static void appendRefMap(StringBuilder sb, String name, CiBitMap map) {
-        if (map != null) {
-            sb.append(' ').append(name).append('[').append(map.toBinaryString()).append(']');
-        }
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,739 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.ci;
-
-import static java.lang.reflect.Modifier.*;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * Miscellaneous collection of utility methods used in the {@code CRI} project.
- */
-public class CiUtil {
-
-    public static final String NEW_LINE = String.format("%n");
-
-    /**
-     * Gets the annotation of a particular type for a formal parameter of a given method.
-     *
-     * @param annotationClass the Class object corresponding to the annotation type
-     * @param parameterIndex the index of a formal parameter of {@code method}
-     * @param method the method for which a parameter annotation is being requested
-     * @return the annotation of type {@code annotationClass} for the formal parameter present, else null
-     * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal parameter
-     */
-    public static <T extends Annotation> T getParameterAnnotation(Class<T> annotationClass, int parameterIndex, RiResolvedMethod method) {
-        if (parameterIndex >= 0) {
-            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
-            for (Annotation a : parameterAnnotations[parameterIndex]) {
-                if (a.annotationType() == annotationClass) {
-                    return annotationClass.cast(a);
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for anonymous and local
-     * classes.
-     *
-     * @param clazz the class for which the simple name is being requested
-     * @param withEnclosingClass specifies if the returned name should be qualified with the name(s) of the enclosing
-     *            class/classes of {@code clazz} (if any). This option is ignored if {@code clazz} denotes an anonymous
-     *            or local class.
-     * @return the simple name
-     */
-    public static String getSimpleName(Class< ? > clazz, boolean withEnclosingClass) {
-        final String simpleName = clazz.getSimpleName();
-        if (simpleName.length() != 0) {
-            if (withEnclosingClass) {
-                String prefix = "";
-                Class< ? > enclosingClass = clazz;
-                while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) {
-                    prefix = prefix + enclosingClass.getSimpleName() + ".";
-                }
-                return prefix + simpleName;
-            }
-            return simpleName;
-        }
-        // Must be an anonymous or local class
-        final String name = clazz.getName();
-        int index = name.indexOf('$');
-        if (index == -1) {
-            return name;
-        }
-        index = name.lastIndexOf('.', index);
-        if (index == -1) {
-            return name;
-        }
-        return name.substring(index + 1);
-    }
-
-    public static final int K = 1024;
-    public static final int M = 1024 * 1024;
-
-    public static boolean isOdd(int n) {
-        return (n & 1) == 1;
-    }
-
-    public static boolean isEven(int n) {
-        return (n & 1) == 0;
-    }
-
-    /**
-     * Checks whether the specified integer is a power of two.
-     *
-     * @param val the value to check
-     * @return {@code true} if the value is a power of two; {@code false} otherwise
-     */
-    public static boolean isPowerOf2(int val) {
-        return val != 0 && (val & val - 1) == 0;
-    }
-
-    /**
-     * Checks whether the specified long is a power of two.
-     *
-     * @param val the value to check
-     * @return {@code true} if the value is a power of two; {@code false} otherwise
-     */
-    public static boolean isPowerOf2(long val) {
-        return val != 0 && (val & val - 1) == 0;
-    }
-
-    /**
-     * Computes the log (base 2) of the specified integer, rounding down. (E.g {@code log2(8) = 3}, {@code log2(21) = 4}
-     * )
-     *
-     * @param val the value
-     * @return the log base 2 of the value
-     */
-    public static int log2(int val) {
-        assert val > 0 && isPowerOf2(val);
-        return 31 - Integer.numberOfLeadingZeros(val);
-    }
-
-    /**
-     * Computes the log (base 2) of the specified long, rounding down. (E.g {@code log2(8) = 3}, {@code log2(21) = 4})
-     *
-     * @param val the value
-     * @return the log base 2 of the value
-     */
-    public static int log2(long val) {
-        assert val > 0 && isPowerOf2(val);
-        return 63 - Long.numberOfLeadingZeros(val);
-    }
-
-    public static int align(int size, int align) {
-        assert isPowerOf2(align);
-        return (size + align - 1) & ~(align - 1);
-    }
-
-    /**
-     * Gets a word with the nth bit set.
-     *
-     * @param n the nth bit to set
-     * @return an integer value with the nth bit set
-     */
-    public static int nthBit(int n) {
-        return n >= Integer.SIZE ? 0 : 1 << n;
-    }
-
-    /**
-     * Gets a word with the right-most n bits set.
-     *
-     * @param n the number of right most bits to set
-     * @return an integer value with the right-most n bits set
-     */
-    public static int rightNBits(int n) {
-        return nthBit(n) - 1;
-    }
-
-    /**
-     * Converts a given type to its Java programming language name. The following are examples of strings returned by
-     * this method:
-     *
-     * <pre>
-     *     qualified == true:
-     *         java.lang.Object
-     *         int
-     *         boolean[][]
-     *     qualified == false:
-     *         Object
-     *         int
-     *         boolean[][]
-     * </pre>
-     *
-     * @param riType the type to be converted to a Java name
-     * @param qualified specifies if the package prefix of the type should be included in the returned name
-     * @return the Java name corresponding to {@code riType}
-     */
-    public static String toJavaName(RiType riType, boolean qualified) {
-        CiKind kind = riType.kind(false);
-        if (kind.isPrimitive() || kind == CiKind.Void) {
-            return kind.javaName;
-        }
-        return internalNameToJava(riType.name(), qualified);
-    }
-
-    /**
-     * Converts a given type to its Java programming language name. The following are examples of strings returned by
-     * this method:
-     *
-     * <pre>
-     *      java.lang.Object
-     *      int
-     *      boolean[][]
-     * </pre>
-     *
-     * @param riType the type to be converted to a Java name
-     * @return the Java name corresponding to {@code riType}
-     */
-    public static String toJavaName(RiType riType) {
-        return (riType == null) ? null : internalNameToJava(riType.name(), true);
-    }
-
-    public static String internalNameToJava(String name, boolean qualified) {
-        switch (name.charAt(0)) {
-            case 'L': {
-                String result = name.substring(1, name.length() - 1).replace('/', '.');
-                if (!qualified) {
-                    final int lastDot = result.lastIndexOf('.');
-                    if (lastDot != -1) {
-                        result = result.substring(lastDot + 1);
-                    }
-                }
-                return result;
-
-            }
-            case '[':
-                return internalNameToJava(name.substring(1), qualified) + "[]";
-            default:
-                if (name.length() != 1) {
-                    throw new IllegalArgumentException("Illegal internal name: " + name);
-                }
-                return CiKind.fromPrimitiveOrVoidTypeChar(name.charAt(0)).javaName;
-        }
-    }
-
-    /**
-     * Gets a string for a given method formatted according to a given format specification. A format specification is
-     * composed of characters that are to be copied verbatim to the result and specifiers that denote an attribute of
-     * the method that is to be copied to the result. A specifier is a single character preceded by a '%' character. The
-     * accepted specifiers and the method attributes they denote are described below:
-     *
-     * <pre>
-     *     Specifier | Description                                          | Example(s)
-     *     ----------+------------------------------------------------------------------------------------------
-     *     'R'       | Qualified return type                                | "int" "java.lang.String"
-     *     'r'       | Unqualified return type                              | "int" "String"
-     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
-     *     'h'       | Unqualified holder                                   | "Entry"
-     *     'n'       | Method name                                          | "add"
-     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
-     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
-     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
-     *     '%'       | A '%' character                                      | "%"
-     * </pre>
-     *
-     * @param format a format specification
-     * @param method the method to be formatted
-     * @param kinds if {@code true} then the types in {@code method}'s signature are printed in the
-     *            {@linkplain CiKind#jniName JNI} form of their {@linkplain CiKind kind}
-     * @return the result of formatting this method according to {@code format}
-     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
-     */
-    public static String format(String format, RiMethod method) throws IllegalFormatException {
-        final StringBuilder sb = new StringBuilder();
-        int index = 0;
-        RiSignature sig = null;
-        while (index < format.length()) {
-            final char ch = format.charAt(index++);
-            if (ch == '%') {
-                if (index >= format.length()) {
-                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification");
-                }
-                final char specifier = format.charAt(index++);
-                boolean qualified = false;
-                switch (specifier) {
-                    case 'R':
-                        qualified = true;
-                        // fall through
-                    case 'r': {
-                        if (sig == null) {
-                            sig = method.signature();
-                        }
-                        sb.append(toJavaName(sig.returnType(null), qualified));
-                        break;
-                    }
-                    case 'H':
-                        qualified = true;
-                        // fall through
-                    case 'h': {
-                        sb.append(toJavaName(method.holder(), qualified));
-                        break;
-                    }
-                    case 'n': {
-                        sb.append(method.name());
-                        break;
-                    }
-                    case 'P':
-                        qualified = true;
-                        // fall through
-                    case 'p': {
-                        if (sig == null) {
-                            sig = method.signature();
-                        }
-                        for (int i = 0; i < sig.argumentCount(false); i++) {
-                            if (i != 0) {
-                                sb.append(", ");
-                            }
-                            sb.append(toJavaName(sig.argumentTypeAt(i, null), qualified));
-                        }
-                        break;
-                    }
-                    case 'f': {
-                        sb.append(!(method instanceof RiResolvedMethod) ? "unresolved" : isStatic(((RiResolvedMethod) method).accessFlags()) ? "static" : "virtual");
-                        break;
-                    }
-                    case '%': {
-                        sb.append('%');
-                        break;
-                    }
-                    default: {
-                        throw new UnknownFormatConversionException(String.valueOf(specifier));
-                    }
-                }
-            } else {
-                sb.append(ch);
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Gets a string for a given field formatted according to a given format specification. A format specification is
-     * composed of characters that are to be copied verbatim to the result and specifiers that denote an attribute of
-     * the field that is to be copied to the result. A specifier is a single character preceded by a '%' character. The
-     * accepted specifiers and the field attributes they denote are described below:
-     *
-     * <pre>
-     *     Specifier | Description                                          | Example(s)
-     *     ----------+------------------------------------------------------------------------------------------
-     *     'T'       | Qualified type                                       | "int" "java.lang.String"
-     *     't'       | Unqualified type                                     | "int" "String"
-     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
-     *     'h'       | Unqualified holder                                   | "Entry"
-     *     'n'       | Field name                                           | "age"
-     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
-     *     '%'       | A '%' character                                      | "%"
-     * </pre>
-     *
-     * @param format a format specification
-     * @param field the field to be formatted
-     * @param kinds if {@code true} then {@code field}'s type is printed in the {@linkplain CiKind#jniName JNI} form of
-     *            its {@linkplain CiKind kind}
-     * @return the result of formatting this field according to {@code format}
-     * @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
-     */
-    public static String format(String format, RiField field) throws IllegalFormatException {
-        final StringBuilder sb = new StringBuilder();
-        int index = 0;
-        RiType type = field.type();
-        while (index < format.length()) {
-            final char ch = format.charAt(index++);
-            if (ch == '%') {
-                if (index >= format.length()) {
-                    throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification");
-                }
-                final char specifier = format.charAt(index++);
-                boolean qualified = false;
-                switch (specifier) {
-                    case 'T':
-                        qualified = true;
-                        // fall through
-                    case 't': {
-                        sb.append(toJavaName(type, qualified));
-                        break;
-                    }
-                    case 'H':
-                        qualified = true;
-                        // fall through
-                    case 'h': {
-                        sb.append(toJavaName(field.holder(), qualified));
-                        break;
-                    }
-                    case 'n': {
-                        sb.append(field.name());
-                        break;
-                    }
-                    case 'f': {
-                        sb.append(!(field instanceof RiResolvedField) ? "unresolved" : isStatic(((RiResolvedField) field).accessFlags()) ? "static" : "instance");
-                        break;
-                    }
-                    case '%': {
-                        sb.append('%');
-                        break;
-                    }
-                    default: {
-                        throw new UnknownFormatConversionException(String.valueOf(specifier));
-                    }
-                }
-            } else {
-                sb.append(ch);
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Converts a Java source-language class name into the internal form.
-     *
-     * @param className the class name
-     * @return the internal name form of the class name
-     */
-    public static String toInternalName(String className) {
-        return "L" + className.replace('.', '/') + ";";
-    }
-
-    /**
-     * Creates a set that uses reference-equality instead of {@link Object#equals(Object)} when comparing values.
-     *
-     * @param <T> the type of elements in the set
-     * @return a set based on reference-equality
-     */
-    public static <T> Set<T> newIdentityHashSet() {
-        return Collections.newSetFromMap(new IdentityHashMap<T, Boolean>());
-    }
-
-    /**
-     * Prepends the String {@code indentation} to every line in String {@code lines}, including a possibly non-empty
-     * line following the final newline.
-     */
-    public static String indent(String lines, String indentation) {
-        if (lines.length() == 0) {
-            return lines;
-        }
-        final String newLine = "\n";
-        if (lines.endsWith(newLine)) {
-            return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
-        }
-        return indentation + lines.replace(newLine, newLine + indentation);
-    }
-
-    /**
-     * Formats the values in a frame as a tabulated string.
-     *
-     * @param frame
-     * @return the values in {@code frame} as a tabulated string
-     */
-    public static String tabulateValues(CiFrame frame) {
-        int cols = Math.max(frame.numLocals, Math.max(frame.numStack, frame.numLocks));
-        assert cols > 0;
-        ArrayList<Object> cells = new ArrayList<>();
-        cells.add("");
-        for (int i = 0; i < cols; i++) {
-            cells.add(i);
-        }
-        cols++;
-        if (frame.numLocals != 0) {
-            cells.add("locals:");
-            cells.addAll(Arrays.asList(frame.values).subList(0, frame.numLocals));
-            cells.addAll(Collections.nCopies(cols - frame.numLocals - 1, ""));
-        }
-        if (frame.numStack != 0) {
-            cells.add("stack:");
-            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals, frame.numLocals + frame.numStack));
-            cells.addAll(Collections.nCopies(cols - frame.numStack - 1, ""));
-        }
-        if (frame.numLocks != 0) {
-            cells.add("locks:");
-            cells.addAll(Arrays.asList(frame.values).subList(frame.numLocals + frame.numStack, frame.values.length));
-            cells.addAll(Collections.nCopies(cols - frame.numLocks - 1, ""));
-        }
-        Object[] cellArray = cells.toArray();
-        for (int i = 0; i < cellArray.length; i++) {
-            if ((i % cols) != 0) {
-                cellArray[i] = "|" + cellArray[i];
-            }
-        }
-        return CiUtil.tabulate(cellArray, cols, 1, 1);
-    }
-
-    /**
-     * Formats a given table as a string. The value of each cell is produced by {@link String#valueOf(Object)}.
-     *
-     * @param cells the cells of the table in row-major order
-     * @param cols the number of columns per row
-     * @param lpad the number of space padding inserted before each formatted cell value
-     * @param rpad the number of space padding inserted after each formatted cell value
-     * @return a string with one line per row and each column left-aligned
-     */
-    public static String tabulate(Object[] cells, int cols, int lpad, int rpad) {
-        int rows = (cells.length + (cols - 1)) / cols;
-        int[] colWidths = new int[cols];
-        for (int col = 0; col < cols; col++) {
-            for (int row = 0; row < rows; row++) {
-                int index = col + (row * cols);
-                if (index < cells.length) {
-                    Object cell = cells[index];
-                    colWidths[col] = Math.max(colWidths[col], String.valueOf(cell).length());
-                }
-            }
-        }
-        StringBuilder sb = new StringBuilder();
-        String nl = NEW_LINE;
-        for (int row = 0; row < rows; row++) {
-            for (int col = 0; col < cols; col++) {
-                int index = col + (row * cols);
-                if (index < cells.length) {
-                    for (int i = 0; i < lpad; i++) {
-                        sb.append(' ');
-                    }
-                    Object cell = cells[index];
-                    String s = String.valueOf(cell);
-                    int w = s.length();
-                    sb.append(s);
-                    while (w < colWidths[col]) {
-                        sb.append(' ');
-                        w++;
-                    }
-                    for (int i = 0; i < rpad; i++) {
-                        sb.append(' ');
-                    }
-                }
-            }
-            sb.append(nl);
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Convenient shortcut for calling {@link #appendLocation(StringBuilder, RiMethod, int)} without having to supply a
-     * a {@link StringBuilder} instance and convert the result to a string.
-     */
-    public static String toLocation(RiResolvedMethod method, int bci) {
-        return appendLocation(new StringBuilder(), method, bci).toString();
-    }
-
-    /**
-     * Appends a string representation of a location specified by a given method and bci to a given
-     * {@link StringBuilder}. If a stack trace element with a non-null file name and non-negative line number is
-     * {@linkplain RiMethod#toStackTraceElement(int) available} for the given method, then the string returned is the
-     * {@link StackTraceElement#toString()} value of the stack trace element, suffixed by the bci location. For example:
-     *
-     * <pre>
-     *     java.lang.String.valueOf(String.java:2930) [bci: 12]
-     * </pre>
-     *
-     * Otherwise, the string returned is the value of {@code CiUtil.format("%H.%n(%p)"}, suffixed by the bci location.
-     * For example:
-     *
-     * <pre>
-     *     java.lang.String.valueOf(int) [bci: 12]
-     * </pre>
-     *
-     * @param sb
-     * @param method
-     * @param bci
-     * @return
-     */
-    public static StringBuilder appendLocation(StringBuilder sb, RiResolvedMethod method, int bci) {
-        if (method != null) {
-            StackTraceElement ste = method.toStackTraceElement(bci);
-            if (ste.getFileName() != null && ste.getLineNumber() > 0) {
-                sb.append(ste);
-            } else {
-                sb.append(CiUtil.format("%H.%n(%p)", method));
-            }
-        } else {
-            sb.append("Null method");
-        }
-        return sb.append(" [bci: ").append(bci).append(']');
-    }
-
-    /**
-     * Appends a formatted code position to a {@link StringBuilder}.
-     *
-     * @param sb the {@link StringBuilder} to append to
-     * @param pos the code position to format and append to {@code sb}
-     * @return the value of {@code sb}
-     */
-    public static StringBuilder append(StringBuilder sb, CiCodePos pos) {
-        appendLocation(sb.append("at "), pos.method, pos.bci);
-        if (pos.caller != null) {
-            sb.append(NEW_LINE);
-            append(sb, pos.caller);
-        }
-        return sb;
-    }
-
-    /**
-     * Appends a formatted frame to a {@link StringBuilder}.
-     *
-     * @param sb the {@link StringBuilder} to append to
-     * @param frame the frame to format and append to {@code sb}
-     * @return the value of {@code sb}
-     */
-    public static StringBuilder append(StringBuilder sb, CiFrame frame) {
-        appendLocation(sb.append("at "), frame.method, frame.bci);
-        if (frame.values != null && frame.values.length > 0) {
-            sb.append(NEW_LINE);
-            String table = tabulateValues(frame);
-            String[] rows = table.split(NEW_LINE);
-            for (int i = 0; i < rows.length; i++) {
-                String row = rows[i];
-                if (!row.trim().isEmpty()) {
-                    sb.append("  ").append(row);
-                    if (i != rows.length - 1) {
-                        sb.append(NEW_LINE);
-                    }
-                }
-            }
-        }
-        if (frame.caller() != null) {
-            sb.append(NEW_LINE);
-            append(sb, frame.caller());
-        } else if (frame.caller != null) {
-            sb.append(NEW_LINE);
-            append(sb, frame.caller);
-        }
-        return sb;
-    }
-
-    /**
-     * Formats a location present in a register or frame reference map.
-     */
-    public static class RefMapFormatter {
-
-        /**
-         * The size of a stack slot.
-         */
-        public final int slotSize;
-
-        /**
-         * The register used as the frame pointer.
-         */
-        public final CiRegister fp;
-
-        public final CiArchitecture arch;
-
-        /**
-         * The offset (in bytes) from the slot pointed to by {@link #fp} to the slot corresponding to bit 0 in the frame
-         * reference map.
-         */
-        public final int refMapToFPOffset;
-
-        public RefMapFormatter(CiArchitecture arch, int slotSize, CiRegister fp, int refMapToFPOffset) {
-            this.arch = arch;
-            this.slotSize = slotSize;
-            this.fp = fp;
-            this.refMapToFPOffset = refMapToFPOffset;
-        }
-
-        public String formatStackSlot(int frameRefMapIndex) {
-            int refMapOffset = frameRefMapIndex * slotSize;
-            int fpOffset = refMapOffset + refMapToFPOffset;
-            if (fpOffset >= 0) {
-                return fp + "+" + fpOffset;
-            }
-            return fp.name + fpOffset;
-        }
-
-        public String formatRegister(int regRefMapIndex) {
-            return arch.registers[regRefMapIndex].toString();
-        }
-    }
-
-    /**
-     * Appends a formatted debug info to a {@link StringBuilder}.
-     *
-     * @param sb the {@link StringBuilder} to append to
-     * @param info the debug info to format and append to {@code sb}
-     * @return the value of {@code sb}
-     */
-    public static StringBuilder append(StringBuilder sb, CiDebugInfo info, RefMapFormatter formatter) {
-        String nl = NEW_LINE;
-        if (info.hasRegisterRefMap()) {
-            sb.append("  reg-ref-map:");
-            CiBitMap bm = info.registerRefMap;
-            if (formatter != null) {
-                for (int reg = bm.nextSetBit(0); reg >= 0; reg = bm.nextSetBit(reg + 1)) {
-                    sb.append(" " + formatter.formatRegister(reg));
-                }
-            }
-            sb.append(' ').append(bm).append(nl);
-        }
-        if (info.hasStackRefMap()) {
-            sb.append("frame-ref-map:");
-            CiBitMap bm = info.frameRefMap;
-            if (formatter != null) {
-                for (int i = bm.nextSetBit(0); i >= 0; i = bm.nextSetBit(i + 1)) {
-                    sb.append(" " + formatter.formatStackSlot(i));
-                }
-            }
-            sb.append(' ').append(bm).append(nl);
-        }
-        CiFrame frame = info.frame();
-        if (frame != null) {
-            append(sb, frame);
-        } else if (info.codePos != null) {
-            append(sb, info.codePos);
-        }
-        return sb;
-    }
-
-    public static CiKind[] signatureToKinds(RiResolvedMethod method) {
-        CiKind receiver = isStatic(method.accessFlags()) ? null : method.holder().kind(true);
-        return signatureToKinds(method.signature(), receiver);
-    }
-
-    public static CiKind[] signatureToKinds(RiSignature signature, CiKind receiverKind) {
-        int args = signature.argumentCount(false);
-        CiKind[] result;
-        int i = 0;
-        if (receiverKind != null) {
-            result = new CiKind[args + 1];
-            result[0] = receiverKind;
-            i = 1;
-        } else {
-            result = new CiKind[args];
-        }
-        for (int j = 0; j < args; j++) {
-            result[i + j] = signature.argumentKindAt(j, true);
-        }
-        return result;
-    }
-
-    public static Class< ? >[] signatureToTypes(RiSignature signature, RiResolvedType accessingClass) {
-        int count = signature.argumentCount(false);
-        Class< ? >[] result = new Class< ? >[count];
-        for (int i = 0; i < result.length; ++i) {
-            result[i] = signature.argumentTypeAt(i, accessingClass).resolve(accessingClass).toJava();
-        }
-        return result;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValue.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2009, 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.ci;
-
-import java.io.*;
-
-/**
- * Abstract base class for values manipulated by the compiler. All values have a {@linkplain CiKind kind} and are immutable.
- */
-public abstract class CiValue implements Serializable {
-    private static final long serialVersionUID = -6909397188697766469L;
-
-    @SuppressWarnings("serial")
-    public static CiValue IllegalValue = new CiValue(CiKind.Illegal) {
-        @Override
-        public String toString() {
-            return "-";
-        }
-    };
-
-    /**
-     * The kind of this value.
-     */
-    public final CiKind kind;
-
-    /**
-     * Initializes a new value of the specified kind.
-     * @param kind the kind
-     */
-    protected CiValue(CiKind kind) {
-        this.kind = kind;
-    }
-
-    /**
-     * String representation of the kind, which should be the end of all {@link #toString()} implementation of subclasses.
-     */
-    protected final String kindSuffix() {
-        return "|" + kind.typeChar;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiValueUtil.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2012, 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.ci;
-
-public class CiValueUtil {
-    public static boolean isIllegal(CiValue value) {
-        assert value != null;
-        return value == CiValue.IllegalValue;
-    }
-
-    public static boolean isLegal(CiValue value) {
-        return !isIllegal(value);
-    }
-
-    public static boolean isVirtualObject(CiValue value) {
-        assert value != null;
-        return value instanceof CiVirtualObject;
-    }
-
-    public static CiVirtualObject asVirtualObject(CiValue value) {
-        assert value != null;
-        return (CiVirtualObject) value;
-    }
-
-    public static boolean isConstant(CiValue value) {
-        assert value != null;
-        return value instanceof CiConstant;
-    }
-
-    public static CiConstant asConstant(CiValue value) {
-        assert value != null;
-        return (CiConstant) value;
-    }
-
-
-    public static boolean isStackSlot(CiValue value) {
-        assert value != null;
-        return value instanceof CiStackSlot;
-    }
-
-    public static CiStackSlot asStackSlot(CiValue value) {
-        assert value != null;
-        return (CiStackSlot) value;
-    }
-
-    public static boolean isAddress(CiValue value) {
-        assert value != null;
-        return value instanceof CiAddress;
-    }
-
-    public static CiAddress asAddress(CiValue value) {
-        assert value != null;
-        return (CiAddress) value;
-    }
-
-
-    public static boolean isRegister(CiValue value) {
-        assert value != null;
-        return value instanceof CiRegisterValue;
-    }
-
-    public static CiRegister asRegister(CiValue value) {
-        assert value != null;
-        return ((CiRegisterValue) value).reg;
-    }
-
-    public static CiRegister asIntReg(CiValue value) {
-        assert value.kind == CiKind.Int || value.kind == CiKind.Jsr;
-        return asRegister(value);
-    }
-
-    public static CiRegister asLongReg(CiValue value) {
-        assert value.kind == CiKind.Long : value.kind;
-        return asRegister(value);
-    }
-
-    public static CiRegister asObjectReg(CiValue value) {
-        assert value.kind == CiKind.Object;
-        return asRegister(value);
-    }
-
-    public static CiRegister asFloatReg(CiValue value) {
-        assert value.kind == CiKind.Float;
-        return asRegister(value);
-    }
-
-    public static CiRegister asDoubleReg(CiValue value) {
-        assert value.kind == CiKind.Double;
-        return asRegister(value);
-    }
-
-
-    public static boolean sameRegister(CiValue v1, CiValue v2) {
-        return isRegister(v1) && isRegister(v2) && asRegister(v1) == asRegister(v2);
-    }
-
-    public static boolean sameRegister(CiValue v1, CiValue v2, CiValue v3) {
-        return sameRegister(v1, v2) && sameRegister(v1, v3);
-    }
-
-    public static boolean differentRegisters(CiValue v1, CiValue v2) {
-        return !isRegister(v1) || !isRegister(v2) || asRegister(v1) != asRegister(v2);
-    }
-
-    public static boolean differentRegisters(CiValue v1, CiValue v2, CiValue v3) {
-        return differentRegisters(v1, v2) && differentRegisters(v1, v3) && differentRegisters(v2, v3);
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiVirtualObject.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2010, 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.ci;
-
-import com.oracle.max.cri.ri.*;
-
-/**
- * An instance of this class represents an object whose allocation was removed by escape analysis. The information stored in the {@link CiVirtualObject} is used during
- * deoptimization to recreate the object.
- */
-public final class CiVirtualObject extends CiValue {
-    private static final long serialVersionUID = -2907197776426346021L;
-
-    private final RiType type;
-    private CiValue[] values;
-    private final int id;
-
-    /**
-     * Creates a new CiVirtualObject for the given type, with the given fields. If the type is an instance class then the values array needs to have one entry for each field, ordered in
-     * like the fields returned by {@link RiResolvedType#declaredFields()}. If the type is an array then the length of the values array determines the reallocated array length.
-     * @param type the type of the object whose allocation was removed during compilation. This can be either an instance of an array type.
-     * @param values an array containing all the values to be stored into the object when it is recreated.
-     * @param id a unique id that identifies the object within the debug information for one position in the compiled code.
-     * @return a new CiVirtualObject instance.
-     */
-    public static CiVirtualObject get(RiType type, CiValue[] values, int id) {
-        return new CiVirtualObject(type, values, id);
-    }
-
-    private CiVirtualObject(RiType type, CiValue[] values, int id) {
-        super(CiKind.Object);
-        this.type = type;
-        this.values = values;
-        this.id = id;
-    }
-
-    @Override
-    public String toString() {
-        return "vobject:" + id;
-    }
-
-    /**
-     * @return the type of the object whose allocation was removed during compilation. This can be either an instance of an array type.
-     */
-    public RiType type() {
-        return type;
-    }
-
-    /**
-     * @return an array containing all the values to be stored into the object when it is recreated.
-     */
-    public CiValue[] values() {
-        return values;
-    }
-
-    /**
-     * @return the unique id that identifies the object within the debug information for one position in the compiled code.
-     */
-    public int id() {
-        return id;
-    }
-
-    /**
-     * Overwrites the current set of values with a new one.
-     * @param values an array containing all the values to be stored into the object when it is recreated.
-     */
-    public void setValues(CiValue[] values) {
-        this.values = values;
-    }
-
-    @Override
-    public int hashCode() {
-        return kind.ordinal() + type.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-        if (o instanceof CiVirtualObject) {
-            CiVirtualObject l = (CiVirtualObject) o;
-            if (l.type != type || l.values.length != values.length) {
-                return false;
-            }
-            for (int i = 0; i < values.length; i++) {
-                if (values[i] != l.values[i]) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * This is a helper class used to create virtual objects for a number of different JDK classes.
-     */
-    public static class CiVirtualObjectFactory {
-        private int nextId = 0;
-        private final RiRuntime runtime;
-
-        public CiVirtualObjectFactory(RiRuntime runtime) {
-            this.runtime = runtime;
-        }
-
-        public CiVirtualObject constantProxy(CiKind kind, CiValue objectValue, CiValue primitiveValue) {
-            CiConstant cKind = CiConstant.forObject(kind);
-            // TODO: here the ordering is hard coded... we should query RiType.fields() and act accordingly
-            return new CiVirtualObject(runtime.getType(CiConstant.class), new CiValue[] {cKind, primitiveValue, CiValue.IllegalValue, objectValue}, nextId++);
-        }
-
-        public CiValue proxy(CiValue ciValue) {
-            switch (ciValue.kind) {
-                case Boolean:
-                    return new CiVirtualObject(runtime.getType(Boolean.class), new CiValue[] {ciValue}, nextId++);
-                case Byte:
-                    return new CiVirtualObject(runtime.getType(Byte.class), new CiValue[] {ciValue}, nextId++);
-                case Char:
-                    return new CiVirtualObject(runtime.getType(Character.class), new CiValue[] {ciValue}, nextId++);
-                case Double:
-                    return new CiVirtualObject(runtime.getType(Double.class), new CiValue[] {ciValue, CiValue.IllegalValue}, nextId++);
-                case Float:
-                    return new CiVirtualObject(runtime.getType(Float.class), new CiValue[] {ciValue}, nextId++);
-                case Int:
-                    return new CiVirtualObject(runtime.getType(Integer.class), new CiValue[] {ciValue}, nextId++);
-                case Long:
-                    return new CiVirtualObject(runtime.getType(Long.class), new CiValue[] {ciValue, CiValue.IllegalValue}, nextId++);
-                case Object:
-                    return ciValue;
-                case Short:
-                    return new CiVirtualObject(runtime.getType(Short.class), new CiValue[] {ciValue}, nextId++);
-                default:
-                    assert false : ciValue.kind;
-                    return null;
-            }
-        }
-
-        public CiVirtualObject arrayProxy(RiType arrayType, CiValue[] values) {
-            return new CiVirtualObject(arrayType, values, nextId++);
-        }
-
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/package-info.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2010, 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.
- */
-/**
- * The compiler-provided part of the bi-directional interface between the compiler and the runtime system of a virtual machine for the instruction set defined in
- * {@link com.oracle.graal.compiler.graphbuilder.Bytecodes}.
- *
- * The target hardware architecture is represented by {@link com.oracle.max.cri.ci.CiArchitecture} and the specific target machine
- * environment for a compiler instance is represented by {@link com.oracle.max.cri.ci.CiTarget}.
- * <p>
- * A {@code CiResult} encapsulates
- * {@linkplain com.oracle.max.cri.ci.CiStatistics compilation statistics}, possible {@linkplain com.oracle.max.cri.ci.CiBailout error state}
- * and the {@linkplain com.oracle.max.cri.ci.CiTargetMethod compiled code and metadata}.
- * {@link com.oracle.max.cri.ci.CiCodePos} and {@link com.oracle.max.cri.ci.CiDebugInfo} provide detailed information to the
- * runtime to support debugging and deoptimization of the compiled code.
- * <p>
- * The compiler manipulates {@link com.oracle.max.cri.ci.CiValue} instances that have a {@link com.oracle.max.cri.ci.CiKind}, and are
- * immutable. A concrete {@link com.oracle.max.cri.ci.CiValue value} is one of the following subclasses:
- * <ul>
- * <li>{@link com.oracle.max.cri.ci.CiConstant}: a constant value.
- * <li>{@link com.oracle.max.cri.ci.CiRegisterValue}: a value stored in a {@linkplain com.oracle.max.cri.ci.CiRegister target machine register}.
- * <li>{@link com.oracle.max.cri.ci.CiStackSlot}: a spill slot or an outgoing stack-based argument in a method's frame.
- * <li>{@link com.oracle.max.cri.ci.CiAddress}: an address in target machine memory.
- * <li>{@link com.oracle.graal.compiler.lir.CiVariable}: a value (cf. virtual register) that is yet to be bound to a target machine location (physical register or memory address).
- *</ul>
- */
-package com.oracle.max.cri.ci;
-
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/package-info.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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.
- */
-/**
- * A virtual machine compiler-runtime interface (CRI).
- * <p>
- * Specifically, this package defines an interface between the compiler and the runtime system of a virtual machine for
- * the instruction set defined in {@link com.oracle.graal.compiler.graphbuilder.Bytecodes}. The interface has three components:
- * <ol>
- * <li>the {@link com.oracle.max.cri.ci compiler-provided interface} that must be used by the runtime.
- * <li>the {@link com.oracle.max.cri.ri runtime-provided interface} that must be used by the compiler.
- * <li>the {@link com.oracle.max.cri.xir XIR interface} for translating object operations.
- * </ol>
- *
- * The interface is independent of any particular compiler or runtime implementation.
- * <p>
- * For more details see <a href="http://wikis.sun.com/download/attachments/173802383/vee2010.pdf">Improving Compiler-Runtime Separation with XIR</a>.
- */
-package com.oracle.max.cri;
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCodeInfo.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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;
-
-import com.oracle.max.cri.ci.*;
-
-
-/**
- * Represents some code installed in the code cache of the runtime.
- * This encapsulated details are only for informational purposes.
- * At any time, the runtime may invalidate the underlying code (e.g. due to deopt etc).
- */
-public interface RiCodeInfo {
-
-    /**
-     * Gets the start address of this installed code.
-     */
-    long start();
-
-    /**
-     * Gets a copy of this installed code.
-     */
-    byte[] code();
-
-    /**
-     * Gets the target method (if any) from which this installed code was produced.
-     */
-    CiTargetMethod targetMethod();
-
-    /**
-     * Gets the method (if any) from which this installed code was compiled.
-     */
-    RiResolvedMethod method();
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiCompiledMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2011, 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;
-
-/**
- * Represents a compiled instance of a method. It may have been invalidated or removed in the meantime.
- */
-public interface RiCompiledMethod {
-
-    public abstract class MethodInvalidatedException extends RuntimeException {
-
-        private static final long serialVersionUID = -3540232440794244844L;
-    }
-
-    /**
-     * Returns the method to which the compiled code belongs.
-     * @return the method to which the compiled code belongs.
-     */
-    RiResolvedMethod method();
-
-    /**
-     * @return true if the code represented by this object is still valid, false otherwise (may happen due to deopt, etc.)
-     */
-    boolean isValid();
-
-    Object execute(Object arg1, Object arg2, Object arg3);
-
-    Object executeVarargs(Object... args);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiConstantPool.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-/**
- * Represents the runtime representation of the constant pool that is
- * used by the compiler when parsing bytecode. The {@code lookupXXX} methods look up a constant
- * pool entry without performing resolution, and are used during compilation.
- */
-public interface RiConstantPool {
-
-    /**
-     * Makes sure that the type referenced by the specified constant pool entry is loaded and
-     * initialized. This can be used to compile time resolve a type. It works for field, method,
-     * or type constant pool entries.
-     * @param cpi the index of the constant pool entry that references the type
-     * @param opcode the opcode of the instruction that references the type
-     */
-    void loadReferencedType(int cpi, int opcode);
-
-    /**
-     * Looks up a reference to a field. If {@code opcode} is non-negative, then resolution checks
-     * specific to the JVM instruction it denotes are performed if the field is already resolved.
-     * Should any of these checks fail, an {@linkplain RiField#isResolved() unresolved}
-     * field reference is returned.
-     *
-     * @param cpi the constant pool index
-     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
-     * @return a reference to the field at {@code cpi} in this pool
-     * @throws ClassFormatError if the entry at {@code cpi} is not a field
-     */
-    RiField lookupField(int cpi, int opcode);
-
-    /**
-     * Looks up a reference to a method. If {@code opcode} is non-negative, then resolution checks
-     * specific to the JVM instruction it denotes are performed if the method is already resolved.
-     * Should any of these checks fail, an {@linkplain RiMethod#isResolved() unresolved}
-     * method reference is returned.
-     *
-     * @param cpi the constant pool index
-     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
-     * @return a reference to the method at {@code cpi} in this pool
-     * @throws ClassFormatError if the entry at {@code cpi} is not a method
-     */
-    RiMethod lookupMethod(int cpi, int opcode);
-
-    /**
-     * Looks up a reference to a type. If {@code opcode} is non-negative, then resolution checks
-     * specific to the JVM instruction it denotes are performed if the type is already resolved.
-     * Should any of these checks fail, an {@linkplain RiType#isResolved() unresolved}
-     * type reference is returned.
-     *
-     * @param cpi the constant pool index
-     * @param opcode the opcode of the instruction for which the lookup is being performed or {@code -1}
-     * @return a reference to the compiler interface type
-     */
-    RiType lookupType(int cpi, int opcode);
-
-    /**
-     * Looks up a method signature.
-     *
-     * @param cpi the constant pool index
-     * @return the method signature at index {@code cpi} in this constant pool
-     */
-    RiSignature lookupSignature(int cpi);
-
-    /**
-     * Looks up a constant at the specified index.
-     * @param cpi the constant pool index
-     * @return the {@code CiConstant} instance representing the constant
-     */
-    Object lookupConstant(int cpi);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptAction.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +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,                           // 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
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptReason.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +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 {
-    None,
-    NullCheckException,
-    BoundsCheckException,
-    ClassCastException,
-    ArrayStoreException,
-    UnreachedCode,
-    TypeCheckedInliningViolated,
-    OptimizedTypeCheckViolated,
-    NotCompiledExceptionHandler,
-    Unresolved,
-    JavaSubroutineMismatch,
-    ArithmeticException,
-    RuntimeConstraint;
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiExceptionHandler.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-/**
- * Represents an exception handler within the bytecode.
- */
-public interface RiExceptionHandler {
-
-    /**
-     * Gets the start bytecode index of the protected range of this handler.
-     * @return the start bytecode index
-     */
-    int startBCI();
-
-    /**
-     * Gets the end bytecode index of the protected range of this handler.
-     * @return the end bytecode index
-     */
-    int endBCI();
-
-    /**
-     * Gets the bytecode index of the handler block of this handler.
-     * @return the handler block bytecode index
-     */
-    int handlerBCI();
-
-    /**
-     * Gets the index into the constant pool representing the type of exception
-     * caught by this handler.
-     * @return the constant pool index of the catch type
-     */
-    int catchTypeCPI();
-
-    /**
-     * Checks whether this handler catches all exceptions.
-     * @return {@code true} if this handler catches all exceptions
-     */
-    boolean isCatchAll();
-
-    /**
-     * The type of exception caught by this exception handler.
-     *
-     * @return the exception type
-     */
-    RiType catchType();
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiExceptionSeen.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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;
-
-
-/**
- * Represents the three possibilities that an exception was seen at a specific BCI.
- */
-public enum RiExceptionSeen {
-    TRUE,
-    FALSE,
-    NOT_SUPPORTED;
-
-    public static RiExceptionSeen get(boolean value) {
-        return value ? TRUE : FALSE;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiField.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * Represents a reference to a field, including both resolved and unresolved fields. Fields, like methods and types, are
- * resolved through {@link RiConstantPool constant pools}, and their actual implementation is provided by the
- * {@link RiRuntime runtime} to the compiler.
- */
-public interface RiField {
-    /**
-     * Gets the name of this field as a string.
-     * @return the name of this field
-     */
-    String name();
-
-    /**
-     * Gets the type of this field as a compiler-runtime interface type.
-     * @return the type of this field
-     */
-    RiType type();
-
-    /**
-     * Gets the kind of this field.
-     * @param architecture When true, the architecture-specific kind used for emitting machine code is returned.
-     *        When false, the kind according to the Java specification is returned.
-     * @return the kind
-     */
-    CiKind kind(boolean architecture);
-
-    /**
-     * Gets the holder of this field as a compiler-runtime interface type.
-     * @return the holder of this field
-     */
-    RiType holder();
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-/**
- * Represents resolved and unresolved methods. Methods, like fields and types, are resolved through
- * {@link RiConstantPool constant pools}, and their actual implementation is provided by the {@link RiRuntime runtime}
- * to the compiler.
- */
-public interface RiMethod {
-
-    /**
-     * Gets the name of the method as a string.
-     * @return the name of the method
-     */
-    String name();
-
-    /**
-     * Gets the type in which this method is declared.
-     * @return the type in which this method is declared
-     */
-    RiType holder();
-
-    /**
-     * Gets the signature of the method.
-     * @return the signature of the method
-     */
-    RiSignature signature();
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiProfilingInfo.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +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;
-
-
-/**
- * Provides access to the profiling information of one specific method.
- * Every accessor method returns the information that is available at the time of invocation.
- * If a method is invoked multiple times, it may return significantly different results for every invocation
- * as the profiling information may be changed by other Java threads at any time.
- */
-public interface RiProfilingInfo {
-    /**
-     * Returns an estimate of how often the branch at the given byte code was taken.
-     * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if this information is not available.
-     */
-    double getBranchTakenProbability(int bci);
-
-    /**
-     * Returns an estimate of how often the switch cases are taken at the given BCI.
-     * The default case is stored as the last entry.
-     * @return A double value that contains the estimated probabilities, with 0.0 meaning never and 1.0 meaning always,
-     * or -1 if this information is not available.
-     */
-    double[] getSwitchProbabilities(int bci);
-
-    /**
-     * Returns the TypeProfile for the given BCI.
-     * @return Returns an RiTypeProfile object, or null if not available.
-     */
-    RiTypeProfile getTypeProfile(int bci);
-
-    /**
-     * Returns information if the given BCI did ever throw an exception.
-     * @return @link{RiExceptionSeen.TRUE} if the instruction has thrown an exception at least once,
-     * @link{RiExceptionSeen.FALSE} if it never threw an exception, and @link{RiExceptionSeen.UNKNOWN}
-     * if this information was not recorded.
-     */
-    RiExceptionSeen getExceptionSeen(int bci);
-
-    /**
-     * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts to each other,
-     * as the returned value highly depends on the time of invocation.
-     * @return the estimated execution count or -1 if not available.
-     */
-    int getExecutionCount(int bci);
-
-    /**
-     * Returns how frequently a method was deoptimized for the given deoptimization reason. This only indicates how
-     * often the method did fall back to the interpreter for the execution and does not indicate how often it was recompiled.
-     * @param reason the reason for which the number of deoptimizations should be queried
-     * @return the number of times the compiled method deoptimized for the given reason.
-     */
-    int getDeoptimizationCount(RiDeoptReason reason);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRegisterAttributes.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2010, 2011, 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;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * A collection of register attributes. The specific attribute values for a register may be
- * local to a compilation context. For example, a {@link RiRegisterConfig} in use during
- * a compilation will determine which registers are callee saved.
- */
-public class RiRegisterAttributes {
-
-    /**
-     * Denotes a register whose value preservation (if required) across a call is the responsibility of the caller.
-     */
-    public final boolean isCallerSave;
-
-    /**
-     * Denotes a register whose value preservation (if required) across a call is the responsibility of the callee.
-     */
-    public final boolean isCalleeSave;
-
-    /**
-     * Denotes a register that is available for use by a register allocator.
-     */
-    public final boolean isAllocatable;
-
-    /**
-     * Denotes a register guaranteed to be non-zero if read in compiled Java code.
-     * For example, a register dedicated to holding the current thread.
-     */
-    public boolean isNonZero;
-
-    public RiRegisterAttributes(boolean isCallerSave, boolean isCalleeSave, boolean isAllocatable) {
-        this.isCallerSave = isCallerSave;
-        this.isCalleeSave = isCalleeSave;
-        this.isAllocatable = isAllocatable;
-    }
-
-    public static final RiRegisterAttributes NONE = new RiRegisterAttributes(false, false, false);
-
-    /**
-     * Creates a map from register {@linkplain CiRegister#number numbers} to register
-     * {@linkplain RiRegisterAttributes attributes} for a given register configuration and set of
-     * registers.
-     *
-     * @param registerConfig a register configuration
-     * @param registers a set of registers
-     * @return an array whose length is the max register number in {@code registers} plus 1. An element at index i holds
-     *         the attributes of the register whose number is i.
-     */
-    public static RiRegisterAttributes[] createMap(RiRegisterConfig registerConfig, CiRegister[] registers) {
-        RiRegisterAttributes[] map = new RiRegisterAttributes[registers.length];
-        for (CiRegister reg : registers) {
-            if (reg != null) {
-                CiCalleeSaveLayout csl = registerConfig.getCalleeSaveLayout();
-                RiRegisterAttributes attr = new RiRegisterAttributes(
-                                Arrays.asList(registerConfig.getCallerSaveRegisters()).contains(reg),
-                                csl == null ? false : Arrays.asList(csl.registers).contains(reg),
-                                Arrays.asList(registerConfig.getAllocatableRegisters()).contains(reg));
-                if (map.length <= reg.number) {
-                    map = Arrays.copyOf(map, reg.number + 1);
-                }
-                map[reg.number] = attr;
-            }
-        }
-        for (int i = 0; i < map.length; i++) {
-            if (map[i] == null) {
-                map[i] = NONE;
-            }
-        }
-        return map;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRegisterConfig.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiCallingConvention.*;
-import com.oracle.max.cri.ci.CiRegister.*;
-
-/**
- * A register configuration binds roles and {@linkplain RiRegisterAttributes attributes}
- * to physical registers.
- */
-public interface RiRegisterConfig {
-
-    /**
-     * Gets the register to be used for returning a value of a given kind.
-     */
-    CiRegister getReturnRegister(CiKind kind);
-
-    /**
-     * Gets the register to which {@link CiRegister#Frame} and {@link CiRegister#CallerFrame} are bound.
-     */
-    CiRegister getFrameRegister();
-
-    CiRegister getScratchRegister();
-
-    /**
-     * Gets the calling convention describing how arguments are passed.
-     *
-     * @param type the type of calling convention being requested
-     * @param parameters the types of the arguments of the call
-     * @param target the target platform
-     * @param stackOnly ignore registers
-     */
-    CiCallingConvention getCallingConvention(Type type, CiKind[] parameters, CiTarget target, boolean stackOnly);
-
-    /**
-     * Gets the ordered set of registers that are can be used to pass parameters
-     * according to a given calling convention.
-     *
-     * @param type the type of calling convention
-     * @param flag specifies whether registers for {@linkplain RegisterFlag#CPU integral} or
-     *             {@linkplain} RegisterFlag#FPU floating point} parameters are being requested
-     * @return the ordered set of registers that may be used to pass parameters in a call conforming to {@code type}
-     */
-    CiRegister[] getCallingConventionRegisters(Type type, RegisterFlag flag);
-
-    /**
-     * Gets the set of registers that can be used by the register allocator.
-     */
-    CiRegister[] getAllocatableRegisters();
-
-    /**
-     * Gets the set of registers that can be used by the register allocator,
-     * {@linkplain CiRegister#categorize(CiRegister[]) categorized} by register {@linkplain RegisterFlag flags}.
-     *
-     * @return a map from each {@link RegisterFlag} constant to the list of {@linkplain #getAllocatableRegisters()
-     *         allocatable} registers for which the flag is {@linkplain #isSet(RegisterFlag) set}
-     *
-     */
-    EnumMap<RegisterFlag, CiRegister[]> getCategorizedAllocatableRegisters();
-
-    /**
-     * Gets the registers whose values must be preserved by a method across any call it makes.
-     */
-    CiRegister[] getCallerSaveRegisters();
-
-    /**
-     * Gets the layout of the callee save area of this register configuration.
-     *
-     * @return {@code null} if there is no callee save area
-     */
-    CiCalleeSaveLayout getCalleeSaveLayout();
-
-    /**
-     * Gets a map from register {@linkplain CiRegister#number numbers} to register
-     * {@linkplain RiRegisterAttributes attributes} for this register configuration.
-     *
-     * @return an array where an element at index i holds the attributes of the register whose number is i
-     * @see CiRegister#categorize(CiRegister[])
-     */
-    RiRegisterAttributes[] getAttributesMap();
-
-    /**
-     * Gets the register corresponding to a runtime-defined role.
-     *
-     * @param id the identifier of a runtime-defined register role
-     * @return the register playing the role specified by {@code id}
-     */
-    CiRegister getRegisterForRole(int id);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedField.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * Represents a reference to a resolved field. Fields, like methods and types, are
- * resolved through {@link RiConstantPool constant pools}, and their actual implementation is provided by the
- * {@link RiRuntime runtime} to the compiler.
- */
-public interface RiResolvedField extends RiField {
-
-    /**
-     * Gets the access flags for this field. Only the flags specified in the JVM specification
-     * will be included in the returned mask. The utility methods in the {@link Modifier} class
-     * should be used to query the returned mask for the presence/absence of individual flags.
-     * @return the mask of JVM defined field access flags defined for this field
-     */
-    int accessFlags();
-
-    /**
-     * Gets the constant value of this field if available.
-     * @param receiver object from which this field's value is to be read. This value is ignored if this field is static.
-     * @return the constant value of this field or {@code null} if the constant value is not available
-     */
-    CiConstant constantValue(CiConstant receiver);
-
-    /**
-     * Gets the holder of this field as a compiler-runtime interface type.
-     * @return the holder of this field
-     */
-    RiResolvedType holder();
-
-    /**
-     * Returns this field's annotation of a specified type.
-     *
-     * @param annotationClass the Class object corresponding to the annotation type
-     * @return the annotation of type {@code annotationClass} for this field if present, else null
-     */
-    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,232 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.max.cri.ci.*;
-
-
-/**
- * Represents resolved methods. Methods, like fields and types, are resolved through
- * {@link RiConstantPool constant pools}, and their actual implementation is provided by the {@link RiRuntime runtime}
- * to the compiler.
- */
-public interface RiResolvedMethod extends RiMethod {
-
-    /**
-     * Gets the bytecode of the method, if the method {@linkplain #isResolved()} and has code.
-     * The returned byte array does not contain breakpoints or non-Java bytecodes.
-     * @return the bytecode of the method or {@code null} if none is available
-     */
-    byte[] code();
-
-    /**
-     * Gets the size of the bytecode of the method, if the method {@linkplain #isResolved()} and has code.
-     * @return the size of the bytecode in bytes, or 0 if no bytecode is available
-     */
-    int codeSize();
-
-    /**
-     * Gets the size of the compiled machine code.
-     * @return the size of the compiled machine code in bytes, or 0 if no compiled code exists.
-     */
-    int compiledCodeSize();
-
-    /**
-     * Gets an estimate how complex it is to compile this method.
-     * @return A value >= 0, where higher means more complex.
-     */
-    int compilationComplexity();
-
-    /**
-     * Gets the symbol used to link this method if it is native, otherwise {@code null}.
-     */
-    String jniSymbol();
-
-    /**
-     * Gets the type in which this method is declared.
-     * @return the type in which this method is declared
-     */
-    RiResolvedType holder();
-
-    /**
-     * Gets the maximum number of locals used in this method's bytecode.
-     * @return the maximum number of locals
-     */
-    int maxLocals();
-
-    /**
-     * Gets the maximum number of stack slots used in this method's bytecode.
-     * @return the maximum number of stack slots
-     */
-    int maxStackSize();
-
-    /**
-     * Checks whether this method has balanced monitor operations.
-     * @return {@code true} if the method has balanced monitor operations
-     */
-    boolean hasBalancedMonitors();
-
-    /**
-     * Gets the access flags for this method. Only the flags specified in the JVM specification
-     * will be included in the returned mask. The utility methods in the {@link Modifier} class
-     * should be used to query the returned mask for the presence/absence of individual flags.
-     * @return the mask of JVM defined method access flags defined for this method
-     */
-    int accessFlags();
-
-    /**
-     * Checks whether this method is a leaf method.
-     * @return {@code true} if the method is a leaf method (that is, is final or private)
-     */
-    boolean isLeafMethod();
-
-    /**
-     * Checks whether this method is a class initializer.
-     * @return {@code true} if the method is a class initializer
-     */
-    boolean isClassInitializer();
-
-    /**
-     * Checks whether this method is a constructor.
-     * @return {@code true} if the method is a constructor
-     */
-    boolean isConstructor();
-
-    /**
-     * Checks whether this method has been overridden. Decisions made based
-     * on a method being overridden must be registered as dependencies.
-     * @return {@code true} if the method has been overridden
-     */
-    boolean isOverridden();
-
-    /**
-     * Checks whether the compiler can insert safepoint polls in this method.
-     * @return {@code true} if the method cannot have safepoint polls inserted
-     */
-    boolean noSafepointPolls();
-
-    /**
-     * Gets a map from bytecode indexes to bit maps denoting the live locals at that position.
-     * If a non-null array is return, its length is guaranteed to be equal to {@code code().length}.
-     *
-     * @return the liveness map if it is available; {@code null} otherwise
-     */
-    CiBitMap[] livenessMap();
-
-    /**
-     * Checks whether this method can be statically bound (that is, it is final or private or static).
-     * @return {@code true} if this method can be statically bound
-     */
-    boolean canBeStaticallyBound();
-
-    /**
-     * Gets the list of exception handlers for this method.
-     * @return the list of exception handlers
-     */
-    RiExceptionHandler[] exceptionHandlers();
-
-    /**
-     * Gets a stack trace element for this method and a given bytecode index.
-     */
-    StackTraceElement toStackTraceElement(int bci);
-
-    /**
-     * Temporary work-around to support the @ACCESSOR Maxine annotation.
-     * Non-Maxine VMs should just return {@code null}.
-     */
-    RiResolvedType accessor();
-
-    /**
-     * Gets the intrinsic id of this method.
-     */
-    String intrinsic();
-
-    /**
-     * Provides an estimate of how often this method has been executed.
-     * @return The number of invocations, or -1 if this information isn't available.
-     */
-    int invocationCount();
-
-    /**
-     * Returns an object that provides access to the method's profiling information.
-     * @return The profiling information recorded for this method.
-     */
-    RiProfilingInfo profilingInfo();
-
-    /**
-     * Returns a map that the compiler can use to store objects that should survive the current compilation.
-     */
-    Map<Object, Object> compilerStorage();
-
-    /**
-     * Returns a pointer to the method's constant pool.
-     * @return the constant pool
-     */
-    RiConstantPool getConstantPool();
-
-    /**
-     * Returns this method's annotation of a specified type.
-     *
-     * @param annotationClass the Class object corresponding to the annotation type
-     * @return the annotation of type {@code annotationClass} for this method if present, else null
-     */
-    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
-
-    /**
-     * Returns an array of arrays that represent the annotations on the formal
-     * parameters, in declaration order, of this method.
-     *
-     * @see Method#getParameterAnnotations()
-     * @see CiUtil#getParameterAnnotation(int, RiResolvedMethod)
-     */
-    Annotation[][] getParameterAnnotations();
-
-    /**
-     * Returns an array of {@link Type} objects that represent the formal
-     * parameter types, in declaration order, of this method.
-     *
-     * @see Method#getGenericParameterTypes()
-     */
-    Type[] getGenericParameterTypes();
-
-    /**
-     * Returns a {@link Type} object that represents the formal return type of this method.
-     *
-     * @see Method#getGenericReturnType()
-     */
-    Type getGenericReturnType();
-
-    /**
-     * @return {@code true} if this method can be inlined
-     */
-    boolean canBeInlined();
-
-    /**
-     * Dumps the recorded profiling information to TTY.
-     */
-    void dumpProfile();
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * Represents a resolved in the compiler-runtime interface. Types include primitives, objects, {@code void},
- * and arrays thereof. Types, like fields and methods, are resolved through {@link RiConstantPool constant pools}, and
- * their actual implementation is provided by the {@link RiRuntime runtime} to the compiler.
- */
-public interface RiResolvedType extends RiType {
-
-    /**
-     * Gets the encoding of (that is, a constant representing the value of) the specified part of this type.
-     * @param r the part of the this type
-     * @return a constant representing a reference to the specified part of this type
-     */
-    CiConstant getEncoding(Representation r);
-
-    /**
-     * Checks whether this type has any subclasses so far. Any decisions
-     * based on this information require the registration of a dependency, since
-     * this information may change.
-     * @return {@code true} if this class has subclasses
-     */
-    boolean hasSubclass();
-
-    /**
-     * Checks whether this type has a finalizer method.
-     * @return {@code true} if this class has a finalizer
-     */
-    boolean hasFinalizer();
-
-    /**
-     * Checks whether this type has any finalizable subclasses so far. Any decisions
-     * based on this information require the registration of a dependency, since
-     * this information may change.
-     * @return {@code true} if this class has any subclasses with finalizers
-     */
-    boolean hasFinalizableSubclass();
-
-    /**
-     * Checks whether this type is an interface.
-     * @return {@code true} if this type is an interface
-     */
-    boolean isInterface();
-
-    /**
-     * Checks whether this type is an instance class.
-     * @return {@code true} if this type is an instance class
-     */
-    boolean isInstanceClass();
-
-    /**
-     * Checks whether this type is an array class.
-     * @return {@code true} if this type is an array class
-     */
-    boolean isArrayClass();
-
-    /**
-     * Gets the access flags for this type. Only the flags specified in the JVM specification
-     * will be included in the returned mask. The utility methods in the {@link Modifier} class
-     * should be used to query the returned mask for the presence/absence of individual flags.
-     * @return the mask of JVM defined class access flags defined for this type
-     */
-    int accessFlags();
-
-    /**
-     * Checks whether this type is initialized.
-     * @return {@code true} if this type is initialized
-     */
-    boolean isInitialized();
-
-    /**
-     * Checks whether this type is a subtype of another type.
-     * @param other the type to test
-     * @return {@code true} if this type a subtype of the specified type
-     */
-    boolean isSubtypeOf(RiResolvedType other);
-
-    /**
-     * Checks whether the specified object is an instance of this type.
-     * @param obj the object to test
-     * @return {@code true} if the object is an instance of this type
-     */
-    boolean isInstance(CiConstant obj);
-
-    /**
-     * Attempts to get an exact type for this type. Final classes,
-     * arrays of final classes, and primitive types all have exact types.
-     * @return the exact type of this type, if it exists; {@code null} otherwise
-     */
-    RiResolvedType exactType();
-
-    /**
-     * Gets the super type of this type or {@code null} if no such type exists.
-     */
-    RiResolvedType superType();
-
-    /**
-     * Walks the class hierarchy upwards and returns the least common type that is a super type of both
-     * the current and the given type.
-     * @return the least common type that is a super type of both the current and the given type, or null if primitive types are involved.
-     */
-    RiResolvedType leastCommonAncestor(RiResolvedType otherType);
-
-    /**
-     * Attempts to get the unique concrete subtype of this type.
-     * @return the exact type of this type, if it exists; {@code null} otherwise
-     */
-    RiResolvedType uniqueConcreteSubtype();
-
-    /**
-     * For array types, gets the type of the components.
-     * @return the component type of this array type
-     */
-    RiResolvedType componentType();
-
-    /**
-     * Gets the type representing an array with elements of this type.
-     * @return a new compiler interface type representing an array of this type
-     */
-    RiResolvedType arrayOf();
-
-    /**
-     * Resolves the method implementation for virtual dispatches on objects
-     * of this dynamic type.
-     * @param method the method to select the implementation of
-     * @return the method implementation that would be selected at runtime
-     */
-    RiResolvedMethod resolveMethodImpl(RiResolvedMethod method);
-
-    /**
-     * Given an RiMethod a, returns a concrete RiMethod b that is the only possible
-     * unique target for a virtual call on a(). Returns {@code null} if either no
-     * such concrete method or more than one such method exists. Returns the method a
-     * if a is a concrete method that is not overridden. If the compiler uses the
-     * result of this method for its compilation, it must register an assumption
-     * (see {@link CiAssumptions}), because dynamic class loading can invalidate
-     * the result of this method.
-     * @param method the method a for which a unique concrete target is searched
-     * @return the unique concrete target or {@code null} if no such target exists
-     *         or assumptions are not supported by this runtime
-     */
-    RiResolvedMethod uniqueConcreteMethod(RiResolvedMethod method);
-
-    /**
-     * Returns the instance fields declared in this class sorted by field offset.
-     * @return an array of instance fields
-     */
-    RiResolvedField[] declaredFields();
-
-    /**
-     * Returns this type's annotation of a specified type.
-     *
-     * @param annotationClass the Class object corresponding to the annotation type
-     * @return the annotation of type {@code annotationClass} for this type if present, else null
-     */
-    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
-
-    /**
-     * Returns the java.lang.Class object representing this RiType instance or {@code null} if none exists.
-     * @return the java.lang.Class object
-     */
-    Class<?> toJava();
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2009, 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;
-
-import java.lang.reflect.*;
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * Encapsulates the main functionality of the runtime for the compiler, including access
- * to constant pools, OSR frames, inlining requirements, and runtime calls such as checkcast.
-s */
-public interface RiRuntime {
-
-    /**
-     * Offset of the lock within the lock object on the stack.
-
-     * Note: superseded by sizeOfLockData() in Graal.
-     *
-     * @return the offset in bytes
-     */
-    int basicObjectLockOffsetInBytes();
-
-    /**
-     * Get the size in bytes of a lock object on the stack.
-     *
-     * Note: superseded by sizeOfLockData() in Graal.
-     */
-    int sizeOfBasicObjectLock();
-
-    /**
-     * Get the size in bytes for locking information on the stack.
-     */
-    int sizeOfLockData();
-
-    /**
-     * The offset of the normal entry to the code. The compiler inserts NOP instructions to satisfy this constraint.
-     *
-     * @return the code offset in bytes
-     */
-    int codeOffset();
-
-    /**
-     * Returns a disassembly of the given installed code.
-     *
-     * @param code the code that should be disassembled
-     * @return a disassembly. This will be of length 0 if the runtime does not support disassembling.
-     */
-    String disassemble(RiCodeInfo code);
-
-    /**
-     * Returns the disassembly of the given method in a {@code javap}-like format.
-     *
-     * @param method the method that should be disassembled
-     * @return the disassembly. This will be of length 0 if the runtime does not support disassembling.
-     */
-    String disassemble(RiResolvedMethod method);
-
-    /**
-     * Registers the given compiler stub and returns an object that can be used to identify it in the relocation
-     * information.
-     *
-     * @param targetMethod the target method representing the code of the compiler stub
-     * @param name the name of the stub, used for debugging purposes only
-     * @param info the object into which details of the installed code will be written (ignored if null)
-     * @return the identification object
-     */
-    Object registerCompilerStub(CiTargetMethod targetMethod, String name, RiCodeInfo info);
-
-    /**
-     * Returns the RiType object representing the base type for the given kind.
-     */
-    RiResolvedType asRiType(CiKind kind);
-
-    /**
-     * Returns the type of the given constant object.
-     *
-     * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()}
-     */
-    RiResolvedType getTypeOf(CiConstant constant);
-
-
-    RiResolvedType getType(Class<?> clazz);
-
-    /**
-     * Returns true if the given type is a subtype of java/lang/Throwable.
-     */
-    boolean isExceptionType(RiResolvedType type);
-
-    /**
-     * Used by the canonicalizer to compare objects, since a given runtime might not want to expose the real objects to the compiler.
-     *
-     * @return true if the two parameters represent the same runtime object, false otherwise
-     */
-    boolean areConstantObjectsEqual(CiConstant x, CiConstant y);
-
-    /**
-     * Gets the register configuration to use when compiling a given method.
-     *
-     * @param method the top level method of a compilation
-     */
-    RiRegisterConfig getRegisterConfig(RiMethod method);
-
-    RiRegisterConfig getGlobalStubRegisterConfig();
-
-    /**
-     * Custom area on the stack of each compiled method that the VM can use for its own purposes.
-     * @return the size of the custom area in bytes
-     */
-    int getCustomStackAreaSize();
-
-    /**
-     * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all cases, even when
-     * the compiled method has no regular call instructions.
-     * @return the minimum size of the outgoing parameter area in bytes
-     */
-    int getMinimumOutgoingSize();
-
-    /**
-     * Gets the length of the array that is wrapped in a CiConstant object.
-     */
-    int getArrayLength(CiConstant array);
-
-    /**
-     * Converts the given CiConstant object to a object.
-     *
-     * @return {@code null} if the conversion is not possible <b>OR</b> {@code c.isNull() == true}
-     */
-    Object asJavaObject(CiConstant c);
-
-    /**
-     * Converts the given CiConstant object to a {@link Class} object.
-     *
-     * @return {@code null} if the conversion is not possible.
-     */
-    Class<?> asJavaClass(CiConstant c);
-
-    /**
-     * Performs any runtime-specific conversion on the object used to describe the target of a call.
-     */
-    Object asCallTarget(Object target);
-
-    /**
-     * Returns the maximum absolute offset of a runtime call target from any position in the code cache or -1
-     * when not known or not applicable. Intended for determining the required size of address/offset fields.
-     */
-    long getMaxCallTargetOffset(CiRuntimeCall rtcall);
-
-    /**
-     * Provides the {@link RiMethod} for a {@link Method} obtained via reflection.
-     */
-    RiResolvedMethod getRiMethod(Method reflectionMethod);
-
-    /**
-     * Installs some given machine code as the implementation of a given method.
-     *
-     * @param method a method whose executable code is being modified
-     * @param code the code to be executed when {@code method} is called
-     * @param info the object into which details of the installed code will be written (ignored if null)
-     */
-    void installMethod(RiResolvedMethod method, CiTargetMethod code, RiCodeInfo info);
-
-    /**
-     * Adds the given machine code as an implementation of the given method without making it the default implementation.
-     * @param method a method to which the executable code is begin added
-     * @param code the code to be added
-     * @return a reference to the compiled and ready-to-run code
-     */
-    RiCompiledMethod addMethod(RiResolvedMethod method, CiTargetMethod code);
-
-    /**
-     * Encodes a deoptimization action and a deoptimization reason in an integer value.
-     * @return the encoded value as an integer
-     */
-    int encodeDeoptActionAndReason(RiDeoptAction action, RiDeoptReason reason);
-
-    /**
-     * Converts a RiDeoptReason into an integer value.
-     * @return An integer value representing the given RiDeoptReason.
-     */
-    int convertDeoptReason(RiDeoptReason reason);
-
-    /**
-     * Converts a RiDeoptAction into an integer value.
-     * @return An integer value representing the given RiDeoptAction.
-     */
-    int convertDeoptAction(RiDeoptAction action);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiSignature.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * Represents a method signature provided by the runtime.
- *
- * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#7035">Method Descriptors</a>
- */
-public interface RiSignature {
-    /**
-     * Gets the number of arguments in this signature, adding 1 for a receiver if requested.
-     *
-     * @param receiver true if 1 is to be added to the result for a receiver
-     * @return the number of arguments + 1 iff {@code receiver == true}
-     */
-    int argumentCount(boolean receiver);
-
-    /**
-     * Gets the argument type at the specified position. This method will return a
-     * {@linkplain RiType#isResolved() resolved} type if possible but without
-     * triggering any class loading or resolution.
-     *
-     * @param index the index into the parameters, with {@code 0} indicating the first parameter
-     * @param accessingClass the context of the type lookup. If accessing class is resolved, its class loader
-     *        is used to retrieve an existing resolved type. This value can be {@code null} if the caller does
-     *        not care for a resolved type.
-     * @return the {@code index}'th argument type
-     */
-    RiType argumentTypeAt(int index, RiResolvedType accessingClass);
-
-    /**
-     * Gets the argument kind at the specified position.
-     * @param index the index into the parameters, with {@code 0} indicating the first parameter
-     * @param architecture When true, the architecture-specific kind used for emitting machine code is returned.
-     *        When false, the kind according to the Java specification is returned.
-     * @return the kind of the argument at the specified position
-     */
-    CiKind argumentKindAt(int index, boolean architecture);
-
-    /**
-     * Gets the return type of this signature. This method will return a
-     * {@linkplain RiResolvedType resolved} type if possible but without
-     * triggering any class loading or resolution.
-     *
-     * @param accessingClass the context of the type lookup. If accessing class is resolved, its class loader
-     *        is used to retrieve an existing resolved type. This value can be {@code null} if the caller does
-     *        not care for a resolved type.
-     * @return the compiler interface type representing the return type
-     */
-    RiType returnType(RiType accessingClass);
-
-    /**
-     * Gets the return kind of this signature.
-     * @param architectureSpecific When true, the architecture-specific kind used for emitting machine code is returned.
-     *        When false, the kind according to the Java specification is returned.
-     * @return the return kind
-     */
-    CiKind returnKind(boolean architectureSpecific);
-
-    /**
-     * Converts this signature to a string.
-     * @return the signature as a string
-     */
-    String asString();
-
-    /**
-     * Gets the size, in Java slots, of the arguments to this signature.
-     * @param withReceiver {@code true} if to add a slot for a receiver object; {@code false} not to include the receiver
-     * @return the size of the arguments in slots
-     */
-    int argumentSlots(boolean withReceiver);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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;
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * Represents a resolved or unresolved type in the compiler-runtime interface. Types include primitives, objects, {@code void},
- * and arrays thereof.
- */
-public interface RiType {
-
-    /**
-     * Represents each of the several different parts of the runtime representation of
-     * a type which compiled code may need to reference individually. These may or may not be
-     * different objects or data structures, depending on the runtime system.
-     */
-    public enum Representation {
-        /**
-         * The runtime representation of the data structure containing the static fields of this type.
-         */
-        StaticFields,
-
-        /**
-         * The runtime representation of the Java class object of this type.
-         */
-        JavaClass,
-
-        /**
-         * The runtime representation of the "hub" of this type--that is, the closest part of the type
-         * representation which is typically stored in the object header.
-         */
-        ObjectHub,
-
-        /**
-         * The runtime representation of the type information for an object, which is typically used
-         * for subtype tests.
-         */
-        TypeInfo
-    }
-
-    /**
-     * Gets the name of this type in internal form. The following are examples of strings returned by this method:
-     * <pre>
-     *     "Ljava/lang/Object;"
-     *     "I"
-     *     "[[B"
-     * </pre>
-     *
-     * @return the name of this type in internal form
-     */
-    String name();
-
-    /**
-     * For array types, gets the type of the components.
-     * @return the component type of this array type
-     */
-    RiType componentType();
-
-    /**
-     * Gets the type representing an array with elements of this type.
-     * @return a new compiler interface type representing an array of this type
-     */
-    RiType arrayOf();
-
-    /**
-     * Gets the kind of this compiler interface type.
-     * @param architecture When true, the architecture-specific kind used for emitting machine code is returned.
-     *        When false, the kind according to the Java specification is returned.
-     * @return the kind
-     */
-    CiKind kind(boolean architecture);
-
-    /**
-     * Gets the kind used to represent the specified part of this type.
-     * @param r the part of the this type
-     * @return the kind of constants for the specified part of the type
-     */
-    CiKind getRepresentationKind(Representation r);
-
-    RiResolvedType resolve(RiResolvedType accessingClass);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiTypeProfile.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2011, 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;
-
-import java.io.*;
-
-/**
- * This profile object represents the type profile at a specific BCI. The precision of the supplied values may vary,
- * but a runtime that provides this information should be aware that it will be used to guide performance-critical
- * decisions like speculative inlining, etc.
- */
-public final class RiTypeProfile implements Serializable {
-    /**
-     *
-     */
-    private static final long serialVersionUID = -6877016333706838441L;
-
-    private final RiResolvedType[] types;
-    private final double notRecordedProbability;
-    private final double[] probabilities;
-
-    public RiTypeProfile(RiResolvedType[] types, double notRecordedProbability, double[] probabilites) {
-        this.types = types;
-        this.notRecordedProbability = notRecordedProbability;
-        this.probabilities = probabilites;
-    }
-
-    /**
-     * The estimated probabilities of the different receivers. This array needs to have the same length as the array returned by
-     * {@link RiTypeProfile#types}.
-     */
-    public double[] getProbabilities() {
-        return probabilities;
-    }
-
-    /**
-     * Returns the estimated probability of all types that could not be recorded due to profiling limitations.
-     * @return double value >= 0.0 and <= 1.0
-     */
-    public double getNotRecordedProbability() {
-        return notRecordedProbability;
-    }
-
-    /**
-     * A list of receivers for which the runtime has recorded probability information. This array needs to have the same
-     * length as {@link RiTypeProfile#probabilities}.
-     */
-    public RiResolvedType[] getTypes() {
-        return types;
-    }
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/package-info.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, 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.
- */
-/**
- * The runtime-provided part of the bi-directional interface between the compiler and the runtime system of a virtual machine for the
- * instruction set defined in {@link com.oracle.graal.compiler.graphbuilder.Bytecodes}.
- * <p>
- * Unlike the {@link com.oracle.max.cri.ci compiler-provided interface}, the runtime-provided interface is specified largely
- * using interfaces, that must be implemented by classes provided by a specific runtime implementation.
- * <p>
- * {@link com.oracle.max.cri.ri.RiRuntime} encapsulates the main functionality of the runtime for the compiler.
- * <p>
- * Types (i.e., primitives, classes and interfaces}, fields and methods are represented by {@link com.oracle.max.cri.ri.RiType},
- * {@link com.oracle.max.cri.ri.RiField} and {@link com.oracle.max.cri.ri.RiMethod}, respectively, with additional support from
- * {@link com.oracle.max.cri.ri.RiSignature} and {@link com.oracle.max.cri.ri.RiExceptionHandler}. Access to the runtime constant pool
- * is through {@link com.oracle.max.cri.ri.RiConstantPool}.
- */
-package com.oracle.max.cri.ri;
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/util/JavacBug.java	Wed Jun 27 11:48:26 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2011, 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.util;
-
-/**
- * Used to indicate that an otherwise strange looking code pattern is required to work around a bug in javac.
- */
-public @interface JavacBug {
-    /**
-     * A description of the bug. Only really useful if there is no existing entry for the bug in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
-     */
-    String value() default "";
-
-    /**
-     * An identifier in the <a href="http://bugs.sun.com/bugdatabase/">Bug Database</a>.
-     */
-    int id() default 0;
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java	Wed Jun 27 17:35:32 2012 +0200
@@ -26,9 +26,9 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiAddress.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Address.*;
+import com.oracle.graal.api.meta.*;
 
 /**
  * Represents an assembler that allows a client such as the runtime system to
@@ -58,9 +58,9 @@
      */
     protected boolean finished = true;
 
-    protected final CiTarget target;
+    protected final TargetDescription target;
 
-    public CiXirAssembler(CiTarget target) {
+    public CiXirAssembler(TargetDescription target) {
         this.target = target;
     }
 
@@ -153,7 +153,7 @@
      */
     public abstract static class XirOperand {
 
-        public final CiKind kind;
+        public final Kind kind;
 
         /**
          * Unique id in range {@code 0} to {@link #variableCount variableCount - 1}.
@@ -165,7 +165,7 @@
          */
         public final Object name;
 
-        public XirOperand(CiXirAssembler asm, Object name, CiKind kind) {
+        public XirOperand(CiXirAssembler asm, Object name, Kind kind) {
             this.kind = kind;
             this.name = name;
             this.index = asm.variableCount++;
@@ -198,7 +198,7 @@
 
         public final boolean canBeConstant;
 
-        XirParameter(CiXirAssembler asm, String name, CiKind kind, boolean canBeConstant) {
+        XirParameter(CiXirAssembler asm, String name, Kind kind, boolean canBeConstant) {
             super(asm, name, kind);
             this.parameterIndex = asm.parameters.size();
             this.canBeConstant = canBeConstant;
@@ -208,7 +208,7 @@
     }
 
     public static class XirConstantParameter extends XirParameter implements XirConstantOperand {
-        XirConstantParameter(CiXirAssembler asm, String name, CiKind kind) {
+        XirConstantParameter(CiXirAssembler asm, String name, Kind kind) {
             super(asm, name, kind, true);
         }
 
@@ -218,15 +218,15 @@
     }
 
     public static class XirVariableParameter extends XirParameter {
-        XirVariableParameter(CiXirAssembler asm, String name, CiKind kind, boolean canBeConstant) {
+        XirVariableParameter(CiXirAssembler asm, String name, Kind kind, boolean canBeConstant) {
             super(asm, name, kind, canBeConstant);
         }
     }
 
     public static class XirConstant extends XirOperand implements XirConstantOperand {
-        public final CiConstant value;
+        public final Constant value;
 
-        XirConstant(CiXirAssembler asm, CiConstant value) {
+        XirConstant(CiXirAssembler asm, Constant value) {
             super(asm, value, value.kind);
             this.value = value;
         }
@@ -239,16 +239,16 @@
     public static class XirTemp extends XirOperand {
         public final boolean reserve;
 
-        XirTemp(CiXirAssembler asm, String name, CiKind kind, boolean reserve) {
+        XirTemp(CiXirAssembler asm, String name, Kind kind, boolean reserve) {
             super(asm, name, kind);
             this.reserve = reserve;
         }
     }
 
     public static class XirRegister extends XirTemp {
-        public final CiValue register;
+        public final Value register;
 
-        XirRegister(CiXirAssembler asm, String name, CiRegisterValue register, boolean reserve) {
+        XirRegister(CiXirAssembler asm, String name, RegisterValue register, boolean reserve) {
             super(asm, name, register.kind, reserve);
             this.register = register;
         }
@@ -267,7 +267,7 @@
      * @param kind the result kind
      * @return an {@code XirOperand} for the result operand
      */
-    public XirOperand restart(CiKind kind) {
+    public XirOperand restart(Kind kind) {
         reset();
         resultOperand = new XirTemp(this, "result", kind, true);
         allocateResultOperand = true;
@@ -292,16 +292,16 @@
     }
 
     /**
-     * Represents an XIR instruction, characterized by an {@link XirOp operation}, a {@link CiKind kind}, an optional {@link XirOperand result}, a variable number of {@link XirOperand arguments},
+     * Represents an XIR instruction, characterized by an {@link XirOp operation}, a {@link Kind kind}, an optional {@link XirOperand result}, a variable number of {@link XirOperand arguments},
      * and some optional instruction-specific state. The {@link #x}, {@link #y} and {@link #z} methods are convenient ways to access the first, second and third
      * arguments, respectively. Only the {@link XirOp#CallStub} and {@link XirOp#CallRuntime} instructions can have more than three arguments.
      *
      */
     public static final class XirInstruction {
         /**
-         * The {@link CiKind kind} of values the instruction operates on.
+         * The {@link Kind kind} of values the instruction operates on.
          */
-        public final CiKind kind;
+        public final Kind kind;
         /**
          * The {@link XirOp operation}.
          */
@@ -319,11 +319,11 @@
          */
         public final Object extra;
 
-        public XirInstruction(CiKind kind, XirOp op, XirOperand result, XirOperand... arguments) {
+        public XirInstruction(Kind kind, XirOp op, XirOperand result, XirOperand... arguments) {
             this(kind, null, op, result, arguments);
         }
 
-        public XirInstruction(CiKind kind, Object extra, XirOp op, XirOperand result, XirOperand... arguments) {
+        public XirInstruction(Kind kind, Object extra, XirOp op, XirOperand result, XirOperand... arguments) {
             this.extra = extra;
             this.kind = kind;
             this.op = op;
@@ -357,7 +357,7 @@
 
             sb.append(op.name());
 
-            if (kind != CiKind.Void) {
+            if (kind != Kind.Void) {
                 sb.append('$');
                 sb.append(kind.typeChar);
             }
@@ -640,26 +640,26 @@
     }
 
     public void nullCheck(XirOperand pointer) {
-        append(new XirInstruction(CiKind.Object, NullCheck, VOID, pointer));
+        append(new XirInstruction(Kind.Object, NullCheck, VOID, pointer));
     }
 
-    public void pload(CiKind kind, XirOperand result, XirOperand pointer, boolean canTrap) {
+    public void pload(Kind kind, XirOperand result, XirOperand pointer, boolean canTrap) {
         append(new XirInstruction(kind, canTrap, PointerLoad, result, pointer));
     }
 
-    public void pstore(CiKind kind, XirOperand pointer, XirOperand value, boolean canTrap) {
+    public void pstore(Kind kind, XirOperand pointer, XirOperand value, boolean canTrap) {
         append(new XirInstruction(kind, canTrap, PointerStore, null, pointer, value));
     }
 
-    public void pload(CiKind kind, XirOperand result, XirOperand pointer, XirOperand offset, boolean canTrap) {
+    public void pload(Kind kind, XirOperand result, XirOperand pointer, XirOperand offset, boolean canTrap) {
         append(new XirInstruction(kind, new AddressAccessInformation(canTrap), PointerLoadDisp, result, pointer, offset));
     }
 
-    public void pstore(CiKind kind, XirOperand pointer, XirOperand offset, XirOperand value, boolean canTrap) {
+    public void pstore(Kind kind, XirOperand pointer, XirOperand offset, XirOperand value, boolean canTrap) {
         append(new XirInstruction(kind, new AddressAccessInformation(canTrap), PointerStoreDisp, VOID, pointer, offset, value));
     }
 
-    public void pload(CiKind kind, XirOperand result, XirOperand pointer, XirOperand index, int disp, Scale scale,  boolean canTrap) {
+    public void pload(Kind kind, XirOperand result, XirOperand pointer, XirOperand index, int disp, Scale scale,  boolean canTrap) {
         append(new XirInstruction(kind, new AddressAccessInformation(canTrap, disp, scale), PointerLoadDisp, result, pointer, index));
     }
 
@@ -679,24 +679,24 @@
         append(new XirInstruction(target.wordKind, null, RepeatMoveBytes, null, src, dest, length));
     }
 
-    public void pstore(CiKind kind, XirOperand pointer, XirOperand index, XirOperand value, int disp, Scale scale, boolean canTrap) {
+    public void pstore(Kind kind, XirOperand pointer, XirOperand index, XirOperand value, int disp, Scale scale, boolean canTrap) {
         append(new XirInstruction(kind, new AddressAccessInformation(canTrap, disp, scale), PointerStoreDisp, VOID, pointer, index, value));
     }
 
-    public void pcas(CiKind kind, XirOperand result, XirOperand pointer, XirOperand newValue, XirOperand oldValue) {
+    public void pcas(Kind kind, XirOperand result, XirOperand pointer, XirOperand newValue, XirOperand oldValue) {
         append(new XirInstruction(kind, null, PointerCAS, result, pointer, newValue, oldValue));
     }
 
     public void jmp(XirLabel l) {
-        append(new XirInstruction(CiKind.Void, l, Jmp, null));
+        append(new XirInstruction(Kind.Void, l, Jmp, null));
     }
 
     public void decAndJumpNotZero(XirLabel l, XirOperand val) {
-        append(new XirInstruction(CiKind.Void, l, DecAndJumpNotZero, null, val));
+        append(new XirInstruction(Kind.Void, l, DecAndJumpNotZero, null, val));
     }
 
     public void jmpRuntime(Object rt) {
-        append(new XirInstruction(CiKind.Void, rt, Jmp, null));
+        append(new XirInstruction(Kind.Void, rt, Jmp, null));
     }
 
     public void jeq(XirLabel l, XirOperand a, XirOperand b) {
@@ -704,7 +704,7 @@
     }
 
     private void jcc(XirOp op, XirLabel l, XirOperand a, XirOperand b) {
-        append(new XirInstruction(CiKind.Void, l, op, null, a, b));
+        append(new XirInstruction(Kind.Void, l, op, null, a, b));
     }
 
     public void jneq(XirLabel l, XirOperand a, XirOperand b) {
@@ -732,25 +732,25 @@
     }
 
     public void jbset(XirLabel l, XirOperand a, XirOperand b, XirOperand c) {
-        append(new XirInstruction(CiKind.Void, l, Jbset, null, a, b, c));
+        append(new XirInstruction(Kind.Void, l, Jbset, null, a, b, c));
     }
 
     public void bindInline(XirLabel l) {
         assert l.inline;
-        append(new XirInstruction(CiKind.Void, l, Bind, null));
+        append(new XirInstruction(Kind.Void, l, Bind, null));
     }
 
     public void bindOutOfLine(XirLabel l) {
         assert !l.inline;
-        append(new XirInstruction(CiKind.Void, l, Bind, null));
+        append(new XirInstruction(Kind.Void, l, Bind, null));
     }
 
     public void safepoint() {
-        append(new XirInstruction(CiKind.Void, null, Safepoint, null));
+        append(new XirInstruction(Kind.Void, null, Safepoint, null));
     }
 
     public void push(XirOperand value) {
-        append(new XirInstruction(CiKind.Void, Push, VOID, value));
+        append(new XirInstruction(Kind.Void, Push, VOID, value));
     }
 
     public void pop(XirOperand result) {
@@ -760,20 +760,20 @@
     public XirMark mark(Object id, XirMark... references) {
         XirMark mark = new XirMark(id, references);
         marks.add(mark);
-        append(new XirInstruction(CiKind.Void, mark, Mark, null));
+        append(new XirInstruction(Kind.Void, mark, Mark, null));
         return mark;
     }
 
     public void nop(int size) {
-        append(new XirInstruction(CiKind.Void, size, Nop, null));
+        append(new XirInstruction(Kind.Void, size, Nop, null));
     }
 
     public void shouldNotReachHere() {
-        append(new XirInstruction(CiKind.Void, null, ShouldNotReachHere, null));
+        append(new XirInstruction(Kind.Void, null, ShouldNotReachHere, null));
     }
 
     public void shouldNotReachHere(String message) {
-        append(new XirInstruction(CiKind.Void, message, ShouldNotReachHere, null));
+        append(new XirInstruction(Kind.Void, message, ShouldNotReachHere, null));
     }
 
     public void callRuntime(Object rt, XirOperand result, XirOperand... args) {
@@ -781,7 +781,7 @@
     }
 
     public void callRuntime(Object rt, XirOperand result, boolean useInfoAfter, XirOperand... args) {
-        CiKind resultKind = result == null ? CiKind.Void : result.kind;
+        Kind resultKind = result == null ? Kind.Void : result.kind;
         append(new XirInstruction(resultKind, new RuntimeCallInformation(rt, useInfoAfter), CallRuntime, result, args));
     }
 
@@ -795,54 +795,54 @@
     }
 
     /**
-     * Creates an {@link XirVariableParameter variable input parameter}  of given name and {@link CiKind kind}.
+     * Creates an {@link XirVariableParameter variable input parameter}  of given name and {@link Kind kind}.
      * @param name a name for the parameter
      * @param kind the parameter kind
      * @return the  {@link XirVariableParameter}
      */
-    public XirVariableParameter createInputParameter(String name, CiKind kind, boolean canBeConstant) {
+    public XirVariableParameter createInputParameter(String name, Kind kind, boolean canBeConstant) {
         assert !finished;
         return new XirVariableParameter(this, name, kind, canBeConstant);
     }
 
-    public XirVariableParameter createInputParameter(String name, CiKind kind) {
+    public XirVariableParameter createInputParameter(String name, Kind kind) {
         return createInputParameter(name, kind, false);
     }
 
     /**
-     * Creates an {@link XirConstantParameter constant input parameter}  of given name and {@link CiKind kind}.
+     * Creates an {@link XirConstantParameter constant input parameter}  of given name and {@link Kind kind}.
      * @param name a name for the parameter
      * @param kind the parameter kind
      * @return the  {@link XirConstantParameter}
      */
-    public XirConstantParameter createConstantInputParameter(String name, CiKind kind) {
+    public XirConstantParameter createConstantInputParameter(String name, Kind kind) {
         assert !finished;
         return new XirConstantParameter(this, name, kind);
     }
 
-    public XirConstant createConstant(CiConstant constant) {
+    public XirConstant createConstant(Constant constant) {
         assert !finished;
         XirConstant temp = new XirConstant(this, constant);
         constants.add(temp);
         return temp;
     }
 
-    public XirOperand createTemp(String name, CiKind kind) {
+    public XirOperand createTemp(String name, Kind kind) {
         assert !finished;
         XirTemp temp = new XirTemp(this, name, kind, true);
         temps.add(temp);
         return temp;
     }
 
-    public XirOperand createRegister(String name, CiKind kind, CiRegister register) {
+    public XirOperand createRegister(String name, Kind kind, Register register) {
         return createRegister(name, kind, register, false);
     }
 
-    public XirOperand createRegisterTemp(String name, CiKind kind, CiRegister register) {
+    public XirOperand createRegisterTemp(String name, Kind kind, Register register) {
         return createRegister(name, kind, register, true);
     }
 
-    private XirOperand createRegister(String name, CiKind kind, CiRegister register, boolean reserve) {
+    private XirOperand createRegister(String name, Kind kind, Register register, boolean reserve) {
         assert !finished;
         XirRegister fixed = new XirRegister(this, name, register.asValue(kind), reserve);
         temps.add(fixed);
@@ -868,19 +868,19 @@
     }
 
     public XirConstant i(int v) {
-        return createConstant(CiConstant.forInt(v));
+        return createConstant(Constant.forInt(v));
     }
 
-    public XirConstant l(int v) {
-        return createConstant(CiConstant.forLong(v));
+    public XirConstant l(long v) {
+        return createConstant(Constant.forLong(v));
     }
 
     public XirConstant b(boolean v) {
-        return createConstant(CiConstant.forBoolean(v));
+        return createConstant(Constant.forBoolean(v));
     }
 
     public XirConstant o(Object obj) {
-        return createConstant(CiConstant.forObject(obj));
+        return createConstant(Constant.forObject(obj));
     }
 
     public void reserveOutgoingStack(int size) {
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,40 +22,37 @@
  */
 package com.oracle.max.cri.xir;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.Representation;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaType.*;
 
 /**
  * Represents the interface through which the compiler requests the XIR for a given bytecode from the runtime system.
  */
 public interface RiXirGenerator {
 
-    XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, RiMethod method);
+    XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, JavaMethod method);
 
-    XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, RiMethod method, boolean megamorph);
+    XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, JavaMethod method, boolean megamorph);
 
-    XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, RiMethod method);
+    XirSnippet genInvokeSpecial(XirSite site, XirArgument receiver, JavaMethod method);
 
-    XirSnippet genInvokeStatic(XirSite site, RiMethod method);
+    XirSnippet genInvokeStatic(XirSite site, JavaMethod method);
 
     XirSnippet genMonitorEnter(XirSite site, XirArgument receiver, XirArgument lockAddress);
 
     XirSnippet genMonitorExit(XirSite site, XirArgument receiver, XirArgument lockAddress);
 
-    XirSnippet genNewInstance(XirSite site, RiType type);
+    XirSnippet genNewInstance(XirSite site, JavaType type);
 
-    XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType);
+    XirSnippet genNewArray(XirSite site, XirArgument length, Kind elementKind, JavaType componentType, JavaType arrayType);
 
-    XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type);
+    XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, JavaType type);
 
-    XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact);
-
-    XirSnippet genInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, RiType type, RiResolvedType[] hints, boolean hintsExact);
+    XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, ResolvedJavaType type, JavaTypeProfile profile);
 
-    XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, XirArgument trueValue, XirArgument falseValue, RiType type, RiResolvedType[] hints, boolean hintsExact);
+    XirSnippet genInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, ResolvedJavaType type, JavaTypeProfile profile);
 
-    XirSnippet genArrayCopy(XirSite site, XirArgument src, XirArgument srcPos, XirArgument dest, XirArgument destPos, XirArgument length, RiType elementType, boolean inputsSame, boolean inputsDifferent);
+    XirSnippet genMaterializeInstanceOf(XirSite site, XirArgument receiver, XirArgument hub, XirArgument trueValue, XirArgument falseValue, ResolvedJavaType type, JavaTypeProfile profile);
 
     /**
      * Generates code that checks that the {@linkplain Representation#ObjectHub hub} of
@@ -67,7 +64,7 @@
      * </pre>
      * This snippet should only be used when the object is guaranteed not to be null.
      */
-    XirSnippet genTypeBranch(XirSite site, XirArgument thisHub, XirArgument otherHub, RiType type);
+    XirSnippet genTypeBranch(XirSite site, XirArgument thisHub, XirArgument otherHub, JavaType type);
 
     /**
      * Initializes the XIR generator for the given XIR assembler.
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirArgument.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirArgument.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,18 +22,18 @@
  */
 package com.oracle.max.cri.xir;
 
-import com.oracle.max.cri.ci.*;
+import com.oracle.graal.api.meta.*;
 
 /**
  * Represents an argument to an {@link XirSnippet}.
- * Currently, this is a <i>union </i> type; it is either a {@link CiConstant} or an {@code Object}.
+ * Currently, this is a <i>union </i> type; it is either a {@link Constant} or an {@code Object}.
  */
 public final class XirArgument {
 
-    public final CiConstant constant;
+    public final Constant constant;
     public final Object object;
 
-    private XirArgument(CiConstant value) {
+    private XirArgument(Constant value) {
         this.constant = value;
         this.object = null;
     }
@@ -48,15 +48,15 @@
     }
 
     public static XirArgument forInt(int x) {
-        return new XirArgument(CiConstant.forInt(x));
+        return new XirArgument(Constant.forInt(x));
     }
 
     public static XirArgument forLong(long x) {
-        return new XirArgument(CiConstant.forLong(x));
+        return new XirArgument(Constant.forLong(x));
     }
 
     public static XirArgument forObject(Object o) {
-        return new XirArgument(CiConstant.forObject(o));
+        return new XirArgument(Constant.forObject(o));
     }
 
     @Override
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirSite.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirSite.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.cri.xir;
 
+import com.oracle.graal.api.code.*;
+
 /**
  * Encapsulates the notion of a site where XIR can be supplied. It is supplied to the {@link RiXirGenerator} by the
  * compiler for each place where XIR can be generated. This interface allows a number of queries, including the
@@ -65,4 +67,10 @@
      * @return {@code true} if an array store check is required
      */
     boolean requiresArrayStoreCheck();
+
+    /**
+     * The object for recording speculations made during compilation.
+     * May be null.
+     */
+    Assumptions assumptions();
 }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirSnippet.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirSnippet.java	Wed Jun 27 17:35:32 2012 +0200
@@ -24,8 +24,8 @@
 
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.*;
+import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.max.cri.xir.CiXirAssembler.*;
 
 /**
@@ -58,7 +58,7 @@
     }
 
     private static boolean assertArgumentCorrect(XirParameter param, XirArgument arg) {
-        if (param.kind == CiKind.Illegal || param.kind == CiKind.Void) {
+        if (param.kind == Kind.Illegal || param.kind == Kind.Void) {
             if (arg != null) {
                 return false;
             }
--- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseProfilingInfo.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseProfilingInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,28 +22,34 @@
  */
 package com.oracle.max.criutils;
 
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 
 
 /**
  * Dummy profiling information in case that a method was not executed frequently enough so that
  * no profiling information does exist yet, or in case that the profiling information should not be used.
  */
-public final class BaseProfilingInfo implements RiProfilingInfo {
-    private static final RiProfilingInfo[] NO_PROFILING_INFO = new RiProfilingInfo[] {
-        new BaseProfilingInfo(RiExceptionSeen.TRUE),
-        new BaseProfilingInfo(RiExceptionSeen.FALSE),
-        new BaseProfilingInfo(RiExceptionSeen.NOT_SUPPORTED)
+public final class BaseProfilingInfo implements ProfilingInfo {
+    private static final ProfilingInfo[] NO_PROFILING_INFO = new ProfilingInfo[] {
+        new BaseProfilingInfo(ExceptionSeen.TRUE),
+        new BaseProfilingInfo(ExceptionSeen.FALSE),
+        new BaseProfilingInfo(ExceptionSeen.NOT_SUPPORTED)
     };
 
-    private final RiExceptionSeen exceptionSeen;
+    private final ExceptionSeen exceptionSeen;
 
-    BaseProfilingInfo(RiExceptionSeen exceptionSeen) {
+    BaseProfilingInfo(ExceptionSeen exceptionSeen) {
         this.exceptionSeen = exceptionSeen;
     }
 
     @Override
-    public RiTypeProfile getTypeProfile(int bci) {
+    public int codeSize() {
+        return 0;
+    }
+
+    @Override
+    public JavaTypeProfile getTypeProfile(int bci) {
         return null;
     }
 
@@ -58,7 +64,7 @@
     }
 
     @Override
-    public RiExceptionSeen getExceptionSeen(int bci) {
+    public ExceptionSeen getExceptionSeen(int bci) {
         return exceptionSeen;
     }
 
@@ -67,12 +73,17 @@
         return -1;
     }
 
-    public static RiProfilingInfo get(RiExceptionSeen exceptionSeen) {
+    public static ProfilingInfo get(ExceptionSeen exceptionSeen) {
         return NO_PROFILING_INFO[exceptionSeen.ordinal()];
     }
 
     @Override
-    public int getDeoptimizationCount(RiDeoptReason reason) {
+    public int getDeoptimizationCount(DeoptimizationReason reason) {
         return 0;
     }
+
+    @Override
+    public String toString() {
+        return "BaseProfilingInfo<" + CodeUtil.profileToString(this, null, "; ") + ">";
+    }
 }
--- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseUnresolvedField.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseUnresolvedField.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,19 +22,19 @@
  */
 package com.oracle.max.criutils;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 
 /**
- * A implementation of {@link RiField} for an unresolved field.
+ * A implementation of {@link JavaField} for an unresolved field.
  */
-public class BaseUnresolvedField implements RiField {
+public class BaseUnresolvedField implements JavaField {
 
     public final String name;
-    public final RiType holder;
-    public final RiType type;
+    public final JavaType holder;
+    public final JavaType type;
 
-    public BaseUnresolvedField(RiType holder, String name, RiType type) {
+    public BaseUnresolvedField(JavaType holder, String name, JavaType type) {
         this.name = name;
         this.type = type;
         this.holder = holder;
@@ -44,15 +44,15 @@
         return name;
     }
 
-    public RiType type() {
+    public JavaType type() {
         return type;
     }
 
-    public CiKind kind(boolean architecture) {
-        return type.kind(architecture);
+    public Kind kind() {
+        return type.kind();
     }
 
-    public RiType holder() {
+    public JavaType holder() {
         return holder;
     }
 
@@ -71,6 +71,6 @@
      */
     @Override
     public String toString() {
-        return CiUtil.format("%H.%n [unresolved]", this);
+        return CodeUtil.format("%H.%n [unresolved]", this);
     }
 }
--- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseUnresolvedMethod.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseUnresolvedMethod.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,19 +22,19 @@
  */
 package com.oracle.max.criutils;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 
 /**
- * A implementation of {@link RiMethod} for an unresolved method.
+ * A implementation of {@link JavaMethod} for an unresolved method.
  */
-public class BaseUnresolvedMethod implements RiMethod {
+public class BaseUnresolvedMethod implements JavaMethod {
 
     public final String name;
-    public final RiType holder;
-    public final RiSignature signature;
+    public final JavaType holder;
+    public final Signature signature;
 
-    public BaseUnresolvedMethod(RiType holder, String name, RiSignature signature) {
+    public BaseUnresolvedMethod(JavaType holder, String name, Signature signature) {
         this.name = name;
         this.holder = holder;
         this.signature = signature;
@@ -44,11 +44,11 @@
         return name;
     }
 
-    public RiType holder() {
+    public JavaType holder() {
         return holder;
     }
 
-    public RiSignature signature() {
+    public Signature signature() {
         return signature;
     }
 
@@ -64,6 +64,6 @@
 
     @Override
     public String toString() {
-        return CiUtil.format("%H.%n(%p) [unresolved]", this);
+        return CodeUtil.format("%H.%n(%p) [unresolved]", this);
     }
 }
--- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/CompilationPrinter.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/CompilationPrinter.java	Wed Jun 27 17:35:32 2012 +0200
@@ -22,13 +22,13 @@
  */
 package com.oracle.max.criutils;
 
-import static com.oracle.max.cri.ci.CiValueUtil.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
 
 import java.io.*;
 import java.util.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 
 /**
  * Utility for printing compilation related data structures at various compilation phases.
@@ -95,10 +95,10 @@
      *
      * @param method the method for which a timestamp will be printed
      */
-    public void printCompilation(RiMethod method) {
+    public void printCompilation(JavaMethod method) {
         begin("compilation");
-        out.print("name \" ").print(CiUtil.format("%H::%n", method)).println('"');
-        out.print("method \"").print(CiUtil.format("%f %r %H.%n(%p)", method)).println('"');
+        out.print("name \" ").print(CodeUtil.format("%H::%n", method)).println('"');
+        out.print("method \"").print(CodeUtil.format("%f %r %H.%n(%p)", method)).println('"');
         out.print("date ").println(System.currentTimeMillis());
         end("compilation");
     }
@@ -106,7 +106,7 @@
     /**
      * Formats a given {@linkplain FrameState JVM frame state} as a multi line string.
      */
-    protected String debugInfoToString(CiCodePos codePos, CiBitMap registerRefMap, CiBitMap frameRefMap, CiArchitecture arch) {
+    protected String debugInfoToString(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap, Architecture arch) {
         StringBuilder sb = new StringBuilder();
 
         if (registerRefMap != null) {
@@ -126,13 +126,13 @@
         }
 
         if (codePos != null) {
-            CiCodePos curCodePos = codePos;
-            List<CiVirtualObject> virtualObjects = new ArrayList<>();
+            BytecodePosition curCodePos = codePos;
+            List<VirtualObject> virtualObjects = new ArrayList<>();
             do {
-                sb.append(CiUtil.toLocation(curCodePos.method, curCodePos.bci));
+                sb.append(CodeUtil.toLocation(curCodePos.getMethod(), curCodePos.getBCI()));
                 sb.append('\n');
-                if (curCodePos instanceof CiFrame) {
-                    CiFrame frame = (CiFrame) curCodePos;
+                if (curCodePos instanceof BytecodeFrame) {
+                    BytecodeFrame frame = (BytecodeFrame) curCodePos;
                     if (frame.numStack > 0) {
                         sb.append("stack: ");
                         for (int i = 0; i < frame.numStack; i++) {
@@ -154,11 +154,11 @@
                     }
 
                 }
-                curCodePos = curCodePos.caller;
+                curCodePos = curCodePos.getCaller();
             } while (curCodePos != null);
 
             for (int i = 0; i < virtualObjects.size(); i++) {
-                CiVirtualObject obj = virtualObjects.get(i);
+                VirtualObject obj = virtualObjects.get(i);
                 sb.append(obj).append(" ").append(obj.type().name()).append(" ");
                 for (int j = 0; j < obj.values().length; j++) {
                     sb.append(valueToString(obj.values()[j], virtualObjects)).append(' ');
@@ -170,7 +170,7 @@
         return sb.toString();
     }
 
-    protected String valueToString(CiValue value, List<CiVirtualObject> virtualObjects) {
+    protected String valueToString(Value value, List<VirtualObject> virtualObjects) {
         if (value == null) {
             return "-";
         }
--- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/HexCodeFile.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/HexCodeFile.java	Wed Jun 27 17:35:32 2012 +0200
@@ -27,8 +27,8 @@
 import java.util.*;
 import java.util.regex.*;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.*;
 
 
 /**
@@ -84,7 +84,7 @@
  */
 public class HexCodeFile {
 
-    public static final String NEW_LINE = CiUtil.NEW_LINE;
+    public static final String NEW_LINE = CodeUtil.NEW_LINE;
     public static final String SECTION_DELIM = " <||@";
     public static final Pattern SECTION = Pattern.compile("(\\S+)\\s+(.*)", Pattern.DOTALL);
     public static final Pattern COMMENT = Pattern.compile("(\\d+)\\s+(.*)", Pattern.DOTALL);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/JniMangle.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2007, 2011, 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.criutils;
+
+import com.oracle.graal.api.meta.*;
+
+/**
+ * A utility for mangling Java method name and signatures into C function names.
+ *
+ * @see "http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp615"
+ */
+public final class JniMangle {
+
+    private JniMangle() {
+    }
+
+    /**
+     * Mangles a given string such that it can be represented as (part of) a valid C function name.
+     */
+    private static String mangle(String name) {
+        final StringBuilder mangledName = new StringBuilder(100);
+        final int length = name.length();
+        for (int i = 0; i < length; i++) {
+            final char ch = name.charAt(i);
+            if (isAlphaNumeric(ch)) {
+                mangledName.append(ch);
+            } else if (ch == '_') {
+                mangledName.append("_1");
+            } else if (ch == '.') {
+                mangledName.append("_");
+            } else if (ch == ';') {
+                mangledName.append("_2");
+            } else if (ch == '[') {
+                mangledName.append("_3");
+            } else {
+                mangledName.append(String.format("%04x", (int) ch));
+            }
+        }
+        return mangledName.toString();
+    }
+
+    /**
+     * The delimiter in the string returned by {@link #mangleMethod(TypeDescriptor, String, SignatureDescriptor, boolean)} separating
+     * the short mangled form from the suffix to be added to obtain the long mangled form.
+     */
+    public static final char LONG_NAME_DELIMITER = ' ';
+
+    /**
+     * Mangles a Java method to the symbol(s) to be used when binding it to a native function.
+     * If {@code signature} is {@code null}, then a non-qualified symbol is returned.
+     * Otherwise, a qualified symbol is returned. A qualified symbol has its non-qualified
+     * prefix separated from its qualifying suffix by {@link #LONG_NAME_DELIMITER} if
+     * {@code splitSuffix} is {@code true}.
+     *
+     * @param declaringClass a fully qualified class descriptor
+     * @param name a Java method name (not checked here for validity)
+     * @param signature if non-null, a method signature to include in the mangled name
+     * @param splitSuffix determines if {@link #LONG_NAME_DELIMITER} should be used as described above
+     * @return the symbol for the C function as described above
+     */
+    public static String mangleMethod(ResolvedJavaType declaringClass, String name, Signature signature, boolean splitSuffix) {
+        final StringBuilder result = new StringBuilder(100);
+        final String declaringClassName = MetaUtil.toJavaName(declaringClass);
+        result.append("Java_").append(mangle(declaringClassName)).append('_').append(mangle(name));
+        if (signature != null) {
+            if (splitSuffix) {
+                result.append(LONG_NAME_DELIMITER);
+            }
+            result.append("__");
+            final String sig = signature.asString();
+            final String parametersSignature = sig.substring(1, sig.lastIndexOf(')')).replace('/', '.').replace('$', '.');
+            result.append(mangle(parametersSignature));
+        }
+        return result.toString();
+    }
+
+    private static boolean isAlphaNumeric(char ch) {
+        return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9');
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/SnapshotProfilingInfo.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,176 @@
+/*
+ * 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.criutils;
+
+import java.io.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+/**
+ * A profiling info snapshot that can be {@linkplain #save(File, File) saved} to
+ * and {@linkplain #load(File, CodeCacheProvider) loaded} from a file.
+ */
+public class SnapshotProfilingInfo implements ProfilingInfo, Serializable {
+
+    private static final long serialVersionUID = -5837615128782960391L;
+    private final double[] branchTaken;
+    private final double[][] switches;
+    private final JavaTypeProfile[] typeProfiles;
+    private final ExceptionSeen[] exceptions;
+    private final int[] executions;
+    private final int[] deopts;
+
+    public SnapshotProfilingInfo(ProfilingInfo other) {
+        int codeSize = other.codeSize();
+        branchTaken = new double[codeSize];
+        switches = new double[codeSize][];
+        typeProfiles = new JavaTypeProfile[codeSize];
+        exceptions = new ExceptionSeen[codeSize];
+        executions = new int[codeSize];
+        deopts = new int[DeoptimizationReason.values().length];
+
+        for (int bci = 0; bci < codeSize; bci++) {
+            executions[bci] = other.getExecutionCount(bci);
+            exceptions[bci] = other.getExceptionSeen(bci);
+            branchTaken[bci] = other.getBranchTakenProbability(bci);
+            switches[bci] = other.getSwitchProbabilities(bci);
+            typeProfiles[bci] = other.getTypeProfile(bci);
+        }
+        for (DeoptimizationReason reason: DeoptimizationReason.values()) {
+            deopts[reason.ordinal()] = other.getDeoptimizationCount(reason);
+        }
+    }
+
+    @Override
+    public int codeSize() {
+        return branchTaken.length;
+    }
+
+    public double getBranchTakenProbability(int bci) {
+        return bci < branchTaken.length ? branchTaken[bci] : -1D;
+    }
+    public double[] getSwitchProbabilities(int bci) {
+        return bci < switches.length ? switches[bci] : null;
+    }
+    public JavaTypeProfile getTypeProfile(int bci) {
+        return bci < typeProfiles.length ? typeProfiles[bci] : null;
+    }
+    public ExceptionSeen getExceptionSeen(int bci) {
+        return bci < exceptions.length ? exceptions[bci] : ExceptionSeen.NOT_SUPPORTED;
+    }
+    public int getExecutionCount(int bci) {
+        return bci < executions.length ? executions[bci] : -1;
+    }
+    public int getDeoptimizationCount(DeoptimizationReason reason) {
+        return deopts[reason.ordinal()];
+    }
+
+    @Override
+    public String toString() {
+        return CodeUtil.profileToString(this, null, "; ");
+    }
+
+    /**
+     * Deserializes a profile snapshot from a file.
+     *
+     * @param file a file created by {@link #save(File, File)}
+     * @param runtime the runtime used to resolve {@link ResolvedJavaType}s during deserialization
+     * @return
+     * @throws ClassNotFoundException
+     * @throws IOException
+     */
+    public static SnapshotProfilingInfo load(File file, CodeCacheProvider runtime) throws ClassNotFoundException, IOException {
+        SnapshotProfilingInfo.SnapshotObjectInputStream ois = new SnapshotObjectInputStream(new BufferedInputStream(new FileInputStream(file), (int) file.length()), runtime);
+        try {
+            return (SnapshotProfilingInfo) ois.readObject();
+        } finally {
+            ois.close();
+        }
+    }
+
+    /**
+     * Serializes this snapshot to a file.
+     *
+     * @param file the file to which this snapshot is serialized
+     * @param txtFile
+     * @throws IOException
+     */
+    public void save(File file, File txtFile) throws IOException {
+        SnapshotProfilingInfo.SnapshotObjectOutputStream oos = new SnapshotObjectOutputStream(new FileOutputStream(file));
+        try {
+            oos.writeObject(this);
+        } finally {
+            oos.close();
+        }
+        if (txtFile != null) {
+            PrintStream out = new PrintStream(txtFile);
+            try {
+                out.println(CodeUtil.profileToString(this, null, CodeUtil.NEW_LINE));
+            } finally {
+                out.close();
+            }
+        }
+    }
+
+    static class RiResolvedTypePlaceholder implements Serializable {
+        private static final long serialVersionUID = -5149982457010023916L;
+        final Class javaMirror;
+        public RiResolvedTypePlaceholder(Class javaMirror) {
+            this.javaMirror = javaMirror;
+        }
+    }
+
+    static class SnapshotObjectOutputStream extends ObjectOutputStream {
+        public SnapshotObjectOutputStream(OutputStream out) throws IOException {
+            super(out);
+            enableReplaceObject(true);
+        }
+
+        @Override
+        protected Object replaceObject(Object obj) throws IOException {
+            if (obj instanceof ResolvedJavaType) {
+                return new RiResolvedTypePlaceholder(((ResolvedJavaType) obj).toJava());
+            }
+            return obj;
+        }
+    }
+
+    static class SnapshotObjectInputStream extends ObjectInputStream {
+        private final CodeCacheProvider runtime;
+        public SnapshotObjectInputStream(InputStream in, CodeCacheProvider runtime) throws IOException {
+            super(in);
+            enableResolveObject(true);
+            this.runtime = runtime;
+        }
+
+        @Override
+        protected Object resolveObject(Object obj) throws IOException {
+            if (obj instanceof SnapshotProfilingInfo.RiResolvedTypePlaceholder) {
+                ResolvedJavaType type = runtime.getResolvedJavaType(((SnapshotProfilingInfo.RiResolvedTypePlaceholder) obj).javaMirror);
+                return type;
+            }
+            return obj;
+        }
+    }
+}
--- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/TTY.java	Wed Jun 27 11:48:26 2012 +0200
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/TTY.java	Wed Jun 27 17:35:32 2012 +0200
@@ -89,12 +89,10 @@
         }
     }
 
-    public static final String MAX_TTY_LOG_FILE_PROPERTY = "max.tty.file";
-
     public static PrintStream cachedOut;
 
-    public static void initialize() {
-        cachedOut = System.out;
+    public static void initialize(PrintStream ps) {
+        cachedOut = ps;
     }
 
     private static LogStream createLog() {
@@ -102,16 +100,7 @@
             // In case initialize() was not called.
             cachedOut = System.out;
         }
-        PrintStream newOut = cachedOut;
-        String value = System.getProperty(MAX_TTY_LOG_FILE_PROPERTY);
-        if (value != null) {
-            try {
-                newOut = new PrintStream(new FileOutputStream(value));
-            } catch (FileNotFoundException e) {
-                System.err.println("Could not open log file " + value + ": " + e);
-            }
-        }
-        return new LogStream(newOut);
+        return new LogStream(cachedOut);
     }
 
     private static final ThreadLocal<LogStream> out = new ThreadLocal<LogStream>() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/TypeCheckHints.java	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,111 @@
+/*
+ * 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.criutils;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.JavaTypeProfile.*;
+
+/**
+ * Utility for deriving hint types for a type check instruction (e.g. checkcast or instanceof)
+ * based on the target type of the check and any profiling information available for the instruction.
+ */
+public class TypeCheckHints {
+
+    private static final ResolvedJavaType[] NO_TYPES = {};
+
+    /**
+     * If true, then {@link #types} contains the only possible type that could pass the type check
+     * because the target of the type check is a final class or has been speculated to be a final class.
+     */
+    public final boolean exact;
+
+    /**
+     * The most likely types that the type check instruction will see.
+     */
+    public final ResolvedJavaType[] types;
+
+    /**
+     * Derives hint information for use when generating the code for a type check instruction.
+     *
+     * @param type the target type of the type check
+     * @param profile the profiling information available for the instruction (if any)
+     * @param assumptions the object in which speculations are recorded. This is null if speculations are not supported.
+     * @param minHintHitProbability if the probability that the type check will hit one the profiled types (up to
+     *            {@code maxHints}) is below this value, then {@link #types} will be null
+     * @param maxHints the maximum length of {@link #types}
+     */
+    public TypeCheckHints(ResolvedJavaType type, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) {
+        if (type != null && isFinalClass(type)) {
+            types = new ResolvedJavaType[] {type};
+            exact = true;
+        } else {
+            ResolvedJavaType uniqueSubtype = type == null ? null : type.uniqueConcreteSubtype();
+            if (uniqueSubtype != null) {
+                types = new ResolvedJavaType[] {uniqueSubtype};
+                if (assumptions != null) {
+                    assumptions.recordConcreteSubtype(type, uniqueSubtype);
+                    exact = true;
+                } else {
+                    exact = false;
+                }
+            } else {
+                exact = false;
+                ResolvedJavaType[] hintTypes = NO_TYPES;
+                JavaTypeProfile typeProfile = profile;
+                if (typeProfile != null) {
+                    double notRecordedTypes = typeProfile.getNotRecordedProbability();
+                    ProfiledType[] ptypes = typeProfile.getTypes();
+                    if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) {
+                        hintTypes = new ResolvedJavaType[ptypes.length];
+                        int hintCount = 0;
+                        double totalHintProbability = 0.0d;
+                        for (ProfiledType ptype : ptypes) {
+                            ResolvedJavaType hint = ptype.type;
+                            if (type != null && hint.isSubtypeOf(type)) {
+                                hintTypes[hintCount++] = hint;
+                                totalHintProbability += ptype.probability;
+                            }
+                        }
+                        if (totalHintProbability >= minHintHitProbability) {
+                            if (hintTypes.length != hintCount || hintCount > maxHints) {
+                                hintTypes = Arrays.copyOf(hintTypes, Math.min(maxHints, hintCount));
+                            }
+                        } else {
+                            hintTypes = NO_TYPES;
+                        }
+
+                    }
+                }
+                this.types = hintTypes;
+            }
+        }
+    }
+
+    public static boolean isFinalClass(ResolvedJavaType type) {
+        return Modifier.isFinal(type.accessFlags()) || (type.isArrayClass() && Modifier.isFinal(type.componentType().accessFlags()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/overview.html	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+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.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+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.
+-->
+
+</head>
+<body bgcolor="white">
+
+<body>
+
+<a href="modules.svg" title="Click to enlarge"><img src="modules.svg" width="400"/></a>
+<p>
+This document is the unified Javadoc for the Graal code base.
+The module dependency graph is shown above.
+Each node in the diagram is a link to the standalone Javadoc for the denoted module.
+
+</body>
+</html>
--- a/hotspot/.cproject	Wed Jun 27 11:48:26 2012 +0200
+++ b/hotspot/.cproject	Wed Jun 27 17:35:32 2012 +0200
@@ -20,7 +20,7 @@
 					<folderInfo id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577" name="/" resourcePath="">
 						<toolChain id="cdt.managedbuild.toolchain.gnu.base.1866612258" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
 							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.2075405295" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
-							<builder arguments="${workspace_loc:/hotspot}/../mxtool/mx build" autoBuildTarget="ide-build-target" buildPath="${workspace_loc:/hotspot}/.." cleanBuildTarget="clean" command="bash" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="false" id="cdt.managedbuild.target.gnu.builder.base.81453037" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelizationNumber="1" superClass="cdt.managedbuild.target.gnu.builder.base">
+							<builder arguments="${workspace_loc:/hotspot}/../mxtool/mx build" autoBuildTarget="ide-build-target" buildPath="${workspace_loc:/hotspot}/.." cleanBuildTarget="clean" command="bash" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="false" id="cdt.managedbuild.target.gnu.builder.base.81453037" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base">
 								<outputEntries>
 									<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
 								</outputEntries>
@@ -43,6 +43,7 @@
 									<listOptionValue builtIn="false" value="TARGET_OS_ARCH_linux_x86=1"/>
 									<listOptionValue builtIn="false" value="TARGET_ARCH_MODEL_x86_64=1"/>
 									<listOptionValue builtIn="false" value="GRAAL=1"/>
+									<listOptionValue builtIn="false" value="COMPILER2=1"/>
 								</option>
 								<option id="gnu.cpp.compiler.option.preprocessor.undef.2137486146" name="Undefined symbols (-U)" superClass="gnu.cpp.compiler.option.preprocessor.undef"/>
 								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
@@ -71,164 +72,13 @@
 							</tool>
 						</toolChain>
 					</folderInfo>
-					<sourceEntries>
-						<entry excluding="cpu/vm/templateTable_x86_32.cpp|cpu/vm/templateInterpreter_x86_32.cpp|cpu/vm/stubRoutines_x86_32.cpp|cpu/vm/stubGenerator_x86_32.cpp|cpu/vm/sharedRuntime_x86_32.cpp|cpu/vm/jniFastGetField_x86_32.cpp|cpu/vm/interpreterRT_x86_32.cpp|cpu/vm/interpreter_x86_32.cpp|cpu/vm/interp_masm_x86_32.cpp|cpu/vm/vtableStubs_x86_32.cpp|vm/opto" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
-			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
-			<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-		</cconfiguration>
-		<cconfiguration id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001" moduleId="org.eclipse.cdt.core.settings" name="product">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="hotspot" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001" name="product" parent="org.eclipse.cdt.build.core.emptycfg">
-					<folderInfo id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001." name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.base.1094071149" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
-							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1366986655" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
-							<builder arguments="${workspace_loc:/hotspot}/../mxtool/mx build" autoBuildTarget="product" buildPath="${workspace_loc:/hotspot}/.." cleanBuildTarget="clean" command="bash" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="false" id="cdt.managedbuild.target.gnu.builder.base.831826345" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelizationNumber="1" superClass="cdt.managedbuild.target.gnu.builder.base">
-								<outputEntries>
-									<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
-								</outputEntries>
-							</builder>
-							<tool id="cdt.managedbuild.tool.gnu.archiver.base.1222329151" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.235939569" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
-								<option id="gnu.cpp.compiler.option.include.paths.2124509243" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths"/>
-								<option id="gnu.cpp.compiler.option.preprocessor.def.77729074" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="_LP64=1"/>
-									<listOptionValue builtIn="false" value="COMPILER1=1"/>
-									<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
-									<listOptionValue builtIn="false" value="ASSERT=1"/>
-									<listOptionValue builtIn="false" value="_REENTRANT=1"/>
-									<listOptionValue builtIn="false" value="DEBUG=1"/>
-									<listOptionValue builtIn="false" value="AMD64=1"/>
-									<listOptionValue builtIn="false" value="LINUX=1"/>
-									<listOptionValue builtIn="false" value="TARGET_ARCH_x86=1"/>
-									<listOptionValue builtIn="false" value="TARGET_COMPILER_gcc=1"/>
-									<listOptionValue builtIn="false" value="TARGET_OS_FAMILY_linux=1"/>
-									<listOptionValue builtIn="false" value="TARGET_OS_ARCH_linux_x86=1"/>
-									<listOptionValue builtIn="false" value="TARGET_ARCH_MODEL_x86_64=1"/>
-									<listOptionValue builtIn="false" value="GRAAL=1"/>
-								</option>
-								<option id="gnu.cpp.compiler.option.preprocessor.undef.1117494475" name="Undefined symbols (-U)" superClass="gnu.cpp.compiler.option.preprocessor.undef"/>
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1168038805" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.2110455043" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
-								<option id="gnu.c.compiler.option.preprocessor.def.symbols.1595255663" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="_LP64=1"/>
-									<listOptionValue builtIn="false" value="COMPILER1=1"/>
-									<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
-									<listOptionValue builtIn="false" value="ASSERT=1"/>
-									<listOptionValue builtIn="false" value="_REENTRANT=1"/>
-									<listOptionValue builtIn="false" value="DEBUG=1"/>
-									<listOptionValue builtIn="false" value="AMD64=1"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1261515555" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1541095" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.578894321" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.721919005" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.assembler.base.1944481961" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.284566020" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
+					<fileInfo id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.426128354" name="addnode.cpp" rcbsApplicability="disable" resourcePath="vm/opto/addnode.cpp" toolsToInvoke="cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057.211119144">
+						<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057.211119144" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057">
+							<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.202578082" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+						</tool>
+					</fileInfo>
 					<sourceEntries>
-						<entry excluding="cpu/vm/templateTable_x86_32.cpp|cpu/vm/templateInterpreter_x86_32.cpp|cpu/vm/stubRoutines_x86_32.cpp|cpu/vm/stubGenerator_x86_32.cpp|cpu/vm/sharedRuntime_x86_32.cpp|cpu/vm/jniFastGetField_x86_32.cpp|cpu/vm/interpreterRT_x86_32.cpp|cpu/vm/interpreter_x86_32.cpp|cpu/vm/interp_masm_x86_32.cpp|cpu/vm/vtableStubs_x86_32.cpp|vm/opto" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
-					</sourceEntries>
-				</configuration>
-			</storageModule>
-			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-			<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
-			<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
-			<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-		</cconfiguration>
-		<cconfiguration id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001.200970051">
-			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001.200970051" moduleId="org.eclipse.cdt.core.settings" name="debug">
-				<externalSettings/>
-				<extensions>
-					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-					<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-				</extensions>
-			</storageModule>
-			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="hotspot" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001.200970051" name="debug" parent="org.eclipse.cdt.build.core.emptycfg">
-					<folderInfo id="cdt.managedbuild.toolchain.gnu.solaris.base.945602881.1753195001.200970051." name="/" resourcePath="">
-						<toolChain id="cdt.managedbuild.toolchain.gnu.base.85322399" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
-							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.369211282" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
-							<builder arguments="${workspace_loc:/hotspot}/../mxtool/mx build" autoBuildTarget="debug" buildPath="${workspace_loc:/hotspot}/.." cleanBuildTarget="clean" command="bash" enableAutoBuild="true" enableCleanBuild="false" enabledIncrementalBuild="false" id="cdt.managedbuild.target.gnu.builder.base.944057404" incrementalBuildTarget="jvmg1" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelizationNumber="1" superClass="cdt.managedbuild.target.gnu.builder.base">
-								<outputEntries>
-									<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="outputPath" name=""/>
-								</outputEntries>
-							</builder>
-							<tool id="cdt.managedbuild.tool.gnu.archiver.base.1620577294" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1333497405" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
-								<option id="gnu.cpp.compiler.option.include.paths.323539230" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths"/>
-								<option id="gnu.cpp.compiler.option.preprocessor.def.150327888" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="_LP64=1"/>
-									<listOptionValue builtIn="false" value="COMPILER1=1"/>
-									<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
-									<listOptionValue builtIn="false" value="ASSERT=1"/>
-									<listOptionValue builtIn="false" value="_REENTRANT=1"/>
-									<listOptionValue builtIn="false" value="DEBUG=1"/>
-									<listOptionValue builtIn="false" value="AMD64=1"/>
-									<listOptionValue builtIn="false" value="LINUX=1"/>
-									<listOptionValue builtIn="false" value="TARGET_ARCH_x86=1"/>
-									<listOptionValue builtIn="false" value="TARGET_COMPILER_gcc=1"/>
-									<listOptionValue builtIn="false" value="TARGET_OS_FAMILY_linux=1"/>
-									<listOptionValue builtIn="false" value="TARGET_OS_ARCH_linux_x86=1"/>
-									<listOptionValue builtIn="false" value="TARGET_ARCH_MODEL_x86_64=1"/>
-									<listOptionValue builtIn="false" value="GRAAL=1"/>
-								</option>
-								<option id="gnu.cpp.compiler.option.preprocessor.undef.1178030129" name="Undefined symbols (-U)" superClass="gnu.cpp.compiler.option.preprocessor.undef"/>
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1729844380" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1253851174" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
-								<option id="gnu.c.compiler.option.preprocessor.def.symbols.1067842050" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
-									<listOptionValue builtIn="false" value="_LP64=1"/>
-									<listOptionValue builtIn="false" value="COMPILER1=1"/>
-									<listOptionValue builtIn="false" value="VM_LITTLE_ENDIAN=1"/>
-									<listOptionValue builtIn="false" value="ASSERT=1"/>
-									<listOptionValue builtIn="false" value="_REENTRANT=1"/>
-									<listOptionValue builtIn="false" value="DEBUG=1"/>
-									<listOptionValue builtIn="false" value="AMD64=1"/>
-								</option>
-								<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2133987017" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1778246187" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
-							<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1574482902" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
-								<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.15191548" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-									<additionalInput kind="additionalinput" paths="$(LIBS)"/>
-								</inputType>
-							</tool>
-							<tool id="cdt.managedbuild.tool.gnu.assembler.base.187448222" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
-								<inputType id="cdt.managedbuild.tool.gnu.assembler.input.181490524" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-							</tool>
-						</toolChain>
-					</folderInfo>
-					<sourceEntries>
-						<entry excluding="cpu/vm/templateTable_x86_32.cpp|cpu/vm/templateInterpreter_x86_32.cpp|cpu/vm/stubRoutines_x86_32.cpp|cpu/vm/stubGenerator_x86_32.cpp|cpu/vm/sharedRuntime_x86_32.cpp|cpu/vm/jniFastGetField_x86_32.cpp|cpu/vm/interpreterRT_x86_32.cpp|cpu/vm/interpreter_x86_32.cpp|cpu/vm/interp_masm_x86_32.cpp|cpu/vm/vtableStubs_x86_32.cpp|vm/opto" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+						<entry excluding="cpu/vm/templateTable_x86_32.cpp|cpu/vm/templateInterpreter_x86_32.cpp|cpu/vm/stubRoutines_x86_32.cpp|cpu/vm/stubGenerator_x86_32.cpp|cpu/vm/sharedRuntime_x86_32.cpp|cpu/vm/jniFastGetField_x86_32.cpp|cpu/vm/interpreterRT_x86_32.cpp|cpu/vm/interpreter_x86_32.cpp|cpu/vm/interp_masm_x86_32.cpp|cpu/vm/vtableStubs_x86_32.cpp" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
 					</sourceEntries>
 				</configuration>
 			</storageModule>
@@ -241,10 +91,13 @@
 	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
 		<project id="hotspot.null.1712822257" name="hotspot"/>
 	</storageModule>
-	<storageModule moduleId="refreshScope" versionNumber="1">
-		<resource resourceType="PROJECT" workspacePath="/hotspot"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Default">
+			<resource resourceType="PROJECT" workspacePath="/hotspot"/>
+		</configuration>
 	</storageModule>
 	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
 	<storageModule moduleId="scannerConfiguration">
 		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
 		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.388217325;cdt.managedbuild.tool.gnu.solaris.cpp.compiler.base.377383651;cdt.managedbuild.tool.gnu.cpp.compiler.input.103897085">
@@ -259,10 +112,10 @@
 		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.cpp.compiler.base.1342888057;cdt.managedbuild.tool.gnu.cpp.compiler.input.866181452">
 			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
 		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.351149667;cdt.managedbuild.tool.gnu.c.compiler.input.820447325">
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.c.compiler.base.1535888880;cdt.managedbuild.tool.gnu.c.compiler.input.906671119">
 			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
 		</scannerConfigBuildInfo>
-		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.c.compiler.base.1535888880;cdt.managedbuild.tool.gnu.c.compiler.input.906671119">
+		<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.solaris.base.945602881;cdt.managedbuild.toolchain.gnu.solaris.base.945602881.305678577;cdt.managedbuild.tool.gnu.solaris.c.compiler.base.351149667;cdt.managedbuild.tool.gnu.c.compiler.input.820447325">
 			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
 		</scannerConfigBuildInfo>
 	</storageModule>
--- a/mx/commands.py	Wed Jun 27 11:48:26 2012 +0200
+++ b/mx/commands.py	Wed Jun 27 17:35:32 2012 +0200
@@ -51,15 +51,6 @@
 
 _make_eclipse_launch = False
 
-_jacocoExcludes = ['com.oracle.graal.hotspot.snippets.ArrayCopySnippets',
-                   'com.oracle.graal.snippets.DoubleSnippets',
-                   'com.oracle.graal.snippets.FloatSnippets',
-                   'com.oracle.graal.snippets.MathSnippetsX86',
-                   'com.oracle.graal.snippets.NodeClassSnippets',
-                   'com.oracle.graal.hotspot.snippets.SystemSnippets',
-                   'com.oracle.graal.hotspot.snippets.UnsafeSnippets',
-                   'com.oracle.graal.compiler.tests.*']
-
 _copyrightTemplate = """/*
  * Copyright (c) {0}, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -184,7 +175,7 @@
     """run one or all DaCapo benchmarks
     
     DaCapo options are distinguished from VM options by a '@' prefix.
-    For example, '@--iterations @5' will pass '--iterations 5' to the
+    For example, '@-n @5' will pass '-n 5' to the
     DaCapo harness."""
 
     numTests = {}
@@ -295,13 +286,23 @@
 
 def _vmLibDirInJdk(jdk):
     """
-    Get the directory within a JDK where jvm.cfg file and the server
-    and client subdirectories are located.
+    Get the directory within a JDK where the server and client 
+    subdirectories are located.
     """
     if platform.system() == 'Darwin':
         return join(jdk, 'jre', 'lib')
+    if platform.system() == 'Windows':
+        return join(jdk, 'jre', 'bin')
     return join(jdk, 'jre', 'lib', 'amd64')
 
+def _vmCfgInJdk(jdk):
+    """
+    Get the jvm.cfg file.
+    """
+    if platform.system() == 'Windows':
+        return join(jdk, 'jre', 'lib', 'amd64', 'jvm.cfg')
+    return join(_vmLibDirInJdk(jdk), 'jvm.cfg')
+
 def _jdk(build='product', create=False):
     """
     Get the JDK into which Graal is installed, creating it first if necessary.
@@ -324,7 +325,7 @@
                 
             # Make a copy of the default VM so that this JDK can be
             # reliably used as the bootstrap for a HotSpot build.                
-            jvmCfg = join(_vmLibDirInJdk(jdk), 'jvm.cfg')
+            jvmCfg = _vmCfgInJdk(jdk)
             if not exists(jvmCfg):
                 mx.abort(jvmCfg + ' does not exist')
                 
@@ -347,6 +348,11 @@
                 for line in lines:
                     f.write(line)
                     
+            # Install a copy of the disassembler library
+            try:
+                hsdis([], copyToDir=_vmLibDirInJdk(jdk))
+            except SystemExit:
+                pass
     else:
         if not exists(jdk):
             mx.abort('The ' + build + ' VM has not been created - run \'mx clean; mx build ' + build + '\'')
@@ -368,9 +374,9 @@
         log = open(logFile, 'w')
     ret = False
     while True:
-        line = stdout.readline().decode()
+        line = stdout.readline().decode(sys.stdout.encoding)
         if logFile:
-            log.write(line)
+            log.write(line.encode('utf-8'))
         line = line.strip()
         mx.log(line)
         if line == STARTTOKEN:
@@ -384,7 +390,14 @@
             if match:
                 ret = True
         if line == ENDTOKEN:
-            break
+            if not findInOutput:
+                stdin.write('echo ERR%errorlevel%' + newLine)
+            else:
+                break
+        if line.startswith('ERR'):
+            if line == 'ERR0':
+                ret = True
+            break;
     stdin.write('exit' + newLine)
     if logFile:
         log.close()
@@ -499,8 +512,7 @@
                 mx.log('Error executing create command')
                 return 
             winBuildCmd = 'msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcxproj /p:Configuration=' + project_config + ' /p:Platform=x64'
-            winBuildSuccess = re.compile('Build succeeded.')
-            if not _runInDebugShell(winBuildCmd, _graal_home, compilelogfile, winBuildSuccess):
+            if not _runInDebugShell(winBuildCmd, _graal_home, compilelogfile):
                 mx.log('Error building project')
                 return 
         else:
@@ -520,7 +532,7 @@
             
             mx.run([mx.gmake_cmd(), build + buildSuffix], cwd=join(_graal_home, 'make'), err=filterXusage)
         
-        jvmCfg = join(_vmLibDirInJdk(jdk), 'jvm.cfg')
+        jvmCfg = _vmCfgInJdk(jdk)
         found = False
         if not exists(jvmCfg):
             mx.abort(jvmCfg + ' does not exist')
@@ -562,67 +574,73 @@
         vm = _vm
         
     build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product'
+    jdk = _jdk(build)
     mx.expand_project_in_args(args)
     if _make_eclipse_launch:
         mx.make_eclipse_launch(args, 'graal-' + build, name=None, deps=mx.project('com.oracle.graal.hotspot').all_deps([], True))
     if len([a for a in args if 'PrintAssembly' in a]) != 0:
-        hsdis([])
+        hsdis([], copyToDir=_vmLibDirInJdk(jdk))
     if mx.java().debug_port is not None:
         args = ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(mx.java().debug_port)] + args
     if _jacoco == 'on' or _jacoco == 'append':
         jacocoagent = mx.library("JACOCOAGENT", True)
+        # Exclude all compiler tests and snippets
+        excludes = ['com.oracle.graal.compiler.tests.*']
+        for p in mx.projects():
+            _find_classes_with_annotations(excludes, p, None, ['@Snippet', '@ClassSubstitution'], includeInnerClasses=True)
         agentOptions = {
                         'append' : 'true' if _jacoco == 'append' else 'false',
                         'bootclasspath' : 'true',
                         'includes' : 'com.oracle.*',
-                        'excludes' : ':'.join(_jacocoExcludes)
+                        'excludes' : ':'.join(excludes)
         }
         args = ['-javaagent:' + jacocoagent.get_path(True) + '=' + ','.join([k + '=' + v for k, v in agentOptions.items()])] + args
-    exe = join(_jdk(build), 'bin', mx.exe_suffix('java'))
+    exe = join(jdk, 'bin', mx.exe_suffix('java'))
     return mx.run([exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout)
 
-
-# Table of unit tests.
-# Keys are project names, values are package name lists.
-# All source files in the given (project,package) pairs are scanned for lines
-# containing '@Test'. These are then determined to be the classes defining
-# unit tests.
-_unittests = {
-    'com.oracle.graal.tests': ['com.oracle.graal.compiler.tests'],
-}
-_jtttests = {
-    'com.oracle.graal.jtt': ['com.oracle.graal.jtt'],
-}
-
-def _add_test_classes(testClassList, searchDir, pkgRoot):
+def _find_classes_with_annotations(classes, p, pkgRoot, annotations, includeInnerClasses=False):
+    """
+    Scan the sources of project 'p' for Java source files containing a line starting with 'annotation'
+    (ignoring preceding whitespace) and add the fully qualified class name
+    to 'classes' for each Java source file matched.
+    """
+    for a in annotations:
+        assert a.startswith('@')
     pkgDecl = re.compile(r"^package\s+([a-zA-Z_][\w\.]*)\s*;$")
-    for root, _, files in os.walk(searchDir):
-        for name in files:
-            if name.endswith('.java') and name != 'package-info.java':
-                hasTest = False
-                with open(join(root, name)) as f:
-                    pkg = None
-                    for line in f:
-                        if line.startswith("package "):
-                            match = pkgDecl.match(line)
-                            if match:
-                                pkg = match.group(1)
-                        else:
-                            if line.strip().startswith('@Test'):
-                                hasTest = True
-                                break
-                if hasTest:
-                    assert pkg is not None
-                    if pkg.startswith(pkgRoot):
-                        testClassList.append(pkg + '.' + name[:-len('.java')])
+    for srcDir in p.source_dirs():
+        outputDir = p.output_dir()
+        for root, _, files in os.walk(srcDir):
+            for name in files:
+                if name.endswith('.java') and name != 'package-info.java':
+                    annotationFound = False
+                    with open(join(root, name)) as f:
+                        pkg = None
+                        for line in f:
+                            if line.startswith("package "):
+                                match = pkgDecl.match(line)
+                                if match:
+                                    pkg = match.group(1)
+                            else:
+                                stripped = line.strip()
+                                for a in annotations:
+                                    if stripped == a or stripped.startswith(a + '('):
+                                        annotationFound = True
+                                        break
+                                if annotationFound:
+                                    break
+                    if annotationFound:
+                        basename = name[:-len('.java')]
+                        assert pkg is not None
+                        if pkgRoot is None or pkg.startswith(pkgRoot):
+                            pkgOutputDir = join(outputDir, pkg.replace('.', os.path.sep))
+                            for e in os.listdir(pkgOutputDir):
+                                if includeInnerClasses:
+                                    if e.endswith('.class') and (e.startswith(basename) or e.startswith(basename + '$')):
+                                        classes.append(pkg + '.' + e[:-len('.class')])
+                                elif e == basename + '.class':
+                                    classes.append(pkg + '.' + basename)
 
-def unittest(args):
-    """run the Graal Compiler Unit Tests in the GraalVM
-    
-    If filters are supplied, only tests whose fully qualified name
-    include a filter as a substring are run. Negative filters are
-    those with a '-' prefix. VM args should have a @ prefix."""
-    
+def _run_tests(args, harnessName, harness):
     pos = [a for a in args if a[0] != '-' and a[0] != '@' ]
     neg = [a[1:] for a in args if a[0] == '-']
     vmArgs = [a[1:] for a in args if a[0] == '@']
@@ -633,18 +651,30 @@
                 return True
         return False
     
-    for proj in _unittests.iterkeys():
-        p = mx.project(proj)
-        classes = []
-        for pkg in _unittests[proj]:
-            _add_test_classes(classes, join(p.dir, 'src'), pkg)
+    for p in mx.projects():
+        if getattr(p, 'testHarness', None) == harnessName:
+            classes = []
+            _find_classes_with_annotations(classes, p, None, ['@Test'])
+        
+            if len(pos) != 0:
+                classes = [c for c in classes if containsAny(c, pos)]
+            if len(neg) != 0:
+                classes = [c for c in classes if not containsAny(c, neg)]
+            
+            if len(classes) != 0:
+                mx.log('running tests in ' + p.name)
+                harness(p, vmArgs, classes)                
+
+def unittest(args):
+    """run the Graal Compiler Unit Tests in the GraalVM
     
-        if len(pos) != 0:
-            classes = [c for c in classes if containsAny(c, pos)]
-        if len(neg) != 0:
-            classes = [c for c in classes if not containsAny(c, neg)]
-            
-        vm(['-XX:-BootstrapGraal', '-esa'] + vmArgs + ['-cp', mx.classpath(proj), 'org.junit.runner.JUnitCore'] + classes)
+    If filters are supplied, only tests whose fully qualified name
+    include a filter as a substring are run. Negative filters are
+    those with a '-' prefix. VM args should have a @ prefix."""
+    
+    def harness(p, vmArgs, classes):
+        vm(['-XX:-BootstrapGraal', '-esa'] + vmArgs + ['-cp', mx.classpath(p.name), 'org.junit.runner.JUnitCore'] + classes)
+    _run_tests(args, 'unittest', harness)
     
 def jtt(args):
     """run the Java Tester Tests in the GraalVM
@@ -653,28 +683,9 @@
     include a filter as a substring are run. Negative filters are
     those with a '-' prefix. VM args should have a @ prefix."""
     
-    pos = [a for a in args if a[0] != '-' and a[0] != '@' ]
-    neg = [a[1:] for a in args if a[0] == '-']
-    vmArgs = [a[1:] for a in args if a[0] == '@']
-
-    def containsAny(c, substrings):
-        for s in substrings:
-            if s in c:
-                return True
-        return False
-    
-    for proj in _jtttests.iterkeys():
-        p = mx.project(proj)
-        classes = []
-        for pkg in _jtttests[proj]:
-            _add_test_classes(classes, join(p.dir, 'src'), pkg)
-    
-        if len(pos) != 0:
-            classes = [c for c in classes if containsAny(c, pos)]
-        if len(neg) != 0:
-            classes = [c for c in classes if not containsAny(c, neg)]
-            
-        vm(['-XX:-BootstrapGraal', '-XX:CompileOnly=::test', '-Xcomp', '-esa'] + vmArgs + ['-cp', mx.classpath(proj), 'org.junit.runner.JUnitCore'] + classes)
+    def harness(p, vmArgs, classes):
+        vm(['-XX:-BootstrapGraal', '-XX:CompileOnly=com/oracle/graal/jtt', '-XX:CompileCommand=compileonly,java/lang/Object::<init>', '-XX:CompileCommand=quiet', '-Xcomp', '-esa'] + vmArgs + ['-cp', mx.classpath(p.name), 'org.junit.runner.JUnitCore'] + classes)
+    _run_tests(args, 'jtt', harness)
     
 def buildvms(args):
     """build one or more VMs in various configurations"""
@@ -734,6 +745,10 @@
 
     args = parser.parse_args(args)
 
+    global _vmbuild
+    global _vm
+    global _jacoco
+    
     tasks = []             
     total = Task('Gate')
     try:
@@ -750,9 +765,7 @@
         t = Task('BuildJava')
         build(['--no-native'])
         tasks.append(t.stop())
-        global _jacoco
         for vmbuild in ['fastdebug', 'product']:
-            global _vmbuild
             _vmbuild = vmbuild
             
             if args.buildNative:
@@ -775,7 +788,7 @@
                 _jacoco = 'append'
             
             t = Task('JavaTesterTests:' + vmbuild)
-            jtt([])
+            jtt(['@-XX:CompileCommand=exclude,*::run*'] if vmbuild == 'product'  else [])
             tasks.append(t.stop())
             
             if vmbuild == 'product' and args.jacocout is not None:
@@ -814,6 +827,15 @@
             t = Task('BuildHotSpotVarieties')
             buildvms(['--vms', 'client,server', '--builds', 'fastdebug,product'])
             tasks.append(t.stop())
+
+            for vmbuild in ['product', 'fastdebug']:
+                _vmbuild = vmbuild
+                for theVm in ['client', 'server']:
+                    _vm = theVm
+
+                    t = Task('DaCapo_pmd:' + theVm + ':' + vmbuild)
+                    dacapo(['pmd'])
+                    tasks.append(t.stop())
         
     except KeyboardInterrupt:
         total.abort(1)
@@ -941,19 +963,20 @@
     vm = _vm;
     sanitycheck.getSPECjvm2008(benchArgs, skipValid, wt, it).bench(vm, opts=vmArgs)
     
-def hsdis(args):
-    """install the hsdis library
+def hsdis(args, copyToDir=None):
+    """downloads the hsdis library
 
     This is needed to support HotSpot's assembly dumping features.
-    By default it installs the Intel syntax version, use the 'att' argument to install AT&T syntax."""
+    By default it downloads the Intel syntax version, use the 'att' argument to install AT&T syntax."""
     flavor = 'intel'
     if 'att' in args:
         flavor = 'att'
-    build = _vmbuild if _vmSourcesAvailable else 'product'
     lib = mx.lib_suffix('hsdis-amd64')
-    path = join(_vmLibDirInJdk(_jdk(build)), lib)
+    path = join(_graal_home, 'lib', lib)
     if not exists(path):
         mx.download(path, ['http://lafo.ssw.uni-linz.ac.at/hsdis/' + flavor + "/" + lib])
+    if copyToDir is not None and exists(copyToDir):
+        shutil.copy(path, copyToDir)
     
 def hcfdis(args):
     """disassembles HexCodeFiles embedded in text files
@@ -978,6 +1001,68 @@
         mx.abort('jacocoreport takes only one argument : an output directory')
     mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out])
     
+def site(args):
+    """creates a website containing javadoc and the project dependency graph"""
+    
+    parser = ArgumentParser(prog='site')
+    parser.add_argument('-d', '--base', action='store', help='directory for generated site', required=True, metavar='<dir>')
+    parser.add_argument('-c', '--clean', action='store_true', help='remove existing site in <dir>')
+
+    args = parser.parse_args(args)
+    
+    args.base = os.path.abspath(args.base)
+    
+    if not exists(args.base):
+        os.mkdir(args.base)
+    elif args.clean:
+        shutil.rmtree(args.base)
+        os.mkdir(args.base)
+    
+    mx.javadoc(['--base', args.base])
+
+    unified = join(args.base, 'all')
+    if exists(unified):
+        shutil.rmtree(unified)
+    mx.javadoc(['--base', args.base, '--unified', '--arg', '@-overview', '--arg', '@' + join(_graal_home, 'graal', 'overview.html')])
+    os.rename(join(args.base, 'javadoc'), unified)
+        
+    _, tmp = tempfile.mkstemp()
+    try:
+        svg = join(args.base, 'all', 'modules.svg')
+        with open(tmp, 'w') as fp:
+            print >> fp, 'digraph projects {'
+            print >> fp, 'rankdir=BT;'
+            print >> fp, 'size = "13,13";'
+            print >> fp, 'node [shape=rect, fontcolor="blue"];'
+            print >> fp, 'edge [color="green"];'
+            for p in mx.projects():
+                print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]'  
+                for dep in p.canonical_deps():
+                    if mx.project(dep, False):
+                        print >> fp, '"' + p.name + '" -> "' + dep + '"'
+            depths = dict()
+            for p in mx.projects():
+                d = p.max_depth()
+                depths.setdefault(d, list()).append(p.name)
+            for d, names in depths.iteritems():
+                print >> fp, '{ rank = same; "' + '"; "'.join(names) + '"; }' 
+            print >> fp, '}'
+
+        mx.run(['dot', '-Tsvg', '-o' + svg, tmp])
+        
+        # Post-process generated SVG to remove unified title elements which most browsers
+        # render as redundant (and annoying) tooltips.
+        with open(svg, 'r') as fp:
+            content = fp.read()
+        content = re.sub('<title>.*</title>', '', content)
+        content = re.sub('xlink:title="[^"]*"', '', content)
+        with open(svg, 'w') as fp:
+            fp.write(content)
+        
+        print 'Created website - root is ' + join(unified, 'index.html')
+    finally:
+        os.remove(tmp)
+    
 def mx_init():
     _vmbuild = 'product'
     commands = {
@@ -999,6 +1084,7 @@
         'unittest' : [unittest, '[filters...]'],
         'jtt' : [jtt, '[filters...]'],
         'jacocoreport' : [jacocoreport, '[output directory]'],
+        'site' : [site, '[-options]'],
         'vm': [vm, '[-options] class [args...]'],
         'vmg': [vmg, '[-options] class [args...]'],
         'vmfg': [vmfg, '[-options] class [args...]']
--- a/mx/projects	Wed Jun 27 11:48:26 2012 +0200
+++ b/mx/projects	Wed Jun 27 17:35:32 2012 +0200
@@ -22,19 +22,66 @@
 library@DACAPO_SCALA@path=lib/dacapo-scala-0.1.0.jar
 library@DACAPO_SCALA@urls=http://repo.scalabench.org/snapshots/org/scalabench/benchmarks/scala-benchmark-suite/0.1.0-SNAPSHOT/scala-benchmark-suite-0.1.0-20110908.085753-2.jar
 
+# graal.api
+project@com.oracle.graal.api@subDir=graal
+project@com.oracle.graal.api@sourceDirs=src
+project@com.oracle.graal.api@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.api@javaCompliance=1.7
+
+# graal.api.test
+project@com.oracle.graal.api.test@subDir=graal
+project@com.oracle.graal.api.test@sourceDirs=src
+project@com.oracle.graal.api.test@dependencies=JUNIT,com.oracle.graal.api
+project@com.oracle.graal.api.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.api.test@javaCompliance=1.7
+
+# graal.api.meta
+project@com.oracle.graal.api.meta@subDir=graal
+project@com.oracle.graal.api.meta@sourceDirs=src
+project@com.oracle.graal.api.meta@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.api.meta@javaCompliance=1.7
+
+# graal.api.code
+project@com.oracle.graal.api.code@subDir=graal
+project@com.oracle.graal.api.code@sourceDirs=src
+project@com.oracle.graal.api.code@dependencies=com.oracle.graal.api.meta
+project@com.oracle.graal.api.code@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.api.code@javaCompliance=1.7
+
+# graal.api.interpreter
+project@com.oracle.graal.api.interpreter@subDir=graal
+project@com.oracle.graal.api.interpreter@sourceDirs=src
+project@com.oracle.graal.api.interpreter@dependencies=com.oracle.graal.api.meta
+project@com.oracle.graal.api.interpreter@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.api.interpreter@javaCompliance=1.7
+
 # graal.hotspot
 project@com.oracle.graal.hotspot@subDir=graal
 project@com.oracle.graal.hotspot@sourceDirs=src
-project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.snippets
+project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.snippets,com.oracle.graal.api.interpreter,com.oracle.graal.api
 project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hotspot@javaCompliance=1.7
 
+# graal.hotspot.server
+project@com.oracle.graal.hotspot.server@subDir=graal
+project@com.oracle.graal.hotspot.server@sourceDirs=src
+project@com.oracle.graal.hotspot.server@dependencies=com.oracle.graal.hotspot
+project@com.oracle.graal.hotspot.server@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.hotspot.server@javaCompliance=1.7
+
 # graal.graph
 project@com.oracle.graal.graph@subDir=graal
-project@com.oracle.graal.graph@sourceDirs=src,test
-project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug,JUNIT
+project@com.oracle.graal.graph@sourceDirs=src
+project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug
 project@com.oracle.graal.graph@javaCompliance=1.7
 
+# graal.graph.test
+project@com.oracle.graal.graph.test@subDir=graal
+project@com.oracle.graal.graph.test@sourceDirs=src
+project@com.oracle.graal.graph.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.graph.test@dependencies=JUNIT,com.oracle.graal.graph
+project@com.oracle.graal.graph.test@javaCompliance=1.7
+
 # graal.debug
 project@com.oracle.graal.debug@subDir=graal
 project@com.oracle.graal.debug@sourceDirs=src
@@ -64,11 +111,19 @@
 
 # graal.snippets
 project@com.oracle.graal.snippets@subDir=graal
-project@com.oracle.graal.snippets@sourceDirs=src,test
+project@com.oracle.graal.snippets@sourceDirs=src
 project@com.oracle.graal.snippets@dependencies=com.oracle.graal.printer
 project@com.oracle.graal.snippets@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.snippets@javaCompliance=1.7
 
+# graal.snippets.test
+project@com.oracle.graal.snippets.test@subDir=graal
+project@com.oracle.graal.snippets.test@sourceDirs=src
+project@com.oracle.graal.snippets.test@dependencies=com.oracle.graal.snippets,com.oracle.graal.tests
+project@com.oracle.graal.snippets.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.snippets.test@javaCompliance=1.7
+project@com.oracle.graal.snippets.test@testHarness=unittest
+
 # graal.nodes
 project@com.oracle.graal.nodes@subDir=graal
 project@com.oracle.graal.nodes@sourceDirs=src,test
@@ -76,6 +131,13 @@
 project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.nodes@javaCompliance=1.7
 
+# graal.interpreter
+project@com.oracle.graal.interpreter@subDir=graal
+project@com.oracle.graal.interpreter@sourceDirs=src
+project@com.oracle.graal.interpreter@dependencies=com.oracle.graal.hotspot
+project@com.oracle.graal.interpreter@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.interpreter@javaCompliance=1.7
+
 # graal.compiler
 project@com.oracle.graal.compiler@subDir=graal
 project@com.oracle.graal.compiler@sourceDirs=src
@@ -83,10 +145,30 @@
 project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler@javaCompliance=1.7
 
+# graal.boot
+project@com.oracle.graal.boot@subDir=graal
+project@com.oracle.graal.boot@sourceDirs=src
+project@com.oracle.graal.boot@dependencies=com.oracle.graal.java,com.oracle.graal.api
+project@com.oracle.graal.boot@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.boot@javaCompliance=1.7
+
+# graal.boot.test
+project@com.oracle.graal.boot.test@subDir=graal
+project@com.oracle.graal.boot.test@sourceDirs=src
+project@com.oracle.graal.boot.test@dependencies=JUNIT,com.oracle.graal.boot
+project@com.oracle.graal.boot.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.boot.test@javaCompliance=1.7
+
+# graal.bytecode
+project@com.oracle.graal.bytecode@subDir=graal
+project@com.oracle.graal.bytecode@sourceDirs=src
+project@com.oracle.graal.bytecode@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.bytecode@javaCompliance=1.7
+
 # graal.java
 project@com.oracle.graal.java@subDir=graal
 project@com.oracle.graal.java@sourceDirs=src
-project@com.oracle.graal.java@dependencies=com.oracle.graal.compiler
+project@com.oracle.graal.java@dependencies=com.oracle.graal.compiler,com.oracle.graal.bytecode
 project@com.oracle.graal.java@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.java@javaCompliance=1.7
 
@@ -100,9 +182,10 @@
 # graal.test
 project@com.oracle.graal.tests@subDir=graal
 project@com.oracle.graal.tests@sourceDirs=src
-project@com.oracle.graal.tests@dependencies=com.oracle.graal.printer
+project@com.oracle.graal.tests@dependencies=JUNIT,com.oracle.graal.printer,com.oracle.graal.api
 project@com.oracle.graal.tests@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.tests@javaCompliance=1.7
+project@com.oracle.graal.tests@testHarness=unittest
 
 # graal.jtt
 project@com.oracle.graal.jtt@subDir=graal
@@ -110,6 +193,7 @@
 project@com.oracle.graal.jtt@dependencies=JUNIT
 project@com.oracle.graal.jtt@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.jtt@javaCompliance=1.7
+project@com.oracle.graal.jtt@testHarness=jtt
 
 # graal.examples
 project@com.oracle.graal.examples@subDir=graal
@@ -127,7 +211,7 @@
 # max.cri
 project@com.oracle.max.cri@subDir=graal
 project@com.oracle.max.cri@sourceDirs=src
-project@com.oracle.max.cri@dependencies=
+project@com.oracle.max.cri@dependencies=com.oracle.graal.api.code
 project@com.oracle.max.cri@checkstyle=com.oracle.graal.graph
 project@com.oracle.max.cri@javaCompliance=1.7
 
--- a/mxtool/mx.py	Wed Jun 27 11:48:26 2012 +0200
+++ b/mxtool/mx.py	Wed Jun 27 17:35:32 2012 +0200
@@ -50,10 +50,10 @@
 
   commands.py
       Suite specific extensions to the commands available to mx.
-      This is only processed for the primary suite.
 
   includes
-      Other suites to be loaded. This is recursive.
+      Other suites to be loaded. This is recursive. Each
+      line in an includes file is a path to a suite directory.
 
   env
       A set of environment variable definitions. These override any
@@ -124,7 +124,7 @@
 Property values can use environment variables with Bash syntax (e.g. ${HOME}).
 """
 
-import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils
+import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile
 import shutil, fnmatch, re, xml.dom.minidom
 from collections import Callable
 from threading import Thread
@@ -172,6 +172,13 @@
         self.javaCompliance = JavaCompliance(javaCompliance) if javaCompliance is not None else None
         self.native = False
         self.dir = dir
+        
+        # Create directories for projects that don't yet exist
+        if not exists(dir):
+            os.mkdir(dir)
+        for s in self.source_dirs():
+            if not exists(s):
+                os.mkdir(s)
 
     def all_deps(self, deps, includeLibs, includeSelf=True):
         """
@@ -216,11 +223,17 @@
             if d == 1:
                 result.add(n)
 
-
         if len(result) == len(self.deps) and frozenset(self.deps) == result:
             return self.deps
         return result;
 
+    def max_depth(self):
+        """
+        Get the maximum canonical distance between this project and its most distant dependency.
+        """
+        distances = dict()
+        self._compute_max_dep_distances(self.name, distances, 0)
+        return max(distances.values())        
 
     def source_dirs(self):
         """
@@ -281,8 +294,8 @@
         self.primary = primary
         mxDir = join(dir, 'mx')
         self._load_env(mxDir)
-        if primary:
-            self._load_commands(mxDir)
+        self._load_commands(mxDir)
+        self._load_includes(mxDir)
 
     def _load_projects(self, mxDir):
         libsMap = dict()
@@ -353,8 +366,9 @@
         if exists(commands):
             # temporarily extend the Python path
             sys.path.insert(0, mxDir)
-
             mod = __import__('commands')
+            
+            sys.modules[join(mxDir, 'commands')] = sys.modules.pop('commands')
 
             # revert the Python path
             del sys.path[0]
@@ -372,7 +386,9 @@
         if exists(includes):
             with open(includes) as f:
                 for line in f:
-                    self.includes.append(expandvars_in_property(line.strip()))
+                    include = expandvars_in_property(line.strip())
+                    self.includes.append(include)
+                    _loadSuite(include, False)
 
     def _load_env(self, mxDir):
         e = join(mxDir, 'env')
@@ -386,9 +402,8 @@
 
     def _post_init(self, opts):
         mxDir = join(self.dir, 'mx')
-        self._load_includes(mxDir)
         self._load_projects(mxDir)
-        if self.mx_post_parse_cmd_line is not None:
+        if hasattr(self, 'mx_post_parse_cmd_line'):
             self.mx_post_parse_cmd_line(opts)
         for p in self.projects:
             existing = _projects.get(p.name)
@@ -404,11 +419,11 @@
 class XMLElement(xml.dom.minidom.Element):
     def writexml(self, writer, indent="", addindent="", newl=""):
         writer.write(indent+"<" + self.tagName)
-    
+
         attrs = self._get_attributes()
         a_names = attrs.keys()
         a_names.sort()
-    
+
         for a_name in a_names:
             writer.write(" %s=\"" % a_name)
             xml.dom.minidom._write_data(writer, attrs[a_name].value)
@@ -416,7 +431,7 @@
         if self.childNodes:
             if not self.ownerDocument.padTextNodeWithoutSiblings and len(self.childNodes) == 1 and isinstance(self.childNodes[0], xml.dom.minidom.Text):
                 # if the only child of an Element node is a Text node, then the
-                # text is printed without any indentation or new line padding  
+                # text is printed without any indentation or new line padding
                 writer.write(">")
                 self.childNodes[0].writexml(writer)
                 writer.write("</%s>%s" % (self.tagName,newl))
@@ -440,7 +455,7 @@
         e = XMLElement(tagName)
         e.ownerDocument = self
         return e
-    
+
     def open(self, tag, attributes={}, data=None):
         element = self.createElement(tag)
         for key, value in attributes.items():
@@ -453,13 +468,13 @@
 
     def close(self, tag):
         assert self.current != self
-        assert tag == self.current.tagName, str(tag) + ' != ' + self.current.tagName  
+        assert tag == self.current.tagName, str(tag) + ' != ' + self.current.tagName
         self.current = self.current.parentNode
         return self
-    
+
     def element(self, tag, attributes={}, data=None):
         return self.open(tag, attributes, data).close(tag)
-            
+
     def xml(self, indent='', newl='', escape=False):
         assert self.current == self
         result = self.toprettyxml(indent, newl, encoding="UTF-8")
@@ -534,20 +549,49 @@
         cp += [_opts.cp_suffix]
     return os.pathsep.join(cp)
 
-def classpath(names=None, resolve=True, includeSelf=True):
+def classpath(names=None, resolve=True, includeSelf=True, includeBootClasspath=False):
     """
     Get the class path for a list of given projects, resolving each entry in the
     path (e.g. downloading a missing library) if 'resolve' is true.
     """
     if names is None:
-        return _as_classpath(sorted_deps(includeLibs=True), resolve)
-    deps = []
-    if isinstance(names, types.StringTypes):
-        project(names).all_deps(deps, True, includeSelf)
+        result = _as_classpath(sorted_deps(includeLibs=True), resolve)
     else:
-        for n in names:
-            project(n).all_deps(deps, True, includeSelf)
-    return _as_classpath(deps, resolve)
+        deps = []
+        if isinstance(names, types.StringTypes):
+            project(names).all_deps(deps, True, includeSelf)
+        else:
+            for n in names:
+                project(n).all_deps(deps, True, includeSelf)
+        result = _as_classpath(deps, resolve)
+    if includeBootClasspath:
+        result = os.pathsep.join([java().bootclasspath(), result])
+    return result
+
+def classpath_walk(names=None, resolve=True, includeSelf=True, includeBootClasspath=False):
+    """
+    Walks the resources available in a given classpath, yielding a tuple for each resource
+    where the first member of the tuple is a directory path or ZipFile object for a
+    classpath entry and the second member is the qualified path of the resource relative
+    to the classpath entry.
+    """
+    cp = classpath(names, resolve, includeSelf, includeBootClasspath)
+    for entry in cp.split(os.pathsep):
+        if not exists(entry):
+            continue
+        if isdir(entry):
+            for root, dirs, files in os.walk(entry):
+                for d in dirs:
+                    entryPath = join(root[len(entry) + 1:], d)
+                    yield entry, entryPath
+                for f in files:
+                    entryPath = join(root[len(entry) + 1:], f)
+                    yield entry, entryPath
+        elif entry.endswith('.jar') or entry.endswith('.zip'):
+            with zipfile.ZipFile(entry, 'r') as zf:
+                for zi in zf.infolist():
+                    entryPath = zi.filename
+                    yield zf, entryPath
 
 def sorted_deps(projectNames=None, includeLibs=False):
     """
@@ -830,6 +874,7 @@
         self.javac = exe_suffix(join(self.jdk, 'bin', 'javac'))
         self.javap = exe_suffix(join(self.jdk, 'bin', 'javap'))
         self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc'))
+        self._bootclasspath = None
 
         if not exists(self.java):
             abort('Java launcher derived from JAVA_HOME does not exist: ' + self.java)
@@ -863,6 +908,27 @@
     def format_cmd(self, args):
         return [self.java] + self.java_args_pfx + self.java_args + self.java_args_sfx + args
 
+    def bootclasspath(self):
+        if self._bootclasspath is None:
+            tmpDir = tempfile.mkdtemp()
+            try:
+                src = join(tmpDir, 'bootclasspath.java')
+                with open(src, 'w') as fp:
+                    print >> fp, """
+public class bootclasspath {
+    public static void main(String[] args) {
+        String s = System.getProperty("sun.boot.class.path");
+        if (s != null) {
+            System.out.println(s);
+        }
+    }
+}"""
+                subprocess.check_call([self.javac, '-d', tmpDir, src])
+                self._bootclasspath = subprocess.check_output([self.java, '-cp', tmpDir, 'bootclasspath'])
+            finally:
+                shutil.rmtree(tmpDir)
+        return self._bootclasspath
+
 def check_get_env(key):
     """
     Gets an environment variable, aborting with a useful message if it is not set.
@@ -1039,7 +1105,7 @@
     javaCompliance = java().javaCompliance
 
     defaultEcjPath = join(_mainSuite.dir, 'mx', 'ecj.jar')
-    
+
     parser = parser if parser is not None else ArgumentParser(prog='mx build')
     parser.add_argument('-f', action='store_true', dest='force', help='force build (disables timestamp checking)')
     parser.add_argument('-c', action='store_true', dest='clean', help='removes existing build output')
@@ -1440,8 +1506,7 @@
         for dep in p.canonical_deps():
             print '"' + p.name + '"->"' + dep + '"'
     print '}'
-    
-    
+
 def _source_locator_memento(deps):
     slm = XMLDoc()
     slm.open('sourceLookupDirector')
@@ -1450,7 +1515,7 @@
     # Every Java program depends on the JRE
     memento = XMLDoc().element('classpathContainer', {'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}).xml()
     slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
-        
+
     for dep in deps:
         if dep.isLibrary():
             if hasattr(dep, 'eclipse.container'):
@@ -1482,7 +1547,7 @@
     launch.element('stringAttribute', {'key' : 'org.eclipse.jdt.launching.VM_CONNECTOR_ID', 'value' : 'org.eclipse.jdt.launching.socketAttachConnector'})
     launch.close('launchConfiguration')
     launch = launch.xml(newl='\n') % slm.xml(escape=True)
-    
+
     if name is None:
         name = 'attach-' + hostname + '-' + port
     eclipseLaunches = join('mx', 'eclipse-launches')
@@ -1516,11 +1581,11 @@
             mainClass = a
             appArgs = list(reversed(argsCopy))
             break
-    
+
     if mainClass is None:
         log('Cannot create Eclipse launch configuration without main class or jar file: java ' + ' '.join(javaArgs))
         return False
-    
+
     if name is None:
         if mainClass == '-jar':
             name = basename(appArgs[0])
@@ -1535,9 +1600,9 @@
             for s in suites():
                 deps += [p for p in s.projects if e == p.output_dir()]
                 deps += [l for l in s.libs if e == l.get_path(False)]
-    
+
     slm = _source_locator_memento(deps)
-    
+
     launch = XMLDoc()
     launch.open('launchConfiguration', {'type' : 'org.eclipse.jdt.launching.localJavaApplication'})
     launch.element('stringAttribute', {'key' : 'org.eclipse.debug.core.source_locator_id', 'value' : 'org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector'})
@@ -1564,13 +1629,13 @@
     for p in projects():
         if p.native:
             continue
-        
+
         if not exists(p.dir):
             os.makedirs(p.dir)
 
         out = XMLDoc()
         out.open('classpath')
-        
+
         for src in p.srcDirs:
             srcDir = join(p.dir, src)
             if not exists(srcDir):
@@ -1677,7 +1742,7 @@
                     content = content.replace('${javaCompliance}', str(p.javaCompliance))
                     update_file(join(settingsDir, name), content)
 
-    make_eclipse_attach('localhost', '8000', deps=projects())                    
+    make_eclipse_attach('localhost', '8000', deps=projects())
 
 def netbeansinit(args, suite=None):
     """(re)generate NetBeans project configurations"""
@@ -1685,6 +1750,9 @@
     if suite is None:
         suite = _mainSuite
 
+    def println(out, obj):
+        out.write(str(obj) + '\n')
+
     updated = False
     for p in projects():
         if p.native:
@@ -1714,7 +1782,7 @@
         out.element('root', {'id' : 'test.src.dir'})
         out.close('test-roots')
         out.close('data')
-        
+
         firstDep = True
         for dep in p.all_deps([], True):
             if dep == p:
@@ -1889,69 +1957,90 @@
     eclipseinit(args, suite)
     netbeansinit(args, suite)
 
-def javadoc(args):
+def javadoc(args, parser=None, docDir='javadoc', includeDeps=True):
     """generate javadoc for some/all Java projects"""
-    
-    parser = ArgumentParser(prog='mx javadoc')
+
+    parser = ArgumentParser(prog='mx javadoc') if parser is None else parser
+    parser.add_argument('-d', '--base', action='store', help='base directory for output')
     parser.add_argument('--unified', action='store_true', help='put javadoc in a single directory instead of one per project')
     parser.add_argument('--force', action='store_true', help='(re)generate javadoc even if package-list file exists')
     parser.add_argument('--projects', action='store', help='comma separated projects to process (omit to process all projects)')
     parser.add_argument('--argfile', action='store', help='name of file containing extra javadoc options')
+    parser.add_argument('--arg', action='append', dest='extra_args', help='extra Javadoc arguments (e.g. --arg @-use)', metavar='@<arg>', default=[])
     parser.add_argument('-m', '--memory', action='store', help='-Xmx value to pass to underlying JVM')
-    
+    parser.add_argument('--packages', action='store', help='comma separated packages to process (omit to process all packages)')
+
     args = parser.parse_args(args)
-    
+
     # build list of projects to be processed
     candidates = sorted_deps()
     if args.projects is not None:
         candidates = [project(name) for name in args.projects.split(',')]
-        
+
+    # optionally restrict packages within a project
+    packages = []
+    if args.packages is not None:
+        packages = [name for name in args.packages.split(',')]
+
+    def outDir(p):
+        if args.base is None:
+            return join(p.dir, docDir)
+        return join(args.base, p.name, docDir)
+
+    def check_package_list(p):
+        return not exists(join(outDir(p), 'package-list'))
+
     def assess_candidate(p, projects):
         if p in projects:
             return False
-        if args.force or args.unified or not exists(join(p.dir, 'javadoc', 'package-list')):
+        if args.force or args.unified or check_package_list(p):
             projects.append(p)
             return True
         return False
-        
+
     projects = []
     for p in candidates:
         if not p.native:
-            deps = p.all_deps([], includeLibs=False, includeSelf=False)
-            for d in deps:
-                assess_candidate(d, projects)
+            if includeDeps:
+                deps = p.all_deps([], includeLibs=False, includeSelf=False)
+                for d in deps:
+                    assess_candidate(d, projects)
             if not assess_candidate(p, projects):
                 log('[package-list file exists - skipping {0}]'.format(p.name))
 
-    
+
     def find_packages(sourceDirs, pkgs=set()):
         for sourceDir in sourceDirs:
             for root, _, files in os.walk(sourceDir):
                 if len([name for name in files if name.endswith('.java')]) != 0:
-                    pkgs.add(root[len(sourceDir) + 1:].replace('/','.'))
+                    pkg = root[len(sourceDir) + 1:].replace('/','.')
+                    if (len(packages) == 0) | (pkg in packages):
+                        pkgs.add(pkg)
         return pkgs
 
-    extraArgs = []
+    extraArgs = [a.lstrip('@') for a in args.extra_args]
     if args.argfile is not None:
         extraArgs += ['@' + args.argfile]
+    memory = '2g'
     if args.memory is not None:
-        extraArgs.append('-J-Xmx' + args.memory)
+        memory = args.memory
+    memory = '-J-Xmx' + memory
 
     if not args.unified:
         for p in projects:
             pkgs = find_packages(p.source_dirs(), set())
             deps = p.all_deps([], includeLibs=False, includeSelf=False)
-            links = ['-link', 'http://docs.oracle.com/javase/6/docs/api/']
-            out = join(p.dir, 'javadoc')
+            links = ['-link', 'http://docs.oracle.com/javase/' + str(p.javaCompliance.value) + '/docs/api/']
+            out = outDir(p)
             for d in deps:
-                depOut = join(d.dir, 'javadoc')
+                depOut = outDir(d)
                 links.append('-link')
                 links.append(os.path.relpath(depOut, out))
             cp = classpath(p.name, includeSelf=True)
             sp = os.pathsep.join(p.source_dirs())
-            log('Generating javadoc for {0} in {1}'.format(p.name, out))
-            run([java().javadoc, '-J-Xmx2g', '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs))
-            log('Generated javadoc for {0} in {1}'.format(p.name, out))
+            log('Generating {2} for {0} in {1}'.format(p.name, out, docDir))
+            run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs))
+            log('Generated {2} for {0} in {1}'.format(p.name, out, docDir))
     else:
         pkgs = set()
         sp = []
@@ -1960,14 +2049,30 @@
             find_packages(p.source_dirs(), pkgs)
             sp += p.source_dirs()
             names.append(p.name)
-            
-        links = ['-link', 'http://docs.oracle.com/javase/6/docs/api/']
-        out = join(_mainSuite.dir, 'javadoc')
+
+        links = ['-link', 'http://docs.oracle.com/javase/' + str(_java.javaCompliance.value) + '/docs/api/']
+        out = join(_mainSuite.dir, docDir)
+        if args.base is not None:
+            out = join(args.base, docDir)
         cp = classpath()
         sp = os.pathsep.join(sp)
-        log('Generating javadoc for {0} in {1}'.format(', '.join(names), out))
-        run([java().javadoc, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs))
-        log('Generated javadoc for {0} in {1}'.format(', '.join(names), out))
+        log('Generating {2} for {0} in {1}'.format(', '.join(names), out, docDir))
+        run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs))
+        log('Generated {2} for {0} in {1}'.format(', '.join(names), out, docDir))
+
+def findclass(args):
+    """find all classes matching a given substring"""
+
+    for entry, filename in classpath_walk(includeBootClasspath=True):
+        if filename.endswith('.class'):
+            if isinstance(entry, zipfile.ZipFile):
+                classname = filename.replace('/', '.')
+            else:
+                classname = filename.replace(os.sep, '.')
+            classname = classname[:-len('.class')]
+            for a in args:
+                if a in classname:
+                    log(classname)
 
 def javap(args):
     """launch javap with a -classpath option denoting all available classes
@@ -2010,6 +2115,7 @@
     'canonicalizeprojects': [canonicalizeprojects, ''],
     'clean': [clean, ''],
     'eclipseinit': [eclipseinit, ''],
+    'findclass': [findclass, ''],
     'help': [help_, '[command]'],
     'ideclean': [ideclean, ''],
     'ideinit': [ideinit, ''],
@@ -2022,11 +2128,27 @@
 
 _argParser = ArgParser()
 
+def _findPrimarySuite():
+    # try current working directory first
+    mxDir = join(os.getcwd(), 'mx')
+    if exists(mxDir) and isdir(mxDir):
+        return dirname(mxDir)
+
+    # now search path of my executable
+    me = sys.argv[0]
+    parent = dirname(me)
+    while parent:
+        mxDir = join(parent, 'mx')
+        if exists(mxDir) and isdir(mxDir):
+            return parent
+        parent = dirname(parent)
+    return None
+
 def main():
-    cwdMxDir = join(os.getcwd(), 'mx')
-    if exists(cwdMxDir) and isdir(cwdMxDir):
+    primarySuiteDir = _findPrimarySuite()
+    if primarySuiteDir:
         global _mainSuite
-        _mainSuite = _loadSuite(os.getcwd(), True)
+        _mainSuite = _loadSuite(primarySuiteDir, True)
 
     opts, commandAndArgs = _argParser._parse_cmd_line()
 
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -990,37 +990,6 @@
   return oop_maps;
 }
 
-#ifdef GRAAL
-JRT_ENTRY(void, graal_create_null_exception(JavaThread* thread))
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
-JRT_END
-
-JRT_ENTRY(void, graal_create_out_of_bounds_exception(JavaThread* thread, jint index))
-  char message[jintAsStringSize];
-  sprintf(message, "%d", index);
-  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
-JRT_END
-
-JRT_ENTRY(void, graal_generic_callback(JavaThread* thread, oop _callback, oop _argument))
-  HandleMark hm;
-  Handle callback(_callback);
-  Handle argument(_argument);
-
-  KlassHandle klass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_cri_ci_CiGenericCallback(), SystemDictionary::java_system_loader(), NULL, thread);
-  if (klass.is_null()) {
-    tty->print_cr("couldn't resolve com_oracle_max_cri_ci_CiGenericCallback");
-  }
-
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(Handle(callback));
-  args.push_oop(Handle(argument));
-  JavaCalls::call_virtual(&result, klass, vmSymbols::callbackInternal_name(), vmSymbols::callback_signature(), &args, thread);
-
-  thread->set_vm_result((oop) result.get_jobject());
-JRT_END
-#endif
-
 OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
 
   // for better readability
@@ -1067,6 +1036,10 @@
 
           __ push(rdi);
           __ push(rbx);
+#ifdef GRAAL
+          __ push(rcx);
+          __ push(rsi);
+#endif
 
           if (id == fast_new_instance_init_check_id) {
             // make sure the klass is initialized
@@ -1105,6 +1078,10 @@
 
           __ initialize_object(obj, klass, obj_size, 0, t1, t2);
           __ verify_oop(obj);
+#ifdef GRAAL
+          __ pop(rsi);
+          __ pop(rcx);
+#endif
           __ pop(rbx);
           __ pop(rdi);
           __ ret(0);
@@ -1118,11 +1095,19 @@
 
           __ initialize_object(obj, klass, obj_size, 0, t1, t2);
           __ verify_oop(obj);
+#ifdef GRAAL
+          __ pop(rsi);
+          __ pop(rcx);
+#endif
           __ pop(rbx);
           __ pop(rdi);
           __ ret(0);
 
           __ bind(slow_path);
+#ifdef GRAAL
+          __ pop(rsi);
+          __ pop(rcx);
+#endif
           __ pop(rbx);
           __ pop(rdi);
         }
@@ -1916,6 +1901,30 @@
       break;
     }
 
+    case graal_log_primitive_id: {
+      __ enter();
+      oop_maps = new OopMapSet();
+      OopMap* oop_map = save_live_registers(sasm, 0);
+      int call_offset = __ call_RT(noreg, noreg, (address)graal_log_primitive, j_rarg0, j_rarg1, j_rarg2);
+      oop_maps->add_gc_map(call_offset, oop_map);
+      restore_live_registers(sasm);
+      __ leave();
+      __ ret(0);
+      break;
+    }
+
+    case graal_log_object_id: {
+      __ enter();
+      oop_maps = new OopMapSet();
+      OopMap* oop_map = save_live_registers(sasm, 0);
+      int call_offset = __ call_RT(noreg, noreg, (address)graal_log_object, j_rarg0, j_rarg1, j_rarg2);
+      oop_maps->add_gc_map(call_offset, oop_map);
+      restore_live_registers(sasm);
+      __ leave();
+      __ ret(0);
+      break;
+    }
+
     case graal_generic_callback_id: {
     __ enter();
     oop_maps = new OopMapSet();
@@ -1946,8 +1955,11 @@
       break;
     }
 
-    case graal_verify_pointer_id: {
-      __ verify_oop(r13, "graal verify pointer");
+    case graal_verify_oop_id: {
+      // We use enter & leave so that a better stack trace is produced in the hs_err file
+      __ enter();
+      __ verify_oop(r13, "graal verify oop");
+      __ leave();
       __ ret(0);
       break;
     }
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Wed Jun 27 17:35:32 2012 +0200
@@ -1,11 +1,12 @@
 colorize("name", ".*", white);
-colorize("name", "Begin|EndNode|LoopBegin|LoopEnd|Return", orange);
-colorize("name", "Phi.*", magenta);
+colorize("name", "Begin|EndNode|LoopBegin|LoopEnd|LoopExit|Return", orange);
+colorize("name", "Phi.*|ValueProxy", magenta);
 colorize("name", "FrameState@.*", new java.awt.Color(0.5, 0.8, 1.0));
 colorize("name", "If|Merge", pink);
 colorize("name", "const.*", new java.awt.Color(0.7, 0.7, 0.7));
 colorize("name", "Local", new java.awt.Color(0.85, 0.85, 0.85));
 colorize("name", "\\+|-|\\*|/|&|\\||<<|>>|>>>", cyan);
 colorize("name", "Comp .*", yellow);
+colorize("name", "Virtual.*", green);
 
 colorize("notInOwnBlock", "true", red);
\ No newline at end of file
--- a/src/share/vm/c1/c1_Runtime1.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -206,7 +206,7 @@
     case handle_exception_nofpu_id:  // Unused on sparc
 #endif
 #ifdef GRAAL
-    case graal_verify_pointer_id:
+    case graal_verify_oop_id:
     case graal_unwind_exception_call_id:
     case graal_slow_subtype_check_id:
     case graal_arithmetic_frem_id:
@@ -648,6 +648,36 @@
 JRT_END
 
 #ifdef GRAAL
+
+JRT_ENTRY(void, Runtime1::graal_create_null_exception(JavaThread* thread))
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)());
+JRT_END
+
+JRT_ENTRY(void, Runtime1::graal_create_out_of_bounds_exception(JavaThread* thread, jint index))
+  char message[jintAsStringSize];
+  sprintf(message, "%d", index);
+  thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message)());
+JRT_END
+
+JRT_ENTRY(void, Runtime1::graal_generic_callback(JavaThread* thread, oop _callback, oop _argument))
+  HandleMark hm;
+  Handle callback(_callback);
+  Handle argument(_argument);
+
+  KlassHandle klass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_api_code_GenericCallback(), SystemDictionary::java_system_loader(), NULL, thread);
+  if (klass.is_null()) {
+    tty->print_cr("couldn't resolve com_oracle_graal_api_code_GenericCallback");
+  }
+
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  args.push_oop(Handle(callback));
+  args.push_oop(Handle(argument));
+  JavaCalls::call_virtual(&result, klass, vmSymbols::callbackInternal_name(), vmSymbols::callback_signature(), &args, thread);
+
+  thread->set_vm_result((oop) result.get_jobject());
+JRT_END
+
 JRT_ENTRY_NO_ASYNC(void, Runtime1::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
   NOT_PRODUCT(_monitorenter_slowcase_cnt++;)
 #ifdef ASSERT
@@ -708,7 +738,72 @@
   }
 JRT_END
 
-#endif
+JRT_ENTRY(void, Runtime1::graal_log_object(JavaThread* thread, oop obj, jboolean newline, jboolean string))
+  if (!string) {
+    tty->print("%p", obj);
+  } else {
+    assert(obj != NULL && java_lang_String::is_instance(obj), "must be");
+
+    typeArrayOop value  = java_lang_String::value(obj);
+    int          offset = java_lang_String::offset(obj);
+    int          length = java_lang_String::length(obj);
+
+    if (length != 0) {
+      int printLength = MIN2(length, 1024);
+      if (value == NULL) {
+        // This can happen if, e.g., printing a String
+        // object before its initializer has been called
+        tty->print("null");
+      } else if (printLength < 256 - 1) {
+        // Use an intermediate buffer to try and prevent interlacing of multi-threaded output
+        char buf[256];
+        for (int index = 0; index < printLength; index++) {
+          buf[index] = value->char_at(index + offset);
+        }
+        buf[printLength] = 0;
+        tty->print("%s", buf);
+        if (printLength < length) {
+          tty->print("... (%d more)", length - printLength);
+        }
+      } else {
+        for (int index = 0; index < printLength; index++) {
+          tty->print("%c", value->char_at(index + offset));
+        }
+        if (printLength < length) {
+          tty->print("... (%d more)", length - printLength);
+        }
+      }
+    }
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+JRT_ENTRY(void, Runtime1::graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline))
+  union {
+      jlong l;
+      jdouble d;
+      jfloat f;
+  } uu;
+  uu.l = value;
+  switch (typeChar) {
+    case 'z': tty->print(value == 0 ? "false" : "true"); break;
+    case 'b': tty->print("%d", (jbyte) value); break;
+    case 'c': tty->print("%c", (jchar) value); break;
+    case 's': tty->print("%d", (jshort) value); break;
+    case 'i': tty->print("%d", (jint) value); break;
+    case 'f': tty->print("%f", uu.f); break;
+    case 'j': tty->print(INT64_FORMAT, value); break;
+    case 'd': tty->print("%lf", uu.d); break;
+    default: assert(false, "unknown typeChar"); break;
+  }
+  if (newline) {
+    tty->cr();
+  }
+JRT_END
+
+#endif /* GRAAL */
 
 
 JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock))
--- a/src/share/vm/c1/c1_Runtime1.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -76,11 +76,13 @@
   stub(graal_arithmetic_drem)        \
   stub(graal_monitorenter)           \
   stub(graal_monitorexit)            \
-  stub(graal_verify_pointer)         \
+  stub(graal_verify_oop)         \
   stub(graal_set_deopt_info)         \
   stub(graal_create_null_pointer_exception) \
   stub(graal_create_out_of_bounds_exception) \
   stub(graal_generic_callback)       \
+  stub(graal_log_object)             \
+  stub(graal_log_primitive)          \
   last_entry(number_of_ids)
 #else
 #define RUNTIME1_STUBS(stub, last_entry) \
@@ -199,8 +201,13 @@
   static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock);
   static void monitorexit (JavaThread* thread, BasicObjectLock* lock);
 #ifdef GRAAL
+  static void graal_create_null_exception(JavaThread* thread);
+  static void graal_create_out_of_bounds_exception(JavaThread* thread, jint index);
+  static void graal_generic_callback(JavaThread* thread, oop _callback, oop _argument);
   static void graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);
   static void graal_monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock);
+  static void graal_log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
+  static void graal_log_object(JavaThread* thread, oop msg, jboolean newline, jboolean string);
 #endif
 
   static void deoptimize(JavaThread* thread);
--- a/src/share/vm/classfile/systemDictionary.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -186,47 +186,49 @@
   template(Short_klass,                  java_lang_Short,                Pre) \
   template(Integer_klass,                java_lang_Integer,              Pre) \
   template(Long_klass,                   java_lang_Long,                 Pre) \
-                                                                                                                         \
-  /* Support for Graal */                                                                                                \
-  template(HotSpotTypeResolved_klass,             com_oracle_graal_hotspot_HotSpotTypeResolved,                 Opt) \
-  template(HotSpotType_klass,                     com_oracle_graal_hotspot_HotSpotType,                         Opt) \
-  template(HotSpotField_klass,                    com_oracle_graal_hotspot_HotSpotField,                        Opt) \
-  template(HotSpotCompiledMethod_klass,           com_oracle_graal_hotspot_HotSpotCompiledMethod,               Opt) \
-  template(HotSpotCodeInfo_klass,                 com_oracle_graal_hotspot_HotSpotCodeInfo,                     Opt) \
-  template(HotSpotMethodResolved_klass,           com_oracle_graal_hotspot_ri_HotSpotMethodResolved,            Opt) \
-  template(HotSpotMethodData_klass,               com_oracle_graal_hotspot_ri_HotSpotMethodData,                Opt) \
-  template(HotSpotTargetMethod_klass,             com_oracle_graal_hotspot_HotSpotTargetMethod,                 Opt) \
-  template(HotSpotExceptionHandler_klass,         com_oracle_graal_hotspot_HotSpotExceptionHandler,             Opt) \
+                                                                                                                     \
+  /* Support for Graal */                                                                                            \
+  template(GraalBitMap_klass,                     java_util_BitSet,                                             Opt) \
+  /* graal.hotspot */                                                                                                \
+  template(HotSpotKlassOop_klass,                 com_oracle_graal_hotspot_HotSpotKlassOop,                     Opt) \
   template(HotSpotProxy_klass,                    com_oracle_graal_hotspot_HotSpotProxy,                        Opt) \
-  template(CiAssumptions_klass,                   com_oracle_max_cri_ci_CiAssumptions,                              Opt) \
-  template(CiAssumptions_MethodContents_klass,    com_oracle_max_cri_ci_CiAssumptions_MethodContents,               Opt) \
-  template(CiAssumptions_ConcreteSubtype_klass,   com_oracle_max_cri_ci_CiAssumptions_ConcreteSubtype,              Opt) \
-  template(CiAssumptions_ConcreteMethod_klass,    com_oracle_max_cri_ci_CiAssumptions_ConcreteMethod,               Opt) \
-  template(CiTargetMethod_klass,                  com_oracle_max_cri_ci_CiTargetMethod,                             Opt) \
-  template(CiTargetMethod_Site_klass,             com_oracle_max_cri_ci_CiTargetMethod_Site,                        Opt) \
-  template(CiTargetMethod_Call_klass,             com_oracle_max_cri_ci_CiTargetMethod_Call,                        Opt) \
-  template(CiTargetMethod_DataPatch_klass,        com_oracle_max_cri_ci_CiTargetMethod_DataPatch,                   Opt) \
-  template(CiTargetMethod_Safepoint_klass,        com_oracle_max_cri_ci_CiTargetMethod_Safepoint,                   Opt) \
-  template(CiTargetMethod_ExceptionHandler_klass, com_oracle_max_cri_ci_CiTargetMethod_ExceptionHandler,            Opt) \
-  template(CiTargetMethod_Mark_klass,             com_oracle_max_cri_ci_CiTargetMethod_Mark,                        Opt) \
-  template(GraalBitMap_klass,                     com_oracle_max_cri_ci_CiBitMap,                                   Opt) \
-  template(CiDebugInfo_klass,                     com_oracle_max_cri_ci_CiDebugInfo,                                Opt) \
-  template(CiFrame_klass,                         com_oracle_max_cri_ci_CiFrame,                                    Opt) \
-  template(CiValue_klass,                         com_oracle_max_cri_ci_CiValue,                                    Opt) \
-  template(CiStackSlot_klass,                     com_oracle_max_cri_ci_CiStackSlot,                                Opt) \
-  template(CiRegisterValue_klass,                 com_oracle_max_cri_ci_CiRegisterValue,                            Opt) \
-  template(CiRegister_klass,                      com_oracle_max_cri_ci_CiRegister,                                 Opt) \
-  template(CiCodePos_klass,                       com_oracle_max_cri_ci_CiCodePos,                                  Opt) \
-  template(CiConstant_klass,                      com_oracle_max_cri_ci_CiConstant,                                 Opt) \
-  template(CiVirtualObject_klass,                 com_oracle_max_cri_ci_CiVirtualObject,                            Opt) \
-  template(CiMonitorValue_klass,                  com_oracle_max_cri_ci_CiMonitorValue,                             Opt) \
-  template(CiKind_klass,                          com_oracle_max_cri_ci_CiKind,                                     Opt) \
-  template(CiRuntimeCall_klass,                   com_oracle_max_cri_ci_CiRuntimeCall,                              Opt) \
-  template(RiMethod_klass,                        com_oracle_max_cri_ri_RiMethod,                                   Opt) \
-  template(RiType_klass,                          com_oracle_max_cri_ri_RiType,                                     Opt) \
-  template(RiResolvedField_klass,                 com_oracle_max_cri_ri_RiResolvedField,                            Opt) \
-  template(RiExceptionHandler_klass,              com_oracle_max_cri_ri_RiExceptionHandler,                         Opt) \
-
+  template(HotSpotTargetMethod_klass,             com_oracle_graal_hotspot_HotSpotTargetMethod,                 Opt) \
+  template(HotSpotCodeInfo_klass,                 com_oracle_graal_hotspot_meta_HotSpotCodeInfo,                Opt) \
+  template(HotSpotCompiledMethod_klass,           com_oracle_graal_hotspot_meta_HotSpotCompiledMethod,          Opt) \
+  template(HotSpotJavaType_klass,                 com_oracle_graal_hotspot_meta_HotSpotJavaType,                Opt) \
+  template(HotSpotMethodData_klass,               com_oracle_graal_hotspot_meta_HotSpotMethodData,              Opt) \
+  template(HotSpotResolvedJavaField_klass,        com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField,       Opt) \
+  template(HotSpotResolvedJavaMethod_klass,       com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod,      Opt) \
+  template(HotSpotResolvedJavaType_klass,         com_oracle_graal_hotspot_meta_HotSpotResolvedJavaType,        Opt) \
+  /* graal.api.code */                                                                                               \
+  template(Assumptions_klass,                     com_oracle_graal_api_code_Assumptions,                        Opt) \
+  template(Assumptions_ConcreteMethod_klass,      com_oracle_graal_api_code_Assumptions_ConcreteMethod,         Opt) \
+  template(Assumptions_ConcreteSubtype_klass,     com_oracle_graal_api_code_Assumptions_ConcreteSubtype,        Opt) \
+  template(Assumptions_MethodContents_klass,      com_oracle_graal_api_code_Assumptions_MethodContents,         Opt) \
+  template(BytecodePosition_klass,                com_oracle_graal_api_code_BytecodePosition,                   Opt) \
+  template(DebugInfo_klass,                       com_oracle_graal_api_code_DebugInfo,                          Opt) \
+  template(BytecodeFrame_klass,                   com_oracle_graal_api_code_BytecodeFrame,                      Opt) \
+  template(InstalledCode_klass,                   com_oracle_graal_api_code_InstalledCode,                      Opt) \
+  template(InstalledCode_Call_klass,              com_oracle_graal_api_code_InstalledCode_Call,                 Opt) \
+  template(InstalledCode_DataPatch_klass,         com_oracle_graal_api_code_InstalledCode_DataPatch,            Opt) \
+  template(InstalledCode_ExceptionHandler_klass,  com_oracle_graal_api_code_InstalledCode_ExceptionHandler,     Opt) \
+  template(InstalledCode_Mark_klass,              com_oracle_graal_api_code_InstalledCode_Mark,                 Opt) \
+  template(InstalledCode_Safepoint_klass,         com_oracle_graal_api_code_InstalledCode_Safepoint,            Opt) \
+  template(InstalledCode_Site_klass,              com_oracle_graal_api_code_InstalledCode_Site,                 Opt) \
+  template(code_MonitorValue_klass,               com_oracle_graal_api_code_MonitorValue,                       Opt) \
+  template(code_Register_klass,                   com_oracle_graal_api_code_Register,                           Opt) \
+  template(RegisterValue_klass,                   com_oracle_graal_api_code_RegisterValue,                      Opt) \
+  template(RuntimeCall_klass,                     com_oracle_graal_api_code_RuntimeCall,                        Opt) \
+  template(StackSlot_klass,                       com_oracle_graal_api_code_StackSlot,                          Opt) \
+  template(VirtualObject_klass,                   com_oracle_graal_api_code_VirtualObject,                      Opt) \
+  /* graal.api.meta */                                                                                               \
+  template(Constant_klass,                        com_oracle_graal_api_meta_Constant,                           Opt) \
+  template(ExceptionHandler_klass,                com_oracle_graal_api_meta_ExceptionHandler,                   Opt) \
+  template(Kind_klass,                            com_oracle_graal_api_meta_Kind,                               Opt) \
+  template(JavaMethod_klass,                      com_oracle_graal_api_meta_JavaMethod,                         Opt) \
+  template(JavaType_klass,                        com_oracle_graal_api_meta_JavaType,                           Opt) \
+  template(ResolvedJavaField_klass,               com_oracle_graal_api_meta_ResolvedJavaField,                  Opt) \
+  template(Value_klass,                           com_oracle_graal_api_meta_Value,                              Opt) \
   /*end*/
 
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -267,93 +267,92 @@
   NOT_LP64(  do_alias(intptr_signature,               int_signature)  )                           \
   LP64_ONLY( do_alias(intptr_signature,               long_signature) )                           \
   template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
-                                                                                                                                          \
-  /* Support for Graal */                                                                                                                 \
-  template(com_oracle_graal_hotspot_bridge_VMToCompiler,          "com/oracle/graal/hotspot/bridge/VMToCompiler")                 \
-  template(com_oracle_graal_hotspot_ri_HotSpotMethodResolved,     "com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl")        \
-  template(com_oracle_graal_hotspot_HotSpotTargetMethod,          "com/oracle/graal/hotspot/HotSpotTargetMethod")                 \
-  template(com_oracle_graal_hotspot_ri_HotSpotMethodData,         "com/oracle/graal/hotspot/ri/HotSpotMethodData")                \
-  template(com_oracle_graal_hotspot_HotSpotCodeInfo,              "com/oracle/graal/hotspot/ri/HotSpotCodeInfo")                  \
-  template(com_oracle_graal_hotspot_HotSpotField,                 "com/oracle/graal/hotspot/ri/HotSpotField")                     \
-  template(com_oracle_graal_hotspot_HotSpotCompiledMethod,        "com/oracle/graal/hotspot/ri/HotSpotCompiledMethod")            \
-  template(com_oracle_graal_hotspot_HotSpotOptions,               "com/oracle/graal/hotspot/HotSpotOptions")                      \
-  template(com_oracle_graal_hotspot_HotSpotTypeResolved,          "com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl")          \
-  template(com_oracle_graal_hotspot_HotSpotType,                  "com/oracle/graal/hotspot/ri/HotSpotType")                      \
-  template(com_oracle_graal_hotspot_HotSpotExceptionHandler,      "com/oracle/graal/hotspot/ri/HotSpotExceptionHandler")          \
-  template(com_oracle_graal_hotspot_HotSpotProxy,                 "com/oracle/graal/hotspot/HotSpotProxy")                        \
-  template(com_oracle_graal_hotspot_Compiler,                     "com/oracle/graal/hotspot/Compiler")                            \
-  template(com_oracle_graal_hotspot_CompilerImpl,                 "com/oracle/graal/hotspot/CompilerImpl")                        \
-  template(com_oracle_max_cri_ri_RiMethod,                            "com/oracle/max/cri/ri/RiMethod")                                   \
-  template(com_oracle_max_cri_ri_RiResolvedField,                     "com/oracle/max/cri/ri/RiResolvedField")                            \
-  template(com_oracle_max_cri_ri_RiType,                              "com/oracle/max/cri/ri/RiType")                                     \
-  template(com_oracle_max_cri_ri_RiConstantPool,                      "com/oracle/max/cri/ri/RiConstantPool")                             \
-  template(com_oracle_max_cri_ri_RiExceptionHandler,                  "com/oracle/max/cri/ri/RiExceptionHandler")                         \
-  template(com_oracle_max_cri_ci_CiAssumptions,                       "com/oracle/max/cri/ci/CiAssumptions")                              \
-  template(com_oracle_max_cri_ci_CiAssumptions_MethodContents,        "com/oracle/max/cri/ci/CiAssumptions$MethodContents")               \
-  template(com_oracle_max_cri_ci_CiAssumptions_ConcreteSubtype,       "com/oracle/max/cri/ci/CiAssumptions$ConcreteSubtype")              \
-  template(com_oracle_max_cri_ci_CiAssumptions_ConcreteMethod,        "com/oracle/max/cri/ci/CiAssumptions$ConcreteMethod")               \
-  template(com_oracle_max_cri_ci_CiGenericCallback,                   "com/oracle/max/cri/ci/CiGenericCallback")                          \
-  template(com_oracle_max_cri_ci_CiTargetMethod,                      "com/oracle/max/cri/ci/CiTargetMethod")                             \
-  template(com_oracle_max_cri_ci_CiTargetMethod_Site,                 "com/oracle/max/cri/ci/CiTargetMethod$Site")                        \
-  template(com_oracle_max_cri_ci_CiTargetMethod_Call,                 "com/oracle/max/cri/ci/CiTargetMethod$Call")                        \
-  template(com_oracle_max_cri_ci_CiTargetMethod_DataPatch,            "com/oracle/max/cri/ci/CiTargetMethod$DataPatch")                   \
-  template(com_oracle_max_cri_ci_CiTargetMethod_Safepoint,            "com/oracle/max/cri/ci/CiTargetMethod$Safepoint")                   \
-  template(com_oracle_max_cri_ci_CiTargetMethod_ExceptionHandler,     "com/oracle/max/cri/ci/CiTargetMethod$ExceptionHandler")            \
-  template(com_oracle_max_cri_ci_CiTargetMethod_Mark,                 "com/oracle/max/cri/ci/CiTargetMethod$Mark")                        \
-  template(com_oracle_graal_graph_BitMap,                         "com/oracle/graal/graph/BitMap")                                \
-  template(com_oracle_max_cri_ci_CiBitMap,	                          "com/oracle/max/cri/ci/CiBitMap")                                   \
-  template(com_oracle_max_cri_ci_CiDebugInfo,                         "com/oracle/max/cri/ci/CiDebugInfo")                                \
-  template(com_oracle_max_cri_ci_CiFrame,                             "com/oracle/max/cri/ci/CiFrame")                                    \
-  template(com_oracle_max_cri_ci_CiValue,                             "com/oracle/max/cri/ci/CiValue")                                    \
-  template(com_oracle_max_cri_ci_CiStackSlot,                         "com/oracle/max/cri/ci/CiStackSlot")                                \
-  template(com_oracle_max_cri_ci_CiRegisterValue,                     "com/oracle/max/cri/ci/CiRegisterValue")                            \
-  template(com_oracle_max_cri_ci_CiRegister,                          "com/oracle/max/cri/ci/CiRegister")                                 \
-  template(com_oracle_max_cri_ci_CiCodePos,                           "com/oracle/max/cri/ci/CiCodePos")                                  \
-  template(com_oracle_max_cri_ci_CiConstant,                          "com/oracle/max/cri/ci/CiConstant")                                 \
-  template(com_oracle_max_cri_ci_CiVirtualObject,                     "com/oracle/max/cri/ci/CiVirtualObject")                            \
-  template(com_oracle_max_cri_ci_CiMonitorValue,                      "com/oracle/max/cri/ci/CiMonitorValue")                             \
-  template(com_oracle_max_cri_ci_CiKind,                              "com/oracle/max/cri/ci/CiKind")                                     \
-  template(com_oracle_max_cri_ci_CiRuntimeCall,                       "com/oracle/max/cri/ci/CiRuntimeCall")                              \
-  template(startCompiler_name,                        "startCompiler")                                                  \
-  template(bootstrap_name,                            "bootstrap")                                                      \
-  template(shutdownCompiler_name,                     "shutdownCompiler")                                               \
-  template(compileMethod_name,                        "compileMethod")                                                  \
-  template(compileMethod_signature,                   "(Lcom/oracle/graal/hotspot/ri/HotSpotMethodResolved;IZI)Z")      \
-  template(setOption_name,                            "setOption")                                                      \
-  template(setDefaultOptions_name,                    "setDefaultOptions")                                              \
-  template(setOption_signature,                       "(Ljava/lang/String;)Z")                                          \
-  template(createRiMethodResolved_name,               "createRiMethodResolved")                                         \
-  template(createRiMethodResolved_signature,          "(JLjava/lang/String;)Lcom/oracle/max/cri/ri/RiMethod;")          \
-  template(createRiMethodUnresolved_name,             "createRiMethodUnresolved")                                       \
-  template(createRiMethodUnresolved_signature,        "(Ljava/lang/String;Ljava/lang/String;Lcom/oracle/max/cri/ri/RiType;)Lcom/oracle/max/cri/ri/RiMethod;") \
-  template(createRiSignature_name,                    "createRiSignature")                                              \
-  template(createRiSignature_signature,               "(Ljava/lang/String;)Lcom/oracle/max/cri/ri/RiSignature;")        \
-  template(createRiField_name,                        "createRiField")                                                  \
-  template(createRiField_signature,                   "(Lcom/oracle/max/cri/ri/RiType;Ljava/lang/String;Lcom/oracle/max/cri/ri/RiType;II)Lcom/oracle/max/cri/ri/RiField;") \
-  template(createRiType_name,                         "createRiType")                                                   \
-  template(createRiType_signature,                    "(JLjava/lang/String;)Lcom/oracle/max/cri/ri/RiType;")            \
-  template(createRiTypePrimitive_name,                "createRiTypePrimitive")                                          \
-  template(createRiTypePrimitive_signature,           "(I)Lcom/oracle/max/cri/ri/RiType;")                              \
-  template(createRiTypeUnresolved_name,               "createRiTypeUnresolved")                                         \
-  template(createRiTypeUnresolved_signature,          "(Ljava/lang/String;)Lcom/oracle/max/cri/ri/RiType;")             \
-  template(createCiConstant_name,                     "createCiConstant")                                               \
-  template(createCiConstant_signature,                "(Lcom/oracle/max/cri/ci/CiKind;J)Lcom/oracle/max/cri/ci/CiConstant;") \
-  template(createCiConstantFloat_name,                "createCiConstantFloat")                                          \
-  template(createCiConstantFloat_signature,           "(F)Lcom/oracle/max/cri/ci/CiConstant;")                          \
-  template(createCiConstantDouble_name,               "createCiConstantDouble")                                         \
-  template(createCiConstantDouble_signature,          "(D)Lcom/oracle/max/cri/ci/CiConstant;")                          \
-  template(createCiConstantObject_name,               "createCiConstantObject")                                         \
-  template(createCiConstantObject_signature,          "(Ljava/lang/Object;)Lcom/oracle/max/cri/ci/CiConstant;")         \
-  template(getVMToCompiler_name,                      "getVMToCompiler")                                                     \
-  template(getVMToCompiler_signature,                 "()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;")               \
-  template(getInstance_name,                          "getInstance")                                                    \
-  template(initialize_name,                           "initialize")                                                     \
-  template(getInstance_signature,                     "()Lcom/oracle/graal/hotspot/Compiler;")                          \
-  template(forObject_name,                            "forObject")                                                      \
-  template(callbackInternal_name,                     "callbackInternal")                                               \
-  template(callback_signature,                        "(Ljava/lang/Object;)Ljava/lang/Object;")                         \
-  template(MethodInvalidatedException,                "com/oracle/max/cri/ri/RiCompiledMethod$MethodInvalidatedException") \
-                                                                                                                        \
+                                                                                                                                      \
+  /* Support for Graal */                                                                                                             \
+  template(java_util_BitSet,	                                       "java/util/BitSet")                                              \
+  /* graal.hotspot */                                                                                                                 \
+  template(com_oracle_graal_hotspot_HotSpotGraalRuntime,             "com/oracle/graal/hotspot/HotSpotGraalRuntime")                  \
+  template(com_oracle_graal_hotspot_HotSpotKlassOop,                 "com/oracle/graal/hotspot/HotSpotKlassOop")                      \
+  template(com_oracle_graal_hotspot_HotSpotOptions,                  "com/oracle/graal/hotspot/HotSpotOptions")                       \
+  template(com_oracle_graal_hotspot_HotSpotProxy,                    "com/oracle/graal/hotspot/HotSpotProxy")                         \
+  template(com_oracle_graal_hotspot_HotSpotTargetMethod,             "com/oracle/graal/hotspot/HotSpotTargetMethod")                  \
+  template(com_oracle_graal_hotspot_bridge_VMToCompiler,             "com/oracle/graal/hotspot/bridge/VMToCompiler")                  \
+  template(com_oracle_graal_hotspot_meta_HotSpotCodeInfo,            "com/oracle/graal/hotspot/meta/HotSpotCodeInfo")                 \
+  template(com_oracle_graal_hotspot_meta_HotSpotCompiledMethod,      "com/oracle/graal/hotspot/meta/HotSpotCompiledMethod")           \
+  template(com_oracle_graal_hotspot_meta_HotSpotJavaType,            "com/oracle/graal/hotspot/meta/HotSpotJavaType")                 \
+  template(com_oracle_graal_hotspot_meta_HotSpotMethodData,          "com/oracle/graal/hotspot/meta/HotSpotMethodData")               \
+  template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField,   "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField")        \
+  template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod,  "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod")       \
+  template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaType,    "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType")         \
+  /* graal.api.meta */                                                                                                                \
+  template(com_oracle_graal_api_meta_Constant,                       "com/oracle/graal/api/meta/Constant")                            \
+  template(com_oracle_graal_api_meta_ConstantPool,                   "com/oracle/graal/api/meta/ConstantPool")                        \
+  template(com_oracle_graal_api_meta_ExceptionHandler,               "com/oracle/graal/api/meta/ExceptionHandler")                    \
+  template(com_oracle_graal_api_meta_JavaMethod,                     "com/oracle/graal/api/meta/JavaMethod")                          \
+  template(com_oracle_graal_api_meta_JavaType,                       "com/oracle/graal/api/meta/JavaType")                            \
+  template(com_oracle_graal_api_meta_Kind,                           "com/oracle/graal/api/meta/Kind")                                \
+  template(com_oracle_graal_api_meta_ResolvedJavaField,              "com/oracle/graal/api/meta/ResolvedJavaField")                   \
+  template(com_oracle_graal_api_meta_Value,                          "com/oracle/graal/api/meta/Value")                               \
+  /* graal.api.code */                                                                                                                \
+  template(com_oracle_graal_api_code_Assumptions,                    "com/oracle/graal/api/code/Assumptions")                         \
+  template(com_oracle_graal_api_code_Assumptions_MethodContents,     "com/oracle/graal/api/code/Assumptions$MethodContents")          \
+  template(com_oracle_graal_api_code_Assumptions_ConcreteSubtype,    "com/oracle/graal/api/code/Assumptions$ConcreteSubtype")         \
+  template(com_oracle_graal_api_code_Assumptions_ConcreteMethod,     "com/oracle/graal/api/code/Assumptions$ConcreteMethod")          \
+  template(com_oracle_graal_api_code_GenericCallback,                "com/oracle/graal/api/code/GenericCallback")                     \
+  template(com_oracle_graal_api_code_InstalledCode,                  "com/oracle/graal/api/code/CompilationResult")                   \
+  template(com_oracle_graal_api_code_InstalledCode_Call,             "com/oracle/graal/api/code/CompilationResult$Call")              \
+  template(com_oracle_graal_api_code_InstalledCode_DataPatch,        "com/oracle/graal/api/code/CompilationResult$DataPatch")         \
+  template(com_oracle_graal_api_code_InstalledCode_ExceptionHandler, "com/oracle/graal/api/code/CompilationResult$ExceptionHandler")  \
+  template(com_oracle_graal_api_code_InstalledCode_Mark,             "com/oracle/graal/api/code/CompilationResult$Mark")              \
+  template(com_oracle_graal_api_code_InstalledCode_Safepoint,        "com/oracle/graal/api/code/CompilationResult$Safepoint")         \
+  template(com_oracle_graal_api_code_InstalledCode_Site,             "com/oracle/graal/api/code/CompilationResult$Site")              \
+  template(com_oracle_graal_api_code_BytecodeFrame,                  "com/oracle/graal/api/code/BytecodeFrame")                       \
+  template(com_oracle_graal_api_code_BytecodePosition,               "com/oracle/graal/api/code/BytecodePosition")                    \
+  template(com_oracle_graal_api_code_DebugInfo,                      "com/oracle/graal/api/code/DebugInfo")                           \
+  template(com_oracle_graal_api_code_MonitorValue,                   "com/oracle/graal/api/code/MonitorValue")                        \
+  template(com_oracle_graal_api_code_Register,                       "com/oracle/graal/api/code/Register")                            \
+  template(com_oracle_graal_api_code_RegisterValue,                  "com/oracle/graal/api/code/RegisterValue")                       \
+  template(com_oracle_graal_api_code_RuntimeCall,                    "com/oracle/graal/api/code/RuntimeCall")                         \
+  template(com_oracle_graal_api_code_StackSlot,                      "com/oracle/graal/api/code/StackSlot")                           \
+  template(com_oracle_graal_api_code_VirtualObject,                  "com/oracle/graal/api/code/VirtualObject")                       \
+  template(startCompiler_name,                    "startCompiler")                                                                    \
+  template(bootstrap_name,                        "bootstrap")                                                                        \
+  template(shutdownCompiler_name,                 "shutdownCompiler")                                                                 \
+  template(compileMethod_name,                    "compileMethod")                                                                    \
+  template(compileMethod_signature,               "(Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;IZI)Z")                  \
+  template(setOption_name,                        "setOption")                                                                        \
+  template(setDefaultOptions_name,                "setDefaultOptions")                                                                \
+  template(setOption_signature,                   "(Ljava/lang/String;)Z")                                                            \
+  template(createResolvedJavaMethod_name,         "createResolvedJavaMethod")                                                         \
+  template(createResolvedJavaMethod_signature,    "(JLjava/lang/String;)Lcom/oracle/graal/api/meta/JavaMethod;")                      \
+  template(createJavaMethod_name,                 "createJavaMethod")                                                                 \
+  template(createJavaMethod_signature,            "(Ljava/lang/String;Ljava/lang/String;Lcom/oracle/graal/api/meta/JavaType;)Lcom/oracle/graal/api/meta/JavaMethod;") \
+  template(createSignature_name,                  "createSignature")                                                                  \
+  template(createSignature_signature,             "(Ljava/lang/String;)Lcom/oracle/graal/api/meta/Signature;")                        \
+  template(createJavaField_name,                  "createJavaField")                                                                  \
+  template(createJavaField_signature,             "(Lcom/oracle/graal/api/meta/JavaType;Ljava/lang/String;Lcom/oracle/graal/api/meta/JavaType;II)Lcom/oracle/graal/api/meta/JavaField;") \
+  template(createJavaType_name,                   "createJavaType")                                                                   \
+  template(createJavaType_signature,              "(Ljava/lang/String;)Lcom/oracle/graal/api/meta/JavaType;")                         \
+  template(createPrimitiveJavaType_name,          "createPrimitiveJavaType")                                                          \
+  template(createPrimitiveJavaType_signature,     "(I)Lcom/oracle/graal/api/meta/JavaType;")                                          \
+  template(createConstant_name,                   "createConstant")                                                                   \
+  template(createConstant_signature,              "(Lcom/oracle/graal/api/meta/Kind;J)Lcom/oracle/graal/api/meta/Constant;")          \
+  template(createConstantFloat_name,              "createConstantFloat")                                                              \
+  template(createConstantFloat_signature,         "(F)Lcom/oracle/graal/api/meta/Constant;")                                          \
+  template(createConstantDouble_name,             "createConstantDouble")                                                             \
+  template(createConstantDouble_signature,        "(D)Lcom/oracle/graal/api/meta/Constant;")                                          \
+  template(createConstantObject_name,             "createConstantObject")                                                             \
+  template(createConstantObject_signature,        "(Ljava/lang/Object;)Lcom/oracle/graal/api/meta/Constant;")                         \
+  template(getVMToCompiler_name,                  "getVMToCompiler")                                                                  \
+  template(getVMToCompiler_signature,             "()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;")                                 \
+  template(getInstance_name,                      "getInstance")                                                                      \
+  template(initialize_name,                       "initialize")                                                                       \
+  template(getInstance_signature,                 "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;")                                 \
+  template(forObject_name,                        "forObject")                                                                        \
+  template(callbackInternal_name,                 "callbackInternal")                                                                 \
+  template(callback_signature,                    "(Ljava/lang/Object;)Ljava/lang/Object;")                                           \
+  template(MethodInvalidatedException,            "com/oracle/graal/api/meta/InstalledCode$MethodInvalidatedException")               \
+                                                                                                                                      \
                                                                                                   \
   /* common method and field names */                                                             \
   template(object_initializer_name,                   "<init>")                                   \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -53,28 +53,28 @@
   }
 }
 
+const int MapWordBits = 64;
+
 static bool is_bit_set(oop bit_map, int i) {
-  const int MapWordBits = 64;
-  if (i < MapWordBits) {
-    jlong low = GraalBitMap::low(bit_map);
-    return (low & (1LL << i)) != 0;
-  } else {
-    jint extra_idx = (i - MapWordBits) / MapWordBits;
-    arrayOop extra = (arrayOop) GraalBitMap::extra(bit_map);
-    assert(extra_idx >= 0 && extra_idx < extra->length(), "unexpected index");
-    jlong word = ((jlong*) extra->base(T_LONG))[extra_idx];
-    return (word & (1LL << (i % MapWordBits))) != 0;
-  }
+  jint extra_idx = i / MapWordBits;
+  arrayOop extra = (arrayOop) GraalBitMap::words(bit_map);
+  assert(extra_idx >= 0 && extra_idx < extra->length(), "unexpected index");
+  jlong word = ((jlong*) extra->base(T_LONG))[extra_idx];
+  return (word & (1LL << (i % MapWordBits))) != 0;
 }
 
-// creates a hotspot oop map out of the byte arrays provided by CiDebugInfo
+static int bitmap_size(oop bit_map) {
+  arrayOop arr = (arrayOop) GraalBitMap::words(bit_map);
+  return arr->length() * MapWordBits;
+}
+
+// creates a hotspot oop map out of the byte arrays provided by DebugInfo
 static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) {
   OopMap* map = new OopMap(total_frame_size, parameter_count);
-  oop register_map = (oop) CiDebugInfo::registerRefMap(debug_info);
-  oop frame_map = (oop) CiDebugInfo::frameRefMap(debug_info);
+  oop register_map = (oop) DebugInfo::registerRefMap(debug_info);
+  oop frame_map = (oop) DebugInfo::frameRefMap(debug_info);
 
   if (register_map != NULL) {
-    assert(GraalBitMap::size(register_map) == (unsigned) NUM_CPU_REGS, "unexpected register_map length");
     for (jint i = 0; i < NUM_CPU_REGS; i++) {
       bool is_oop = is_bit_set(register_map, i);
       VMReg reg = get_hotspot_reg(i);
@@ -87,7 +87,7 @@
     }
   }
 
-  for (jint i = 0; i < GraalBitMap::size(frame_map); i++) {
+  for (jint i = 0; i < bitmap_size(frame_map); i++) {
     bool is_oop = is_bit_set(frame_map, i);
     // hotspot stack slots are 4 bytes
     VMReg reg = VMRegImpl::stack2reg(i * 2);
@@ -104,16 +104,16 @@
 // TODO: finish this - graal doesn't provide any scope values at the moment
 static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) {
   second = NULL;
-  if (value == CiValue::IllegalValue()) {
+  if (value == Value::IllegalValue()) {
     return new LocationValue(Location::new_stk_loc(Location::invalid, 0));
   }
 
-  BasicType type = GraalCompiler::kindToBasicType(CiKind::typeChar(CiValue::kind(value)));
+  BasicType type = GraalCompiler::kindToBasicType(Kind::typeChar(Value::kind(value)));
   Location::Type locationType = Location::normal;
   if (type == T_OBJECT || type == T_ARRAY) locationType = Location::oop;
 
-  if (value->is_a(CiRegisterValue::klass())) {
-    jint number = CiRegister::number(CiRegisterValue::reg(value));
+  if (value->is_a(RegisterValue::klass())) {
+    jint number = code_Register::number(RegisterValue::reg(value));
     if (number < 16) {
       if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE || type == T_ADDRESS) {
         locationType = Location::int_in_long;
@@ -141,14 +141,14 @@
       }
       return value;
     }
-  } else if (value->is_a(CiStackSlot::klass())) {
+  } else if (value->is_a(StackSlot::klass())) {
     if (type == T_DOUBLE) {
       locationType = Location::dbl;
     } else if (type == T_LONG) {
       locationType = Location::lng;
     }
-    jint offset = CiStackSlot::offset(value);
-    if (CiStackSlot::addFrameSize(value)) {
+    jint offset = StackSlot::offset(value);
+    if (StackSlot::addFrameSize(value)) {
       offset += total_frame_size;
     }
     ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset));
@@ -156,16 +156,16 @@
       second = value;
     }
     return value;
-  } else if (value->is_a(CiConstant::klass())){
-    oop obj = CiConstant::object(value);
-    jlong prim = CiConstant::primitive(value);
+  } else if (value->is_a(Constant::klass())){
+    oop obj = Constant::object(value);
+    jlong prim = Constant::primitive(value);
     if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) {
       return new ConstantIntValue(*(jint*)&prim);
     } else if (type == T_LONG || type == T_DOUBLE) {
       second = new ConstantIntValue(0);
       return new ConstantLongValue(prim);
     } else if (type == T_OBJECT) {
-      oop obj = CiConstant::object(value);
+      oop obj = Constant::object(value);
       if (obj == NULL) {
         return new ConstantOopWriteValue(NULL);
       } else {
@@ -175,10 +175,10 @@
       return new ConstantLongValue(prim);
     }
     tty->print("%i", type);
-  } else if (value->is_a(CiVirtualObject::klass())) {
-    oop type = CiVirtualObject::type(value);
-    int id = CiVirtualObject::id(value);
-    klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type));
+  } else if (value->is_a(VirtualObject::klass())) {
+    oop type = VirtualObject::type(value);
+    int id = VirtualObject::id(value);
+    klassOop klass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(type));
     bool isLongArray = klass == Universe::longArrayKlassObj();
 
     for (jint i = 0; i < objects->length(); i++) {
@@ -190,7 +190,7 @@
 
     ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), klass)));
 
-    arrayOop values = (arrayOop) CiVirtualObject::values(value);
+    arrayOop values = (arrayOop) VirtualObject::values(value);
     for (jint i = 0; i < values->length(); i++) {
       ((oop*) values->base(T_OBJECT))[i];
     }
@@ -226,19 +226,19 @@
 }
 
 static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects) {
-  guarantee(value->is_a(CiMonitorValue::klass()), "Monitors must be of type CiMonitorValue");
+  guarantee(value->is_a(code_MonitorValue::klass()), "Monitors must be of type MonitorValue");
 
   ScopeValue* second = NULL;
-  ScopeValue* owner_value = get_hotspot_value(CiMonitorValue::owner(value), total_frame_size, objects, second);
+  ScopeValue* owner_value = get_hotspot_value(code_MonitorValue::owner(value), total_frame_size, objects, second);
   assert(second == NULL, "monitor cannot occupy two stack slots");
 
-  ScopeValue* lock_data_value = get_hotspot_value(CiMonitorValue::lockData(value), total_frame_size, objects, second);
+  ScopeValue* lock_data_value = get_hotspot_value(code_MonitorValue::lockData(value), total_frame_size, objects, second);
   assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
   assert(lock_data_value->is_location(), "invalid monitor location");
   Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
 
   bool eliminated = false;
-  if (CiMonitorValue::eliminated(value)) {
+  if (code_MonitorValue::eliminated(value)) {
     eliminated = true;
   }
 
@@ -250,18 +250,18 @@
   _env->set_oop_recorder(_oop_recorder);
   _env->set_dependencies(_dependencies);
   _dependencies = new Dependencies(_env);
-  Handle assumptions_handle = CiTargetMethod::assumptions(HotSpotTargetMethod::targetMethod(target_method));
+  Handle assumptions_handle = InstalledCode::assumptions(HotSpotTargetMethod::targetMethod(target_method));
   if (!assumptions_handle.is_null()) {
-    objArrayHandle assumptions(Thread::current(), (objArrayOop)CiAssumptions::list(assumptions_handle()));
+    objArrayHandle assumptions(Thread::current(), (objArrayOop)Assumptions::list(assumptions_handle()));
     int length = assumptions->length();
     for (int i = 0; i < length; ++i) {
       Handle assumption = assumptions->obj_at(i);
       if (!assumption.is_null()) {
-        if (assumption->klass() == CiAssumptions_MethodContents::klass()) {
+        if (assumption->klass() == Assumptions_MethodContents::klass()) {
           assumption_MethodContents(assumption);
-        } else if (assumption->klass() == CiAssumptions_ConcreteSubtype::klass()) {
+        } else if (assumption->klass() == Assumptions_ConcreteSubtype::klass()) {
           assumption_ConcreteSubtype(assumption);
-        } else if (assumption->klass() == CiAssumptions_ConcreteMethod::klass()) {
+        } else if (assumption->klass() == Assumptions_ConcreteMethod::klass()) {
           assumption_ConcreteMethod(assumption);
         } else {
           assumption->print();
@@ -327,11 +327,11 @@
   _sites = (arrayOop) HotSpotTargetMethod::sites(target_method);
   _exception_handlers = (arrayOop) HotSpotTargetMethod::exceptionHandlers(target_method);
 
-  _code = (arrayOop) CiTargetMethod::targetCode(_citarget_method);
-  _code_size = CiTargetMethod::targetCodeSize(_citarget_method);
+  _code = (arrayOop) InstalledCode::targetCode(_citarget_method);
+  _code_size = InstalledCode::targetCodeSize(_citarget_method);
   // The frame size we get from the target method does not include the return address, so add one word for it here.
-  _total_frame_size = CiTargetMethod::frameSize(_citarget_method) + HeapWordSize;
-  _custom_stack_area_offset = CiTargetMethod::customStackAreaOffset(_citarget_method);
+  _total_frame_size = InstalledCode::frameSize(_citarget_method) + HeapWordSize;
+  _custom_stack_area_offset = InstalledCode::customStackAreaOffset(_citarget_method);
 
 
   // (very) conservative estimate: each site needs a constant section entry
@@ -365,18 +365,18 @@
   oop* sites = (oop*) _sites->base(T_OBJECT);
   for (int i = 0; i < _sites->length(); i++) {
     oop site = sites[i];
-    jint pc_offset = CiTargetMethod_Site::pcOffset(site);
+    jint pc_offset = InstalledCode_Site::pcOffset(site);
 
-    if (site->is_a(CiTargetMethod_Call::klass())) {
+    if (site->is_a(InstalledCode_Call::klass())) {
       TRACE_graal_4("call at %i", pc_offset);
       site_Call(buffer, pc_offset, site);
-    } else if (site->is_a(CiTargetMethod_Safepoint::klass())) {
+    } else if (site->is_a(InstalledCode_Safepoint::klass())) {
       TRACE_graal_4("safepoint at %i", pc_offset);
       site_Safepoint(buffer, pc_offset, site);
-    } else if (site->is_a(CiTargetMethod_DataPatch::klass())) {
+    } else if (site->is_a(InstalledCode_DataPatch::klass())) {
       TRACE_graal_4("datapatch at %i", pc_offset);
       site_DataPatch(buffer, pc_offset, site);
-    } else if (site->is_a(CiTargetMethod_Mark::klass())) {
+    } else if (site->is_a(InstalledCode_Mark::klass())) {
       TRACE_graal_4("mark at %i", pc_offset);
       site_Mark(buffer, pc_offset, site);
     } else {
@@ -386,7 +386,7 @@
 }
 
 void CodeInstaller::assumption_MethodContents(Handle assumption) {
-  Handle method_handle = CiAssumptions_MethodContents::method(assumption());
+  Handle method_handle = Assumptions_MethodContents::method(assumption());
   methodHandle method = getMethodFromHotSpotMethod(method_handle());
   ciMethod* m = (ciMethod*) CURRENT_ENV->get_object(method());
 
@@ -394,11 +394,11 @@
 }
 
 void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) {
-  Handle context_handle = CiAssumptions_ConcreteSubtype::context(assumption());
-  ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(context_handle)));
+  Handle context_handle = Assumptions_ConcreteSubtype::context(assumption());
+  ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(context_handle)));
 
-  Handle type_handle = CiAssumptions_ConcreteSubtype::subtype(assumption());
-  ciKlass* type = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type_handle)));
+  Handle type_handle = Assumptions_ConcreteSubtype::subtype(assumption());
+  ciKlass* type = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(type_handle)));
 
   _dependencies->assert_leaf_type(type);
   if (context != type) {
@@ -408,12 +408,12 @@
 }
 
 void CodeInstaller::assumption_ConcreteMethod(Handle assumption) {
-  Handle impl_handle = CiAssumptions_ConcreteMethod::impl(assumption());
+  Handle impl_handle = Assumptions_ConcreteMethod::impl(assumption());
   methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
   ciMethod* m = (ciMethod*) CURRENT_ENV->get_object(impl());
   
-  Handle context_handle = CiAssumptions_ConcreteMethod::context(assumption());
-  ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(context_handle)));
+  Handle context_handle = Assumptions_ConcreteMethod::context(assumption());
+  ciKlass* context = (ciKlass*) CURRENT_ENV->get_object(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(context_handle)));
   _dependencies->assert_unique_concrete_method(context, m);
 }
 
@@ -428,8 +428,8 @@
     oop* exception_handlers = (oop*) _exception_handlers->base(T_OBJECT);
     for (int i = 0; i < _exception_handlers->length(); i++) {
       oop exc = exception_handlers[i];
-      jint pc_offset = CiTargetMethod_Site::pcOffset(exc);
-      jint handler_offset = CiTargetMethod_ExceptionHandler::handlerPos(exc);
+      jint pc_offset = InstalledCode_Site::pcOffset(exc);
+      jint handler_offset = InstalledCode_ExceptionHandler::handlerPos(exc);
 
       // Subtable header
       _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0));
@@ -441,15 +441,15 @@
 }
 
 void CodeInstaller::record_scope(jint pc_offset, oop frame, GrowableArray<ScopeValue*>* objects) {
-  assert(frame->klass() == CiFrame::klass(), "CiFrame expected");
-  oop caller_frame = CiCodePos::caller(frame);
+  assert(frame->klass() == BytecodeFrame::klass(), "BytecodeFrame expected");
+  oop caller_frame = BytecodePosition::caller(frame);
   if (caller_frame != NULL) {
     record_scope(pc_offset, caller_frame, objects);
   }
 
-  oop hotspot_method = CiCodePos::method(frame);
+  oop hotspot_method = BytecodePosition::method(frame);
   methodOop method = getMethodFromHotSpotMethod(hotspot_method);
-  jint bci = CiCodePos::bci(frame);
+  jint bci = BytecodePosition::bci(frame);
   bool reexecute;
   if (bci == -1) {
      reexecute = false;
@@ -457,7 +457,7 @@
     Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));
     reexecute = Interpreter::bytecode_should_reexecute(code);
     if (frame != NULL) {
-      reexecute = (CiFrame::duringCall(frame) == 0);
+      reexecute = (BytecodeFrame::duringCall(frame) == 0);
     }
   }
 
@@ -465,10 +465,10 @@
     tty->print_cr("Recording scope pc_offset=%d bci=%d frame=%d", pc_offset, bci, frame);
   }
 
-  jint local_count = CiFrame::numLocals(frame);
-  jint expression_count = CiFrame::numStack(frame);
-  jint monitor_count = CiFrame::numLocks(frame);
-  arrayOop values = (arrayOop) CiFrame::values(frame);
+  jint local_count = BytecodeFrame::numLocals(frame);
+  jint expression_count = BytecodeFrame::numStack(frame);
+  jint monitor_count = BytecodeFrame::numLocks(frame);
+  arrayOop values = (arrayOop) BytecodeFrame::values(frame);
 
   assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length");
 
@@ -502,8 +502,8 @@
     }
     if (second != NULL) {
       i++;
-      assert(i < values->length(), "double-slot value not followed by CiValue.IllegalValue");
-      assert(((oop*) values->base(T_OBJECT))[i] == CiValue::IllegalValue(), "double-slot value not followed by CiValue.IllegalValue");
+      assert(i < values->length(), "double-slot value not followed by Value.IllegalValue");
+      assert(((oop*) values->base(T_OBJECT))[i] == Value::IllegalValue(), "double-slot value not followed by Value.IllegalValue");
     }
   }
 
@@ -514,7 +514,7 @@
   DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors);
 
   bool throw_exception = false;
-  if (CiFrame::rethrowException(frame)) {
+  if (BytecodeFrame::rethrowException(frame)) {
     throw_exception = true;
   }
 
@@ -522,14 +522,14 @@
 }
 
 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
-  oop debug_info = CiTargetMethod_Safepoint::debugInfo(site);
+  oop debug_info = InstalledCode_Safepoint::debugInfo(site);
   assert(debug_info != NULL, "debug info expected");
 
   // address instruction = _instructions->start() + pc_offset;
   // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
   _debug_recorder->add_safepoint(pc_offset, -1, create_oop_map(_total_frame_size, _parameter_count, debug_info));
 
-  oop code_pos = CiDebugInfo::codePos(debug_info);
+  oop code_pos = DebugInfo::bytecodePosition(debug_info);
   record_scope(pc_offset, code_pos, new GrowableArray<ScopeValue*>());
 
   _debug_recorder->end_safepoint(pc_offset);
@@ -537,50 +537,56 @@
 
 address CodeInstaller::runtime_call_target_address(oop runtime_call) {
   address target_addr = 0x0;
-  if (runtime_call == CiRuntimeCall::Debug()) {
-    TRACE_graal_3("CiRuntimeCall::Debug()");
-  } else if (runtime_call == CiRuntimeCall::UnwindException()) {
+  if (runtime_call == RuntimeCall::Debug()) {
+    TRACE_graal_3("RuntimeCall::Debug()");
+  } else if (runtime_call == RuntimeCall::UnwindException()) {
     target_addr = Runtime1::entry_for(Runtime1::graal_unwind_exception_call_id);
-    TRACE_graal_3("CiRuntimeCall::UnwindException()");
-  } else if (runtime_call == CiRuntimeCall::SetDeoptInfo()) {
+    TRACE_graal_3("RuntimeCall::UnwindException()");
+  } else if (runtime_call == RuntimeCall::SetDeoptInfo()) {
     target_addr = Runtime1::entry_for(Runtime1::graal_set_deopt_info_id);
-    TRACE_graal_3("CiRuntimeCall::SetDeoptInfo()");
-  } else if (runtime_call == CiRuntimeCall::CreateNullPointerException()) {
+    TRACE_graal_3("RuntimeCall::SetDeoptInfo()");
+  } else if (runtime_call == RuntimeCall::CreateNullPointerException()) {
     target_addr = Runtime1::entry_for(Runtime1::graal_create_null_pointer_exception_id);
-    TRACE_graal_3("CiRuntimeCall::CreateNullPointerException()");
-  } else if (runtime_call == CiRuntimeCall::CreateOutOfBoundsException()) {
+    TRACE_graal_3("RuntimeCall::CreateNullPointerException()");
+  } else if (runtime_call == RuntimeCall::CreateOutOfBoundsException()) {
     target_addr = Runtime1::entry_for(Runtime1::graal_create_out_of_bounds_exception_id);
-    TRACE_graal_3("CiRuntimeCall::CreateOutOfBoundsException()");
-  } else if (runtime_call == CiRuntimeCall::JavaTimeMillis()) {
+    TRACE_graal_3("RuntimeCall::CreateOutOfBoundsException()");
+  } else if (runtime_call == RuntimeCall::JavaTimeMillis()) {
     target_addr = CAST_FROM_FN_PTR(address, os::javaTimeMillis);
-    TRACE_graal_3("CiRuntimeCall::JavaTimeMillis()");
-  } else if (runtime_call == CiRuntimeCall::JavaTimeNanos()) {
+    TRACE_graal_3("RuntimeCall::JavaTimeMillis()");
+  } else if (runtime_call == RuntimeCall::JavaTimeNanos()) {
     target_addr = CAST_FROM_FN_PTR(address, os::javaTimeNanos);
-    TRACE_graal_3("CiRuntimeCall::JavaTimeNanos()");
-  } else if (runtime_call == CiRuntimeCall::ArithmeticFrem()) {
+    TRACE_graal_3("RuntimeCall::JavaTimeNanos()");
+  } else if (runtime_call == RuntimeCall::ArithmeticFrem()) {
     target_addr = Runtime1::entry_for(Runtime1::graal_arithmetic_frem_id);
-    TRACE_graal_3("CiRuntimeCall::ArithmeticFrem()");
-  } else if (runtime_call == CiRuntimeCall::ArithmeticDrem()) {
+    TRACE_graal_3("RuntimeCall::ArithmeticFrem()");
+  } else if (runtime_call == RuntimeCall::ArithmeticDrem()) {
     target_addr = Runtime1::entry_for(Runtime1::graal_arithmetic_drem_id);
-    TRACE_graal_3("CiRuntimeCall::ArithmeticDrem()");
-  } else if (runtime_call == CiRuntimeCall::ArithmeticSin()) {
+    TRACE_graal_3("RuntimeCall::ArithmeticDrem()");
+  } else if (runtime_call == RuntimeCall::ArithmeticSin()) {
     target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
-    TRACE_graal_3("CiRuntimeCall::ArithmeticSin()");
-  } else if (runtime_call == CiRuntimeCall::ArithmeticCos()) {
+    TRACE_graal_3("RuntimeCall::ArithmeticSin()");
+  } else if (runtime_call == RuntimeCall::ArithmeticCos()) {
     target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
-    TRACE_graal_3("CiRuntimeCall::ArithmeticCos()");
-  } else if (runtime_call == CiRuntimeCall::ArithmeticTan()) {
+    TRACE_graal_3("RuntimeCall::ArithmeticCos()");
+  } else if (runtime_call == RuntimeCall::ArithmeticTan()) {
     target_addr = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
-    TRACE_graal_3("CiRuntimeCall::ArithmeticTan()");
-  } else if (runtime_call == CiRuntimeCall::RegisterFinalizer()) {
+    TRACE_graal_3("RuntimeCall::ArithmeticTan()");
+  } else if (runtime_call == RuntimeCall::RegisterFinalizer()) {
     target_addr = Runtime1::entry_for(Runtime1::register_finalizer_id);
-    TRACE_graal_3("CiRuntimeCall::RegisterFinalizer()");
-  } else if (runtime_call == CiRuntimeCall::Deoptimize()) {
+    TRACE_graal_3("RuntimeCall::RegisterFinalizer()");
+  } else if (runtime_call == RuntimeCall::Deoptimize()) {
     target_addr = SharedRuntime::deopt_blob()->uncommon_trap();
-    TRACE_graal_3("CiRuntimeCall::Deoptimize()");
-  } else if (runtime_call == CiRuntimeCall::GenericCallback()) {
+    TRACE_graal_3("RuntimeCall::Deoptimize()");
+  } else if (runtime_call == RuntimeCall::GenericCallback()) {
     target_addr = Runtime1::entry_for(Runtime1::graal_generic_callback_id);
-    TRACE_graal_3("CiRuntimeCall::GenericCallback()");
+    TRACE_graal_3("RuntimeCall::GenericCallback()");
+  } else if (runtime_call == RuntimeCall::LogPrimitive()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_log_primitive_id);
+    TRACE_graal_3("RuntimeCall::LogPrimitive()");
+  } else if (runtime_call == RuntimeCall::LogObject()) {
+    target_addr = Runtime1::entry_for(Runtime1::graal_log_object_id);
+    TRACE_graal_3("RuntimeCall::LogObject()");
   } else {
     runtime_call->print();
     fatal("runtime_call not implemented");
@@ -589,22 +595,22 @@
 }
 
 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) {
-  oop target = CiTargetMethod_Call::target(site);
+  oop target = InstalledCode_Call::target(site);
   instanceKlass* target_klass = instanceKlass::cast(target->klass());
 
-  oop runtime_call = NULL; // CiRuntimeCall
-  oop hotspot_method = NULL; // RiMethod
+  oop runtime_call = NULL; // RuntimeCall
+  oop hotspot_method = NULL; // JavaMethod
   oop global_stub = NULL;
 
   if (target_klass->is_subclass_of(SystemDictionary::Long_klass())) {
     global_stub = target;
-  } else if (target_klass->name() == vmSymbols::com_oracle_max_cri_ci_CiRuntimeCall()) {
+  } else if (target->is_a(RuntimeCall::klass())) {
     runtime_call = target;
   } else {
     hotspot_method = target;
   }
 
-  oop debug_info = CiTargetMethod_Call::debugInfo(site);
+  oop debug_info = InstalledCode_Call::debugInfo(site);
 
   assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type");
 
@@ -641,13 +647,13 @@
   }
 
   if (debug_info != NULL) {
-    oop frame = CiDebugInfo::codePos(debug_info);
-    _debug_recorder->add_safepoint(next_pc_offset, CiFrame::leafGraphId(frame), create_oop_map(_total_frame_size, _parameter_count, debug_info));
+    oop frame = DebugInfo::bytecodePosition(debug_info);
+    _debug_recorder->add_safepoint(next_pc_offset, BytecodeFrame::leafGraphId(frame), create_oop_map(_total_frame_size, _parameter_count, debug_info));
     record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>());
   }
 
   if (runtime_call != NULL) {
-    if (runtime_call != CiRuntimeCall::Debug()) {
+    if (runtime_call != RuntimeCall::Debug()) {
       address target_addr = runtime_call_target_address(runtime_call);
 
       if (inst->is_call()) {
@@ -676,12 +682,12 @@
     _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
     TRACE_graal_3("relocating (stub)  at %016x", inst);
   } else { // method != NULL
-    assert(hotspot_method != NULL, "unexpected RiMethod");
+    assert(hotspot_method != NULL, "unexpected JavaMethod");
     assert(debug_info != NULL, "debug info expected");
 
     methodOop method = NULL;
     // we need to check, this might also be an unresolved method
-    if (hotspot_method->is_a(HotSpotMethodResolved::klass())) {
+    if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
       method = getMethodFromHotSpotMethod(hotspot_method);
     }
 
@@ -730,21 +736,20 @@
 }
 
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
-  oop constant = CiTargetMethod_DataPatch::constant(site);
-  int alignment = CiTargetMethod_DataPatch::alignment(site);
-  oop kind = CiConstant::kind(constant);
+  oop constant = InstalledCode_DataPatch::constant(site);
+  int alignment = InstalledCode_DataPatch::alignment(site);
+  oop kind = Constant::kind(constant);
 
   address instruction = _instructions->start() + pc_offset;
 
-  char typeChar = CiKind::typeChar(kind);
+  char typeChar = Kind::typeChar(kind);
   switch (typeChar) {
     case 'z':
     case 'b':
     case 's':
     case 'c':
     case 'i':
-      fatal("int-sized values not expected in DataPatch")
-      ;
+      fatal("int-sized values not expected in DataPatch");
       break;
     case 'f':
     case 'j':
@@ -759,7 +764,7 @@
       // we don't care if this is a long/double/etc., the primitive field contains the right bits
       address dest = _constants->start() + size;
       _constants->set_end(dest + BytesPerLong);
-      *(jlong*) dest = CiConstant::primitive(constant);
+      *(jlong*) dest = Constant::primitive(constant);
 
       long disp = dest - next_instruction;
       assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
@@ -771,13 +776,15 @@
     }
     case 'a': {
       address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
-      Handle obj = CiConstant::object(constant);
+      Handle obj = Constant::object(constant);
 
-      if (obj->is_a(HotSpotTypeResolved::klass())) {
+      if (obj->is_a(HotSpotKlassOop::klass())) {
         assert(!obj.is_null(), "");
-        *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(obj)));
+        oop type = HotSpotKlassOop::type(obj);
+        klassOop klass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(type));
+        *((jobject*) operand) = JNIHandles::make_local(klass);
         _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
-        TRACE_graal_3("relocating (HotSpotType) at %016x/%016x", instruction, operand);
+        TRACE_graal_3("relocating (HotSpotJavaType) at %016x/%016x", instruction, operand);
       } else {
         jobject value = JNIHandles::make_local(obj());
         if (obj() == HotSpotProxy::DUMMY_CONSTANT_OBJ()) {
@@ -790,14 +797,14 @@
       break;
     }
     default:
-      fatal("unexpected CiKind in DataPatch");
+      fatal("unexpected Kind in DataPatch");
       break;
   }
 }
 
 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
-  oop id_obj = CiTargetMethod_Mark::id(site);
-  arrayOop references = (arrayOop) CiTargetMethod_Mark::references(site);
+  oop id_obj = InstalledCode_Mark::id(site);
+  arrayOop references = (arrayOop) InstalledCode_Mark::references(site);
 
   if (id_obj != NULL) {
     assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected");
@@ -824,7 +831,7 @@
       case MARK_STATIC_CALL_STUB: {
         assert(references->length() == 1, "static call stub needs one reference");
         oop ref = ((oop*) references->base(T_OBJECT))[0];
-        address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref);
+        address call_pc = _instructions->start() + InstalledCode_Site::pcOffset(ref);
         _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc));
         _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
         break;
@@ -869,14 +876,14 @@
         assert(references->length() == 2, "MARK_KLASS_PATCHING/MARK_ACCESS_FIELD_PATCHING needs 2 references");
         oop ref1 = ((oop*) references->base(T_OBJECT))[0];
         oop ref2 = ((oop*) references->base(T_OBJECT))[1];
-        int i_byte_count = CiTargetMethod_Site::pcOffset(ref2) - CiTargetMethod_Site::pcOffset(ref1);
+        int i_byte_count = InstalledCode_Site::pcOffset(ref2) - InstalledCode_Site::pcOffset(ref1);
         assert(i_byte_count == (unsigned char)i_byte_count, "invalid offset");
         *byte_count = i_byte_count;
         *being_initialized_entry_offset = *byte_count + *byte_skip;
 
         // we need to correct the offset of a field access - it's created with MAX_INT to ensure the correct size, and hotspot expects 0
         if (id == MARK_ACCESS_FIELD_PATCHING) {
-          NativeMovRegMem* inst = nativeMovRegMem_at(_instructions->start() + CiTargetMethod_Site::pcOffset(ref1));
+          NativeMovRegMem* inst = nativeMovRegMem_at(_instructions->start() + InstalledCode_Site::pcOffset(ref1));
           assert(inst->offset() == max_jint, "unexpected offset value");
           inst->set_offset(0);
         }
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -22,7 +22,7 @@
  */
 
 /*
- * This class handles the conversion from a CiTargetMethod to a CodeBlob or an nmethod.
+ * This class handles the conversion from a InstalledCode to a CodeBlob or an nmethod.
  */
 class CodeInstaller {
 private:
@@ -90,7 +90,7 @@
   static address runtime_call_target_address(oop runtime_call);
 
 private:
-  // extract the fields of the CiTargetMethod
+  // extract the fields of the InstalledCode
   void initialize_fields(oop target_method);
   void initialize_assumptions(oop target_method);
 
--- a/src/share/vm/graal/graalCompiler.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -73,7 +73,6 @@
   {
     VM_ENTRY_MARK;
     HandleMark hm;
-    VMToCompiler::initializeCompiler();
     VMToCompiler::setDefaultOptions();
     for (int i = 0; i < Arguments::num_graal_args(); ++i) {
       const char* arg = Arguments::graal_args_array()[i];
@@ -163,7 +162,7 @@
   ciEnv* current_env = JavaThread::current()->env();
   JavaThread::current()->set_env(NULL);
   JavaThread::current()->set_compiling(true);
-  Handle hotspot_method = GraalCompiler::createHotSpotMethodResolved(method, CHECK);
+  Handle hotspot_method = GraalCompiler::createHotSpotResolvedJavaMethod(method, CHECK);
   jboolean success = VMToCompiler::compileMethod(hotspot_method, entry_bci, blocking, method->graal_priority());
   JavaThread::current()->set_compiling(false);
   JavaThread::current()->set_env(current_env);
@@ -189,11 +188,11 @@
   TRACE_graal_1("GraalCompiler::print_timers");
 }
 
-Handle GraalCompiler::get_RiType(Symbol* klass_name, TRAPS) {
-   return VMToCompiler::createRiTypeUnresolved(VmIds::toString<Handle>(klass_name, THREAD), THREAD);
+Handle GraalCompiler::get_JavaType(Symbol* klass_name, TRAPS) {
+   return VMToCompiler::createJavaType(VmIds::toString<Handle>(klass_name, THREAD), THREAD);
 }
 
-Handle GraalCompiler::get_RiTypeFromSignature(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) {
+Handle GraalCompiler::get_JavaTypeFromSignature(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) {
   
   Symbol* signature = cp->symbol_at(index);
   BasicType field_type = FieldType::basic_type(signature);
@@ -202,16 +201,16 @@
   if (field_type == T_OBJECT || field_type == T_ARRAY) {
     KlassHandle handle = GraalEnv::get_klass_by_name(loading_klass, signature, false);
     if (handle.is_null()) {
-      return get_RiType(signature, CHECK_NULL);
+      return get_JavaType(signature, CHECK_NULL);
     } else {
-      return get_RiType(handle, CHECK_NULL);
+      return get_JavaType(handle, CHECK_NULL);
     }
   } else {
-    return VMToCompiler::createRiTypePrimitive(field_type, CHECK_NULL);
+    return VMToCompiler::createPrimitiveJavaType(field_type, CHECK_NULL);
   }
 }
 
-Handle GraalCompiler::get_RiType(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) {
+Handle GraalCompiler::get_JavaType(constantPoolHandle cp, int index, KlassHandle loading_klass, TRAPS) {
   bool is_accessible = false;
 
   KlassHandle klass = GraalEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
@@ -226,101 +225,103 @@
     if (tag.is_klass()) {
       // The klass has been inserted into the constant pool
       // very recently.
-      return GraalCompiler::get_RiType(cp->resolved_klass_at(index), CHECK_NULL);
+      return GraalCompiler::get_JavaType(cp->resolved_klass_at(index), CHECK_NULL);
     } else if (tag.is_symbol()) {
       klass_name = cp->symbol_at(index);
     } else {
       assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
       klass_name = cp->unresolved_klass_at(index);
     }
-    return GraalCompiler::get_RiType(klass_name, CHECK_NULL);
+    return GraalCompiler::get_JavaType(klass_name, CHECK_NULL);
   } else {
-    return GraalCompiler::get_RiType(klass, CHECK_NULL);
+    return GraalCompiler::get_JavaType(klass, CHECK_NULL);
   }
 }
 
-Handle GraalCompiler::get_RiType(KlassHandle klass, TRAPS) {
+Handle GraalCompiler::get_JavaType(KlassHandle klass, TRAPS) {
   Handle name = VmIds::toString<Handle>(klass->name(), THREAD);
-  return createHotSpotTypeResolved(klass, name, CHECK_NULL);
+  return createHotSpotResolvedJavaType(klass, name, CHECK_NULL);
 }
 
-Handle GraalCompiler::get_RiField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS) {
+Handle GraalCompiler::get_JavaField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS) {
   Handle name = VmIds::toString<Handle>(field_name, CHECK_NULL);
-  return VMToCompiler::createRiField(field_holder, name, field_type, offset, flags, CHECK_NULL);
+  return VMToCompiler::createJavaField(field_holder, name, field_type, offset, flags, CHECK_NULL);
 }
 
-Handle GraalCompiler::createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS) {
+Handle GraalCompiler::createHotSpotResolvedJavaType(KlassHandle klass, Handle name, TRAPS) {
   ObjectLocker ol(klass, THREAD);
 
   if (klass->graal_mirror() != NULL) {
     return klass->graal_mirror();
   }
 
-  instanceKlass::cast(HotSpotTypeResolved::klass())->initialize(CHECK_NULL);
-  Handle obj = instanceKlass::cast(HotSpotTypeResolved::klass())->allocate_instance(CHECK_NULL);
+  instanceKlass::cast(HotSpotResolvedJavaType::klass())->initialize(CHECK_NULL);
+  Handle obj = instanceKlass::cast(HotSpotResolvedJavaType::klass())->allocate_instance(CHECK_NULL);
   assert(obj() != NULL, "must succeed in allocating instance");
 
-  HotSpotTypeResolved::set_compiler(obj, VMToCompiler::compilerInstance()());
-
   if (klass->oop_is_instance()) {
     ResourceMark rm;
     instanceKlass* ik = (instanceKlass*)klass()->klass_part();
     Handle full_name = java_lang_String::create_from_str(ik->signature_name(), CHECK_NULL);
-    HotSpotType::set_name(obj, full_name());
+    HotSpotJavaType::set_name(obj, full_name());
   } else {
-    HotSpotType::set_name(obj, name());
+    HotSpotJavaType::set_name(obj, name());
   }
 
-  HotSpotTypeResolved::set_javaMirror(obj, klass->java_mirror());
-  HotSpotTypeResolved::set_simpleName(obj, name());
-  HotSpotTypeResolved::set_accessFlags(obj, klass->access_flags().as_int());
-  HotSpotTypeResolved::set_isInterface(obj, klass->is_interface());
-  HotSpotTypeResolved::set_isInstanceClass(obj, klass->oop_is_instance());
+  HotSpotResolvedJavaType::set_javaMirror(obj, klass->java_mirror());
+  HotSpotResolvedJavaType::set_simpleName(obj, name());
+  HotSpotResolvedJavaType::set_accessFlags(obj, klass->access_flags().as_int());
+  HotSpotResolvedJavaType::set_isInterface(obj, klass->is_interface());
+  HotSpotResolvedJavaType::set_superCheckOffset(obj, klass->super_check_offset());
+  HotSpotResolvedJavaType::set_prototypeHeader(obj, (jlong) klass->prototype_header());
+  HotSpotResolvedJavaType::set_isInstanceClass(obj, klass->oop_is_instance());
 
   if (klass->oop_is_javaArray()) {
-    HotSpotTypeResolved::set_isArrayClass(obj, true);
+    HotSpotResolvedJavaType::set_isArrayClass(obj, true);
   } else {
-    HotSpotTypeResolved::set_isArrayClass(obj, false);
-    HotSpotTypeResolved::set_instanceSize(obj, instanceKlass::cast(klass())->size_helper() * HeapWordSize);
-    HotSpotTypeResolved::set_hasFinalizer(obj, klass->has_finalizer());
+    int size = instanceKlass::cast(klass())->size_helper() * HeapWordSize;
+    if (!instanceKlass::cast(klass())->can_be_fastpath_allocated()) {
+      size = -size;
+    }
+    HotSpotResolvedJavaType::set_isArrayClass(obj, false);
+    HotSpotResolvedJavaType::set_instanceSize(obj, size);
+    HotSpotResolvedJavaType::set_hasFinalizer(obj, klass->has_finalizer());
   }
 
   // TODO replace these with correct values
-  HotSpotTypeResolved::set_hasSubclass(obj, false);
-  HotSpotTypeResolved::set_hasFinalizableSubclass(obj, false);
+  HotSpotResolvedJavaType::set_hasFinalizableSubclass(obj, false);
 
   klass->set_graal_mirror(obj());
 
   return obj;
 }
 
-Handle GraalCompiler::createHotSpotMethodResolved(methodHandle method, TRAPS) {
+Handle GraalCompiler::createHotSpotResolvedJavaMethod(methodHandle method, TRAPS) {
   if (method->graal_mirror() != NULL) {
-    assert(method->graal_mirror()->is_a(HotSpotMethodResolved::klass()), "unexpected class...");
+    assert(method->graal_mirror()->is_a(HotSpotResolvedJavaMethod::klass()), "unexpected class...");
     return method->graal_mirror();
   }
   Handle name = VmIds::toString<Handle>(method->name(), CHECK_NULL);
 
-  instanceKlass::cast(HotSpotMethodResolved::klass())->initialize(CHECK_NULL);
-  Handle obj = instanceKlass::cast(HotSpotMethodResolved::klass())->allocate_instance(CHECK_NULL);
+  instanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK_NULL);
+  Handle obj = instanceKlass::cast(HotSpotResolvedJavaMethod::klass())->allocate_instance(CHECK_NULL);
   assert(obj() != NULL, "must succeed in allocating instance");
-  
-  HotSpotMethodResolved::set_compiler(obj, VMToCompiler::compilerInstance()());
+
   // (thomaswue) Cannot use reflection here, because the compiler thread could dead lock with the running application.
   // oop reflected = getReflectedMethod(method(), CHECK_NULL);
-  HotSpotMethodResolved::set_javaMirror(obj, method());
-  HotSpotMethodResolved::set_name(obj, name());
+  HotSpotResolvedJavaMethod::set_javaMirror(obj, method());
+  HotSpotResolvedJavaMethod::set_name(obj, name());
   
   KlassHandle klass = method->method_holder();
   Handle holder_name = VmIds::toString<Handle>(klass->name(), CHECK_NULL);
-  Handle holder = GraalCompiler::createHotSpotTypeResolved(klass, holder_name, CHECK_NULL);
-  HotSpotMethodResolved::set_holder(obj, holder());
+  Handle holder = GraalCompiler::createHotSpotResolvedJavaType(klass, holder_name, CHECK_NULL);
+  HotSpotResolvedJavaMethod::set_holder(obj, holder());
   
-  HotSpotMethodResolved::set_codeSize(obj, method->code_size());
-  HotSpotMethodResolved::set_accessFlags(obj, method->access_flags().as_int());
-  HotSpotMethodResolved::set_maxLocals(obj, method->max_locals());
-  HotSpotMethodResolved::set_maxStackSize(obj, method->max_stack());
-  HotSpotMethodResolved::set_canBeInlined(obj, !method->is_not_compilable() && !CompilerOracle::should_not_inline(method));
+  HotSpotResolvedJavaMethod::set_codeSize(obj, method->code_size());
+  HotSpotResolvedJavaMethod::set_accessFlags(obj, method->access_flags().as_int());
+  HotSpotResolvedJavaMethod::set_maxLocals(obj, method->max_locals());
+  HotSpotResolvedJavaMethod::set_maxStackSize(obj, method->max_stack());
+  HotSpotResolvedJavaMethod::set_canBeInlined(obj, !method->is_not_compilable() && !CompilerOracle::should_not_inline(method));
   
   method->set_graal_mirror(obj());
   return obj;
@@ -336,7 +337,6 @@
   Handle obj = instanceKlass::cast(HotSpotMethodData::klass())->allocate_instance(CHECK_NULL);
   assert(obj.not_null(), "must succeed in allocating instance");
   
-  HotSpotMethodData::set_compiler(obj, VMToCompiler::compilerInstance()());
   HotSpotMethodData::set_hotspotMirror(obj, method_data());
   HotSpotMethodData::set_normalDataSize(obj, method_data()->data_size());
   HotSpotMethodData::set_extraDataSize(obj, method_data()->extra_data_size());
@@ -359,7 +359,7 @@
     case 'r': return T_ADDRESS;
     case '-': return T_ILLEGAL;
     default:
-      fatal(err_msg("unexpected CiKind: %c", ch));
+      fatal(err_msg("unexpected Kind: %c", ch));
       break;
   }
   return T_ILLEGAL;
--- a/src/share/vm/graal/graalCompiler.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalCompiler.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -67,14 +67,14 @@
   // Print compilation timers and statistics
   virtual void print_timers();
   
-  static Handle get_RiTypeFromSignature(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
-  static Handle get_RiType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
-  static Handle get_RiType(Symbol* klass_name, TRAPS);
-  static Handle get_RiType(KlassHandle klass, TRAPS);
-  static Handle get_RiField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS);
+  static Handle get_JavaTypeFromSignature(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
+  static Handle get_JavaType(constantPoolHandle cp, int index, KlassHandle accessor, TRAPS);
+  static Handle get_JavaType(Symbol* klass_name, TRAPS);
+  static Handle get_JavaType(KlassHandle klass, TRAPS);
+  static Handle get_JavaField(int offset, int flags, Symbol* field_name, Handle field_holder, Handle field_type, Bytecodes::Code byteCode, TRAPS);
 
-  static Handle createHotSpotTypeResolved(KlassHandle klass, Handle name, TRAPS);
-  static Handle createHotSpotMethodResolved(methodHandle method, TRAPS);
+  static Handle createHotSpotResolvedJavaType(KlassHandle klass, Handle name, TRAPS);
+  static Handle createHotSpotResolvedJavaMethod(methodHandle method, TRAPS);
   static Handle createHotSpotMethodData(methodDataHandle method_data, TRAPS);
 
   void exit();
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -41,16 +41,16 @@
 }
 
 methodOop getMethodFromHotSpotMethod(oop hotspot_method) {
-  return (methodOop)HotSpotMethodResolved::javaMirror(hotspot_method);
+  return (methodOop)HotSpotResolvedJavaMethod::javaMirror(hotspot_method);
 }
 
 methodDataOop getMethodDataFromHotSpotMethodData(jobject hotspot_method_data) {
   return (methodDataOop)HotSpotMethodData::hotspotMirror(JNIHandles::resolve(hotspot_method_data));
 }
 
-// public byte[] RiMethod_code(HotSpotResolvedMethod method);
-JNIEXPORT jbyteArray JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1code(JNIEnv *env, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_code");
+// public byte[] JavaMethod_code(HotSpotResolvedMethod method);
+JNIEXPORT jbyteArray JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1code(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_code");
   methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
   
   // copy all bytecodes
@@ -85,48 +85,48 @@
   return result;
 }
 
-// public String RiMethod_signature(HotSpotResolvedMethod method);
-JNIEXPORT jstring JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1signature(JNIEnv *env, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_signature");
+// public String JavaMethod_signature(HotSpotResolvedMethod method);
+JNIEXPORT jstring JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1signature(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_signature");
   VM_ENTRY_MARK
   methodOop method = getMethodFromHotSpotMethod(hotspot_method);
   assert(method != NULL && method->signature() != NULL, "signature required");
   return VmIds::toString<jstring>(method->signature(), THREAD);
 }
 
-// public RiExceptionHandler[] RiMethod_exceptionHandlers(long vmId);
-JNIEXPORT jobjectArray JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1exceptionHandlers(JNIEnv *, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_exceptionHandlers");
+// public ExceptionHandler[] JavaMethod_exceptionHandlers(long vmId);
+JNIEXPORT jobjectArray JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1exceptionHandlers(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_exceptionHandlers");
   VM_ENTRY_MARK
   ResourceMark rm;
   methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
   typeArrayHandle handlers = method->exception_table();
   int handler_count = handlers.is_null() ? 0 : handlers->length() / 4;
 
-  instanceKlass::cast(HotSpotExceptionHandler::klass())->initialize(CHECK_NULL);
-  objArrayHandle array = oopFactory::new_objArray(SystemDictionary::RiExceptionHandler_klass(), handler_count, CHECK_NULL);
+  instanceKlass::cast(ExceptionHandler::klass())->initialize(CHECK_NULL);
+  objArrayHandle array = oopFactory::new_objArray(SystemDictionary::ExceptionHandler_klass(), handler_count, CHECK_NULL);
 
   for (int i = 0; i < handler_count; i++) {
     // exception handlers are stored as four integers: start bci, end bci, handler bci, catch class constant pool index
     int base = i * 4;
-    Handle entry = instanceKlass::cast(HotSpotExceptionHandler::klass())->allocate_instance(CHECK_NULL);
-    HotSpotExceptionHandler::set_startBci(entry, handlers->int_at(base + 0));
-    HotSpotExceptionHandler::set_endBci(entry, handlers->int_at(base + 1));
-    HotSpotExceptionHandler::set_handlerBci(entry, handlers->int_at(base + 2));
+    Handle entry = instanceKlass::cast(ExceptionHandler::klass())->allocate_instance(CHECK_NULL);
+    ExceptionHandler::set_startBCI(entry, handlers->int_at(base + 0));
+    ExceptionHandler::set_endBCI(entry, handlers->int_at(base + 1));
+    ExceptionHandler::set_handlerBCI(entry, handlers->int_at(base + 2));
     int catch_class_index = handlers->int_at(base + 3);
-    HotSpotExceptionHandler::set_catchClassIndex(entry, catch_class_index);
+    ExceptionHandler::set_catchTypeCPI(entry, catch_class_index);
 
     if (catch_class_index == 0) {
-      HotSpotExceptionHandler::set_catchClass(entry, NULL);
+      ExceptionHandler::set_catchType(entry, NULL);
     } else {
       constantPoolOop cp = instanceKlass::cast(method->method_holder())->constants();
       KlassHandle loading_klass = method->method_holder();
-      Handle catch_class = GraalCompiler::get_RiType(cp, catch_class_index, loading_klass, CHECK_NULL);
-      if (catch_class->klass() == HotSpotTypeResolved::klass() && java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
-        HotSpotExceptionHandler::set_catchClass(entry, NULL);
-        HotSpotExceptionHandler::set_catchClassIndex(entry, 0);
+      Handle catch_class = GraalCompiler::get_JavaType(cp, catch_class_index, loading_klass, CHECK_NULL);
+      if (catch_class->klass() == HotSpotResolvedJavaType::klass() && java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(catch_class)) == SystemDictionary::Throwable_klass()) {
+        ExceptionHandler::set_catchType(entry, NULL);
+        ExceptionHandler::set_catchTypeCPI(entry, 0);
       } else {
-        HotSpotExceptionHandler::set_catchClass(entry, catch_class());
+        ExceptionHandler::set_catchType(entry, catch_class());
       }
     }
     array->obj_at_put(i, entry());
@@ -135,9 +135,9 @@
   return (jobjectArray) JNIHandles::make_local(array());
 }
 
-// public boolean RiMethod_hasBalancedMonitors(long vmId);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1hasBalancedMonitors(JNIEnv *, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_hasBalancedMonitors");
+// public boolean JavaMethod_hasBalancedMonitors(long vmId);
+JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1hasBalancedMonitors(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_hasBalancedMonitors");
 
   VM_ENTRY_MARK;
 
@@ -163,22 +163,22 @@
   return true;
 }
 
-// public RiMethod getRiMethod(java.lang.reflect.Method reflectionMethod);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getRiMethod(JNIEnv *, jobject, jobject reflection_method_handle) {
-  TRACE_graal_3("CompilerToVM::getRiMethod");
+// public JavaMethod getJavaMethod(java.lang.reflect.Method reflectionMethod);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getJavaMethod(JNIEnv *, jobject, jobject reflection_method_handle) {
+  TRACE_graal_3("CompilerToVM::getJavaMethod");
   VM_ENTRY_MARK;
   oop reflection_method = JNIHandles::resolve(reflection_method_handle);
   oop reflection_holder = java_lang_reflect_Method::clazz(reflection_method);
   int slot = java_lang_reflect_Method::slot(reflection_method);
   klassOop holder = java_lang_Class::as_klassOop(reflection_holder);
   methodOop method = instanceKlass::cast(holder)->method_with_idnum(slot);
-  Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+  Handle ret = GraalCompiler::createHotSpotResolvedJavaMethod(method, CHECK_NULL);
   return JNIHandles::make_local(THREAD, ret());
 }
 
-// public boolean RiMethod_uniqueConcreteMethod(long vmId);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1uniqueConcreteMethod(JNIEnv *, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_uniqueConcreteMethod");
+// public boolean JavaMethod_uniqueConcreteMethod(long vmId);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1uniqueConcreteMethod(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_uniqueConcreteMethod");
 
   VM_ENTRY_MARK;
   methodHandle method = getMethodFromHotSpotMethod(hotspot_method);
@@ -191,7 +191,7 @@
     // class C extends B { public void foo() { } }
     // class D extends B { }
     // Would lead to identify C.foo() as the unique concrete method for I.foo() without seeing A.foo().
-    return false;
+    return NULL;
   }
   methodHandle unique_concrete;
   {
@@ -202,20 +202,20 @@
   if (unique_concrete.is_null()) {
     return NULL;
   } else {
-    Handle method_resolved = GraalCompiler::createHotSpotMethodResolved(unique_concrete, CHECK_NULL);
+    Handle method_resolved = GraalCompiler::createHotSpotResolvedJavaMethod(unique_concrete, CHECK_NULL);
     return JNIHandles::make_local(THREAD, method_resolved());
   }
 }
 
-// public native int RiMethod_invocationCount(long vmId);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1invocationCount(JNIEnv *, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_invocationCount");
+// public native int JavaMethod_invocationCount(long vmId);
+JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1invocationCount(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_invocationCount");
   return getMethodFromHotSpotMethod(hotspot_method)->invocation_count();
 }
 
-// public native HotSpotMethodData RiMethod_methodData(HotSpotMethodResolved method);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1methodData(JNIEnv *, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_methodData");
+// public native HotSpotMethodData JavaMethod_methodData(HotSpotResolvedJavaMethod method);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1methodData(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_methodData");
   VM_ENTRY_MARK;
 
   methodDataHandle method_data = getMethodFromHotSpotMethod(hotspot_method)->method_data();
@@ -253,22 +253,22 @@
   return count;
 }
 
-// public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method);
-JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1hasCompiledCode(JNIEnv *, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_hasCompiledCode");
+// public native boolean JavaMethod_hasCompiledCode(HotSpotResolvedJavaMethod method);
+JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1hasCompiledCode(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_hasCompiledCode");
   return getMethodFromHotSpotMethod(hotspot_method)->has_compiled_code();
 }
 
-// public native int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1getCompiledCodeSize(JNIEnv *env, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_getCompiledCodeSize");
+// public native int JavaMethod_getCompiledCodeSize(HotSpotResolvedJavaMethod method);
+JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1getCompiledCodeSize(JNIEnv *env, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_getCompiledCodeSize");
   nmethod* code = getMethodFromHotSpotMethod(hotspot_method)->code();
   return code == NULL ? 0 : code->insts_size();
 }
 
-// public RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve) {
-  TRACE_graal_3("CompilerToVM::RiSignature_lookupType");
+// public JavaType Signature_lookupType(String returnType, HotSpotResolvedJavaType accessingClass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_Signature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass, jboolean eagerResolve) {
+  TRACE_graal_3("CompilerToVM::Signature_lookupType");
   VM_ENTRY_MARK;
   ResourceMark rm;
 
@@ -277,21 +277,21 @@
 
   oop result;
   if (nameSymbol == vmSymbols::int_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_INT, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_INT, THREAD);
   } else if (nameSymbol == vmSymbols::long_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_LONG, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_LONG, THREAD);
   } else if (nameSymbol == vmSymbols::bool_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_BOOLEAN, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_BOOLEAN, THREAD);
   } else if (nameSymbol == vmSymbols::char_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_CHAR, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_CHAR, THREAD);
   } else if (nameSymbol == vmSymbols::short_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_SHORT, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_SHORT, THREAD);
   } else if (nameSymbol == vmSymbols::byte_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_BYTE, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_BYTE, THREAD);
   } else if (nameSymbol == vmSymbols::double_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_DOUBLE, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_DOUBLE, THREAD);
   } else if (nameSymbol == vmSymbols::float_signature()) {
-    result = VMToCompiler::createRiTypePrimitive((int) T_FLOAT, THREAD);
+    result = VMToCompiler::createPrimitiveJavaType((int) T_FLOAT, THREAD);
   } else {
     klassOop resolved_type = NULL;
     // if the name isn't in the symbol table then the class isn't loaded anyway...
@@ -299,8 +299,8 @@
       Handle classloader;
       Handle protectionDomain;
       if (JNIHandles::resolve(accessingClass) != NULL) {
-        classloader = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->class_loader();
-        protectionDomain = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(accessingClass))->klass_part()->protection_domain();
+        classloader = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(accessingClass))->klass_part()->class_loader();
+        protectionDomain = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(accessingClass))->klass_part()->protection_domain();
       }
       if (eagerResolve) {
         resolved_type = SystemDictionary::resolve_or_null(nameSymbol, classloader, protectionDomain, THREAD);
@@ -321,10 +321,10 @@
       }
     }
     if (resolved_type != NULL) {
-      Handle type = GraalCompiler::createHotSpotTypeResolved(resolved_type, name, CHECK_NULL);
+      Handle type = GraalCompiler::createHotSpotResolvedJavaType(resolved_type, name, CHECK_NULL);
       result = type();
     } else {
-      Handle type = VMToCompiler::createRiTypeUnresolved(name, THREAD);
+      Handle type = VMToCompiler::createJavaType(name, THREAD);
       result = type();
     }
   }
@@ -332,23 +332,23 @@
   return JNIHandles::make_local(THREAD, result);
 }
 
-// public Object RiConstantPool_lookupConstant(HotSpotTypeResolved type, int cpi);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupConstant(JNIEnv *env, jobject, jobject type, jint index) {
-  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupConstant");
+// public Object ConstantPool_lookupConstant(HotSpotResolvedJavaType type, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_ConstantPool_1lookupConstant(JNIEnv *env, jobject, jobject type, jint index) {
+  TRACE_graal_3("CompilerToVM::ConstantPool_lookupConstant");
   VM_ENTRY_MARK;
 
-  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(type)))->constants();
 
   oop result = NULL;
   constantTag tag = cp->tag_at(index);
   if (tag.is_int()) {
-    result = VMToCompiler::createCiConstant(CiKind::Int(), cp->int_at(index), CHECK_0);
+    result = VMToCompiler::createConstant(Kind::Int(), cp->int_at(index), CHECK_0);
   } else if (tag.is_long()) {
-    result = VMToCompiler::createCiConstant(CiKind::Long(), cp->long_at(index), CHECK_0);
+    result = VMToCompiler::createConstant(Kind::Long(), cp->long_at(index), CHECK_0);
   } else if (tag.is_float()) {
-    result = VMToCompiler::createCiConstantFloat(cp->float_at(index), CHECK_0);
+    result = VMToCompiler::createConstantFloat(cp->float_at(index), CHECK_0);
   } else if (tag.is_double()) {
-    result = VMToCompiler::createCiConstantDouble(cp->double_at(index), CHECK_0);
+    result = VMToCompiler::createConstantDouble(cp->double_at(index), CHECK_0);
   } else if (tag.is_string() || tag.is_unresolved_string()) {
     oop string = NULL;
     if (cp->is_pseudo_string_at(index)) {
@@ -362,14 +362,14 @@
         return NULL;
       }
     }
-    result = VMToCompiler::createCiConstantObject(string, CHECK_0);
+    result = VMToCompiler::createConstantObject(string, CHECK_0);
   } else if (tag.is_klass() || tag.is_unresolved_klass()) {
-    Handle type = GraalCompiler::get_RiType(cp, index, cp->pool_holder(), CHECK_NULL);
+    Handle type = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
     result = type();
   } else if (tag.is_object()) {
     oop obj = cp->object_at(index);
     assert(obj->is_instance(), "must be an instance");
-    result = VMToCompiler::createCiConstantObject(obj, CHECK_NULL);
+    result = VMToCompiler::createConstantObject(obj, CHECK_NULL);
   } else {
     ShouldNotReachHere();
   }
@@ -377,45 +377,45 @@
   return JNIHandles::make_local(THREAD, result);
 }
 
-// public RiMethod RiConstantPool_lookupMethod(long vmId, int cpi, byte byteCode);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupMethod(JNIEnv *env, jobject, jobject type, jint index, jbyte byteCode) {
-  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupMethod");
+// public JavaMethod ConstantPool_lookupMethod(long vmId, int cpi, byte byteCode);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_ConstantPool_1lookupMethod(JNIEnv *env, jobject, jobject type, jint index, jbyte byteCode) {
+  TRACE_graal_3("CompilerToVM::ConstantPool_lookupMethod");
   VM_ENTRY_MARK;
   index = GraalCompiler::to_cp_index_u2(index);
-  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(type)))->constants();
   instanceKlassHandle pool_holder(cp->pool_holder());
 
   Bytecodes::Code bc = (Bytecodes::Code) (((int) byteCode) & 0xFF);
   methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
   if (!method.is_null()) {
-    Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+    Handle ret = GraalCompiler::createHotSpotResolvedJavaMethod(method, CHECK_NULL);
     return JNIHandles::make_local(THREAD, ret());
   } else {
     // Get the method's name and signature.
     Handle name = VmIds::toString<Handle>(cp->name_ref_at(index), CHECK_NULL);
     Handle signature  = VmIds::toString<Handle>(cp->signature_ref_at(index), CHECK_NULL);
     int holder_index = cp->klass_ref_index_at(index);
-    Handle type = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, VMToCompiler::createRiMethodUnresolved(name, signature, type, THREAD));
+    Handle type = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+    return JNIHandles::make_local(THREAD, VMToCompiler::createJavaMethod(name, signature, type, THREAD));
   }
 }
 
-// public RiType RiConstantPool_lookupType(long vmId, int cpi);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupType(JNIEnv *env, jobject, jobject type, jint index) {
-  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupType");
+// public JavaType ConstantPool_lookupType(long vmId, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_ConstantPool_1lookupType(JNIEnv *env, jobject, jobject type, jint index) {
+  TRACE_graal_3("CompilerToVM::ConstantPool_lookupType");
   VM_ENTRY_MARK;
 
-  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
-  Handle result = GraalCompiler::get_RiType(cp, index, cp->pool_holder(), CHECK_NULL);
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(type)))->constants();
+  Handle result = GraalCompiler::get_JavaType(cp, index, cp->pool_holder(), CHECK_NULL);
   return JNIHandles::make_local(THREAD, result());
 }
 
-// public void RiConstantPool_loadReferencedType(long vmId, int cpi);
-JNIEXPORT void JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1loadReferencedType(JNIEnv *env, jobject, jobject type, jint index, jbyte op) {
-  TRACE_graal_3("CompilerToVM::RiConstantPool_loadReferencedType");
+// public void ConstantPool_loadReferencedType(long vmId, int cpi);
+JNIEXPORT void JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_ConstantPool_1loadReferencedType(JNIEnv *env, jobject, jobject type, jint index, jbyte op) {
+  TRACE_graal_3("CompilerToVM::ConstantPool_loadReferencedType");
   VM_ENTRY_MARK;
   
-  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(type)))->constants();
+  constantPoolOop cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(type)))->constants();
   int byteCode = (op & 0xFF);
   if (byteCode != Bytecodes::_checkcast && byteCode != Bytecodes::_instanceof && byteCode != Bytecodes::_new && byteCode != Bytecodes::_anewarray
       && byteCode != Bytecodes::_multianewarray && byteCode != Bytecodes::_ldc && byteCode != Bytecodes::_ldc_w && byteCode != Bytecodes::_ldc2_w)
@@ -436,14 +436,14 @@
   }
 }
 
-// public RiField RiConstantPool_lookupField(long vmId, int cpi);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiConstantPool_1lookupField(JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte byteCode) {
-  TRACE_graal_3("CompilerToVM::RiConstantPool_lookupField");
+// public JavaField ConstantPool_lookupField(long vmId, int cpi);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_ConstantPool_1lookupField(JNIEnv *env, jobject, jobject constantPoolHolder, jint index, jbyte byteCode) {
+  TRACE_graal_3("CompilerToVM::ConstantPool_lookupField");
   VM_ENTRY_MARK;
   ResourceMark rm;
 
   index = GraalCompiler::to_cp_index_u2(index);
-  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(constantPoolHolder)))->constants();
+  constantPoolHandle cp = instanceKlass::cast(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(constantPoolHolder)))->constants();
 
   int nt_index = cp->name_and_type_ref_index_at(index);
   int sig_index = cp->signature_ref_index_at(nt_index);
@@ -451,14 +451,14 @@
   int name_index = cp->name_ref_index_at(nt_index);
   Symbol* name = cp->symbol_at(name_index);
   int holder_index = cp->klass_ref_index_at(index);
-  Handle holder = GraalCompiler::get_RiType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
+  Handle holder = GraalCompiler::get_JavaType(cp, holder_index, cp->pool_holder(), CHECK_NULL);
   instanceKlassHandle holder_klass;
   
   Bytecodes::Code code = (Bytecodes::Code)(((int) byteCode) & 0xFF);
   int offset = -1;
   AccessFlags flags;
   BasicType basic_type;
-  if (holder->klass() == SystemDictionary::HotSpotTypeResolved_klass()) {
+  if (holder->klass() == SystemDictionary::HotSpotResolvedJavaType_klass()) {
     FieldAccessInfo result;
     LinkResolver::resolve_field(result, cp, index,
                                 Bytecodes::java_code(code),
@@ -470,12 +470,12 @@
       flags = result.access_flags();
       holder_klass = result.klass()->as_klassOop();
       basic_type = result.field_type();
-      holder = GraalCompiler::get_RiType(holder_klass, CHECK_NULL);
+      holder = GraalCompiler::get_JavaType(holder_klass, CHECK_NULL);
     }
   }
   
-  Handle type = GraalCompiler::get_RiTypeFromSignature(cp, sig_index, cp->pool_holder(), CHECK_NULL);
-  Handle field_handle = GraalCompiler::get_RiField(offset, flags.as_int(), name, holder, type, code, THREAD);
+  Handle type = GraalCompiler::get_JavaTypeFromSignature(cp, sig_index, cp->pool_holder(), CHECK_NULL);
+  Handle field_handle = GraalCompiler::get_JavaField(offset, flags.as_int(), name, holder, type, code, THREAD);
 
   oop constant_object = NULL;
     // Check to see if the field is constant.
@@ -507,31 +507,31 @@
       switch(basic_type) {
         case T_OBJECT:
         case T_ARRAY:
-          constant_object = VMToCompiler::createCiConstantObject(mirror->obj_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstantObject(mirror->obj_field(offset), CHECK_0);
           break;
         case T_DOUBLE:
-          constant_object = VMToCompiler::createCiConstantDouble(mirror->double_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstantDouble(mirror->double_field(offset), CHECK_0);
           break;
         case T_FLOAT:
-          constant_object = VMToCompiler::createCiConstantFloat(mirror->float_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstantFloat(mirror->float_field(offset), CHECK_0);
           break;
         case T_LONG:
-          constant_object = VMToCompiler::createCiConstant(CiKind::Long(), mirror->long_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstant(Kind::Long(), mirror->long_field(offset), CHECK_0);
           break;
         case T_INT:
-          constant_object = VMToCompiler::createCiConstant(CiKind::Int(), mirror->int_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstant(Kind::Int(), mirror->int_field(offset), CHECK_0);
           break;
         case T_SHORT:
-          constant_object = VMToCompiler::createCiConstant(CiKind::Short(), mirror->short_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstant(Kind::Short(), mirror->short_field(offset), CHECK_0);
           break;
         case T_CHAR:
-          constant_object = VMToCompiler::createCiConstant(CiKind::Char(), mirror->char_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstant(Kind::Char(), mirror->char_field(offset), CHECK_0);
           break;
         case T_BYTE:
-          constant_object = VMToCompiler::createCiConstant(CiKind::Byte(), mirror->byte_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstant(Kind::Byte(), mirror->byte_field(offset), CHECK_0);
           break;
         case T_BOOLEAN:
-          constant_object = VMToCompiler::createCiConstant(CiKind::Boolean(), mirror->bool_field(offset), CHECK_0);
+          constant_object = VMToCompiler::createConstant(Kind::Boolean(), mirror->bool_field(offset), CHECK_0);
           break;
         default:
           fatal("Unhandled constant");
@@ -540,18 +540,18 @@
     }
   }
   if (constant_object != NULL) {
-    HotSpotField::set_constant(field_handle, constant_object);
+    HotSpotResolvedJavaField::set_constant(field_handle, constant_object);
   }
   return JNIHandles::make_local(THREAD, field_handle());
 }
 
-// public RiMethod RiType_resolveMethodImpl(HotSpotTypeResolved klass, String name, String signature);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_3resolveMethodImpl(JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature) {
-  TRACE_graal_3("CompilerToVM::RiType_resolveMethodImpl");
+// public JavaMethod JavaType_resolveMethodImpl(HotSpotResolvedJavaType klass, String name, String signature);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_3resolveMethodImpl(JNIEnv *, jobject, jobject resolved_type, jstring name, jstring signature) {
+  TRACE_graal_3("CompilerToVM::JavaType_resolveMethodImpl");
   VM_ENTRY_MARK;
 
   assert(JNIHandles::resolve(resolved_type) != NULL, "");
-  klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(resolved_type));
+  klassOop klass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(resolved_type));
   Symbol* name_symbol = VmIds::toSymbol(name);
   Symbol* signature_symbol = VmIds::toSymbol(signature);
   methodHandle method = klass->klass_part()->lookup_method(name_symbol, signature_symbol);
@@ -562,20 +562,20 @@
     }
     return NULL;
   }
-  Handle ret = GraalCompiler::createHotSpotMethodResolved(method, CHECK_NULL);
+  Handle ret = GraalCompiler::createHotSpotResolvedJavaMethod(method, CHECK_NULL);
   return JNIHandles::make_local(THREAD, ret());
 }
 
-// public boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
-JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_2isSubtypeOf(JNIEnv *, jobject, jobject klass, jobject jother) {
-  TRACE_graal_3("CompilerToVM::RiType_isSubtypeOf");
+// public boolean JavaType_isSubtypeOf(HotSpotResolvedJavaType klass, JavaType other);
+JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_2isSubtypeOf(JNIEnv *, jobject, jobject klass, jobject jother) {
+  TRACE_graal_3("CompilerToVM::JavaType_isSubtypeOf");
   VM_ENTRY_MARK;
   
   oop other = JNIHandles::resolve(jother);
-  assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected");
+  assert(other->is_a(HotSpotResolvedJavaType::klass()), "resolved hotspot type expected");
   assert(JNIHandles::resolve(klass) != NULL, "");
-  klassOop thisKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
-  klassOop otherKlass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other));
+  klassOop thisKlass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(klass));
+  klassOop otherKlass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(other));
   if (thisKlass->klass_part()->oop_is_instance_slow()) {
     return instanceKlass::cast(thisKlass)->is_subtype_of(otherKlass);
   } else if (thisKlass->klass_part()->oop_is_array()) {
@@ -586,39 +586,39 @@
   }
 }
 
-// public RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_2leastCommonAncestor(JNIEnv *, jobject, jobject this_type, jobject other_type) {
-  TRACE_graal_3("CompilerToVM::RiType_leastCommonAncestor");
+// public JavaType JavaType_leastCommonAncestor(HotSpotResolvedJavaType thisType, HotSpotResolvedJavaType otherType);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_2leastCommonAncestor(JNIEnv *, jobject, jobject this_type, jobject other_type) {
+  TRACE_graal_3("CompilerToVM::JavaType_leastCommonAncestor");
   VM_ENTRY_MARK;
 
-  Klass* this_klass  = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(this_type))->klass_part();
-  Klass* other_klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other_type))->klass_part();
+  Klass* this_klass  = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(this_type))->klass_part();
+  Klass* other_klass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(other_type))->klass_part();
   Klass* lca         = this_klass->LCA(other_klass);
 
-  return JNIHandles::make_local(GraalCompiler::get_RiType(lca, THREAD)());
+  return JNIHandles::make_local(GraalCompiler::get_JavaType(lca, THREAD)());
 }
 
-// public RiType RiType_componentType(HotSpotResolvedType klass);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1componentType(JNIEnv *, jobject, jobject klass) {
-  TRACE_graal_3("CompilerToVM::RiType_componentType");
+// public JavaType JavaType_componentType(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_1componentType(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::JavaType_componentType");
   VM_ENTRY_MARK;
-  KlassHandle array_klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  KlassHandle array_klass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(klass));
   if(array_klass->oop_is_typeArray()) {
     BasicType t = typeArrayKlass::cast(array_klass())->element_type();
-    oop primitive_type = VMToCompiler::createRiTypePrimitive((int) t, CHECK_NULL);
+    oop primitive_type = VMToCompiler::createPrimitiveJavaType((int) t, CHECK_NULL);
     return JNIHandles::make_local(primitive_type);
   }
   assert(array_klass->oop_is_objArray(), "just checking");
   klassOop element_type = objArrayKlass::cast(array_klass())->element_klass();
   assert(JNIHandles::resolve(klass) != NULL, "");
-  return JNIHandles::make_local(GraalCompiler::get_RiType(element_type, THREAD)());
+  return JNIHandles::make_local(GraalCompiler::get_JavaType(element_type, THREAD)());
 }
 
-// public RiType RiType_superType(HotSpotResolvedType klass);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1superType(JNIEnv *, jobject, jobject klass) {
-  TRACE_graal_3("CompilerToVM::RiType_superType");
+// public JavaType JavaType_superType(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_1superType(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::JavaType_superType");
   VM_ENTRY_MARK;
-  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(klass)));
   klassOop k;
 
   if (klass_handle->oop_is_array()) {
@@ -629,51 +629,51 @@
   }
 
   if (k != NULL) {
-    return JNIHandles::make_local(GraalCompiler::get_RiType(k, THREAD)());
+    return JNIHandles::make_local(GraalCompiler::get_JavaType(k, THREAD)());
   } else {
     return NULL;
   }
 }
 
-// public RiType RiType_uniqueConcreteSubtype(HotSpotResolvedType klass);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1uniqueConcreteSubtype(JNIEnv *, jobject, jobject klass) {
-  TRACE_graal_3("CompilerToVM::RiType_uniqueConcreteSubtype");
+// public JavaType JavaType_uniqueConcreteSubtype(HotSpotResolvedType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_1uniqueConcreteSubtype(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::JavaType_uniqueConcreteSubtype");
   VM_ENTRY_MARK;
-  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(klass)));
   Klass *up_cast = klass_handle->up_cast_abstract();
   if (up_cast->is_leaf_class()) {
-    return JNIHandles::make_local(GraalCompiler::get_RiType(up_cast, THREAD)());
+    return JNIHandles::make_local(GraalCompiler::get_JavaType(up_cast, THREAD)());
   }
   return NULL;
 }
 
-// public bool RiType_isInitialized(HotSpotResolvedType klass);
-JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1isInitialized(JNIEnv *, jobject, jobject hotspot_klass) {
-  TRACE_graal_3("CompilerToVM::RiType_isInitialized");
-  klassOop klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(hotspot_klass));
+// public bool JavaType_isInitialized(HotSpotResolvedType klass);
+JNIEXPORT jboolean JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_1isInitialized(JNIEnv *, jobject, jobject hotspot_klass) {
+  TRACE_graal_3("CompilerToVM::JavaType_isInitialized");
+  klassOop klass = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(hotspot_klass));
   assert(klass != NULL, "method must not be called for primitive types");
   return instanceKlass::cast(klass)->is_initialized();
 }
 
-// public RiType RiType_arrayOf(HotSpotTypeResolved klass);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1arrayOf(JNIEnv *, jobject, jobject klass) {
-  TRACE_graal_3("CompilerToVM::RiType_arrayOf");
+// public JavaType JavaType_arrayOf(HotSpotResolvedJavaType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_1arrayOf(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::JavaType_arrayOf");
   VM_ENTRY_MARK;
 
-  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass)));
+  KlassHandle klass_handle(java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(klass)));
   KlassHandle arr = klass_handle->array_klass(THREAD);
   Handle name = VmIds::toString<Handle>(arr->name(), CHECK_NULL);
   assert(arr->oop_is_array(), "");
-  return JNIHandles::make_local(THREAD, GraalCompiler::createHotSpotTypeResolved(arr, name, THREAD)());
+  return JNIHandles::make_local(THREAD, GraalCompiler::createHotSpotResolvedJavaType(arr, name, THREAD)());
 }
 
-// public RiResolvedField[] RiType_fields(HotSpotTypeResolved klass);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiType_1fields(JNIEnv *, jobject, jobject klass) {
-  TRACE_graal_3("CompilerToVM::RiType_fields");
+// public ResolvedJavaField[] JavaType_fields(HotSpotResolvedJavaType klass);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaType_1fields(JNIEnv *, jobject, jobject klass) {
+  TRACE_graal_3("CompilerToVM::JavaType_fields");
   VM_ENTRY_MARK;
   ResourceMark rm;
 
-  instanceKlassHandle k = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(klass));
+  instanceKlassHandle k = java_lang_Class::as_klassOop(HotSpotResolvedJavaType::javaMirror(klass));
   class MyFieldClosure : public FieldClosure {
    public:
     instanceKlassHandle _holder;
@@ -685,8 +685,8 @@
     virtual void do_field(fieldDescriptor* fd) {
       if (!Thread::current()->has_pending_exception()) {
         if (fd->field_holder() == _holder()) {
-          Handle type = GraalCompiler::get_RiTypeFromSignature(fd->constants(), fd->signature_index(), fd->field_holder(), Thread::current());
-          Handle field = VMToCompiler::createRiField(_resolved_type_holder, VmIds::toString<Handle>(fd->name(), Thread::current()), type, fd->offset(), fd->access_flags().as_int(), Thread::current());
+          Handle type = GraalCompiler::get_JavaTypeFromSignature(fd->constants(), fd->signature_index(), fd->field_holder(), Thread::current());
+          Handle field = VMToCompiler::createJavaField(_resolved_type_holder, VmIds::toString<Handle>(fd->name(), Thread::current()), type, fd->offset(), fd->access_flags().as_int(), Thread::current());
           _field_array.append(field());
         }
       }
@@ -694,24 +694,24 @@
   };
   MyFieldClosure closure(k, JNIHandles::resolve(klass));
   k->do_nonstatic_fields(&closure);
-  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::RiResolvedField_klass(), closure._field_array.length(), CHECK_NULL);
+  objArrayHandle field_array = oopFactory::new_objArray(SystemDictionary::ResolvedJavaField_klass(), closure._field_array.length(), CHECK_NULL);
   for (int i=0; i<closure._field_array.length(); ++i) {
     field_array->obj_at_put(i, closure._field_array.at(i)());
   }
   return JNIHandles::make_local(field_array());
 }
 
-// public RiType getPrimitiveArrayType(CiKind kind);
+// public JavaType getPrimitiveArrayType(Kind kind);
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getPrimitiveArrayType(JNIEnv *env, jobject, jobject kind) {
   TRACE_graal_3("CompilerToVM::getPrimitiveArrayType");
   VM_ENTRY_MARK;
-  BasicType type = GraalCompiler::kindToBasicType(CiKind::typeChar(kind));
+  BasicType type = GraalCompiler::kindToBasicType(Kind::typeChar(kind));
   assert(type != T_OBJECT, "primitive type expecteds");
-  Handle result = GraalCompiler::get_RiType(Universe::typeArrayKlassObj(type), CHECK_NULL);
+  Handle result = GraalCompiler::get_JavaType(Universe::typeArrayKlassObj(type), CHECK_NULL);
   return JNIHandles::make_local(THREAD, result());
 }
 
-// public long getMaxCallTargetOffset(CiRuntimeCall rtcall);
+// public long getMaxCallTargetOffset(RuntimeCall rtcall);
 JNIEXPORT jlong JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getMaxCallTargetOffset(JNIEnv *env, jobject, jobject rtcall) {
   TRACE_graal_3("CompilerToVM::getMaxCallTargetOffset");
   VM_ENTRY_MARK;
@@ -725,7 +725,7 @@
   return -1;
 }
 
-// public RiType getType(Class<?> javaClass);
+// public JavaType getType(Class<?> javaClass);
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_getType(JNIEnv *env, jobject, jobject javaClass) {
   TRACE_graal_3("CompilerToVM::getType");
   VM_ENTRY_MARK;
@@ -735,12 +735,12 @@
     return NULL;
   } else if (java_lang_Class::is_primitive(javaClassOop)) {
     BasicType basicType = java_lang_Class::primitive_type(javaClassOop);
-    return JNIHandles::make_local(THREAD, VMToCompiler::createRiTypePrimitive((int) basicType, THREAD));
+    return JNIHandles::make_local(THREAD, VMToCompiler::createPrimitiveJavaType((int) basicType, THREAD));
   } else {
     KlassHandle klass = java_lang_Class::as_klassOop(javaClassOop);
     Handle name = java_lang_String::create_from_symbol(klass->name(), CHECK_NULL);
 
-    Handle type = GraalCompiler::createHotSpotTypeResolved(klass, name, CHECK_NULL);
+    Handle type = GraalCompiler::createHotSpotResolvedJavaType(klass, name, CHECK_NULL);
     return JNIHandles::make_local(THREAD, type());
   }
 }
@@ -781,14 +781,18 @@
 #else
   set_boolean(env, config, "windowsOs", false);
 #endif
-  set_boolean(env, config, "verifyPointers", VerifyOops);
+  set_boolean(env, config, "verifyOops", VerifyOops);
   set_boolean(env, config, "useFastLocking", UseFastLocking);
   set_boolean(env, config, "useFastNewObjectArray", UseFastNewObjectArray);
   set_boolean(env, config, "useFastNewTypeArray", UseFastNewTypeArray);
+  set_boolean(env, config, "useTLAB", UseTLAB);
   set_int(env, config, "codeEntryAlignment", CodeEntryAlignment);
   set_int(env, config, "vmPageSize", os::vm_page_size());
   set_int(env, config, "stackShadowPages", StackShadowPages);
   set_int(env, config, "hubOffset", oopDesc::klass_offset_in_bytes());
+  set_int(env, config, "superCheckOffsetOffset", in_bytes(Klass::super_check_offset_offset()));
+  set_int(env, config, "secondarySuperCacheOffset", in_bytes(Klass::secondary_super_cache_offset()));
+  set_int(env, config, "secondarySupersOffset", in_bytes(Klass::secondary_supers_offset()));
   set_int(env, config, "arrayLengthOffset", arrayOopDesc::length_offset_in_bytes());
   set_int(env, config, "klassStateOffset", in_bytes(instanceKlass::init_state_offset()));
   set_int(env, config, "klassStateFullyInitialized", (int)instanceKlass::fully_initialized);
@@ -812,11 +816,15 @@
   set_int(env, config, "bciProfileWidth", BciProfileWidth);
   set_int(env, config, "typeProfileWidth", TypeProfileWidth);
 
+  // We use the fast path stub so that we get TLAB refills whenever possible instead of
+  // unconditionally allocating directly from the heap (which the slow path does).
+  // The stub must also do initialization when the compiled check fails.
+  Runtime1::StubID newInstanceStub = Runtime1::fast_new_instance_init_check_id;
+
   set_long(env, config, "debugStub", VmIds::addStub((address)warning));
   set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
-  set_long(env, config, "verifyPointerStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_verify_pointer_id)));
-  set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_init_check_id)));
-  set_long(env, config, "unresolvedNewInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id)));
+  set_long(env, config, "verifyOopStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_verify_oop_id)));
+  set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(newInstanceStub)));
   set_long(env, config, "newTypeArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_type_array_id)));
   set_long(env, config, "newObjectArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_object_array_id)));
   set_long(env, config, "newMultiArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_multi_array_id)));
@@ -894,12 +902,11 @@
     HotSpotCodeInfo::set_start(info, (jlong) nm->code_begin());
   }
 
-  // if install_code is true then we installed the code into the given method, no need to return an RiCompiledMethod
+  // if install_code is true then we installed the code into the given method, no need to return an InstalledCode
   if (!install_code && nm != NULL) {
     instanceKlass::cast(HotSpotCompiledMethod::klass())->initialize(CHECK_NULL);
     Handle obj = instanceKlass::cast(HotSpotCompiledMethod::klass())->allocate_permanent_instance(CHECK_NULL);
     assert(obj() != NULL, "must succeed in allocating instance");
-    HotSpotCompiledMethod::set_compiler(obj, VMToCompiler::compilerInstance()());
     HotSpotCompiledMethod::set_nmethod(obj, (jlong) nm);
     HotSpotCompiledMethod::set_method(obj, HotSpotTargetMethod::method(targetMethod));
     nm->set_graal_compiled_method(obj());
@@ -909,28 +916,6 @@
   }
 }
 
-// public long installStub(HotSpotTargetMethod targetMethod, String name);
-JNIEXPORT jlong JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_installStub(JNIEnv *jniEnv, jobject, jobject targetMethod, jobject info) {
-  VM_ENTRY_MARK;
-  ResourceMark rm;
-  HandleMark hm;
-  Handle targetMethodHandle = JNIHandles::resolve(targetMethod);
-  jlong id;
-  Arena arena;
-  ciEnv env(&arena);
-  BufferBlob* blob;
-  CodeInstaller installer(targetMethodHandle, blob, id);
-
-  if (info != NULL) {
-    arrayOop codeCopy = oopFactory::new_byteArray(blob->code_size(), CHECK_0);
-    memcpy(codeCopy->base(T_BYTE), blob->code_begin(), blob->code_size());
-    HotSpotCodeInfo::set_code(info, codeCopy);
-    HotSpotCodeInfo::set_start(info, (jlong) blob->code_begin());
-  }
-
-  return id;
-}
-
 // public String disassembleNative(byte[] code, long address);
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_disassembleNative(JNIEnv *jniEnv, jobject, jbyteArray code, jlong start_address) {
   TRACE_graal_3("CompilerToVM::disassembleNative");
@@ -949,7 +934,7 @@
   return JNIHandles::make_local(result());
 }
 
-// public String disassembleJava(HotSpotMethodResolved method);
+// public String disassembleJava(HotSpotResolvedJavaMethod method);
 JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_disassembleJava(JNIEnv *env, jobject, jobject hotspot_method) {
   TRACE_graal_3("CompilerToVM::disassembleJava");
 
@@ -968,9 +953,9 @@
   return JNIHandles::make_local(result());
 }
 
-// public StackTraceElement RiMethod_toStackTraceElement(HotSpotMethodResolved method, int bci);
-JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1toStackTraceElement(JNIEnv *env, jobject, jobject hotspot_method, int bci) {
-  TRACE_graal_3("CompilerToVM::RiMethod_toStackTraceElement");
+// public StackTraceElement JavaMethod_toStackTraceElement(HotSpotResolvedJavaMethod method, int bci);
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_1toStackTraceElement(JNIEnv *env, jobject, jobject hotspot_method, int bci) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_toStackTraceElement");
 
   VM_ENTRY_MARK;
   ResourceMark rm;
@@ -1043,11 +1028,12 @@
   if (nm == NULL || !nm->is_alive()) {
     THROW_0(vmSymbols::MethodInvalidatedException());
   }
+
   JavaCalls::call(&result, mh, nm, &jca, CHECK_NULL);
 
   if (jap.get_ret_type() == T_VOID) {
     return NULL;
-  } else if (jap.get_ret_type() == T_OBJECT) {
+  } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
     return JNIHandles::make_local((oop) result.get_jobject());
   } else {
     oop o = java_lang_boxing_object::create(jap.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
@@ -1081,9 +1067,9 @@
   return JNIHandles::make_local((oop) result.get_jobject());
 }
 
-// public native int RiMethod_vtableEntryOffset(HotSpotMethodResolved method);
-JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_vtableEntryOffset(JNIEnv *, jobject, jobject hotspot_method) {
-  TRACE_graal_3("CompilerToVM::RiMethod_vtableEntryOffset");
+// public native int JavaMethod_vtableEntryOffset(HotSpotResolvedJavaMethod method);
+JNIEXPORT jint JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_JavaMethod_vtableEntryOffset(JNIEnv *, jobject, jobject hotspot_method) {
+  TRACE_graal_3("CompilerToVM::JavaMethod_vtableEntryOffset");
 
   methodOop method = getMethodFromHotSpotMethod(hotspot_method);
   assert(!instanceKlass::cast(method->method_holder())->is_interface(), "vtableEntryOffset cannot be called for interface methods");
@@ -1111,74 +1097,98 @@
   return JNIHandles::make_local(array);
 }
 
+JNIEXPORT jobject JNICALL Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_decodePC(JNIEnv *, jobject, jlong pc) {
+  TRACE_graal_3("CompilerToVM::decodePC");
+
+  VM_ENTRY_MARK;
+
+  stringStream(st);
+  CodeBlob* blob = CodeCache::find_blob_unsafe((void*) pc);
+  if (blob == NULL) {
+    st.print("[unidentified pc]");
+  } else {
+    st.print(blob->name());
+
+    nmethod* nm = blob->as_nmethod_or_null();
+    if (nm != NULL && nm->method() != NULL) {
+      st.print(" %s.", nm->method()->method_holder()->klass_part()->external_name());
+      nm->method()->name()->print_symbol_on(&st);
+      st.print("  @ %d", pc - (jlong) nm->entry_point());
+    }
+  }
+  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
+  return JNIHandles::make_local(result());
+
+}
+
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_##f))
 
 #define PROXY           "J"
-#define TYPE            "Lcom/oracle/max/cri/ri/RiType;"
-#define RESOLVED_TYPE   "Lcom/oracle/graal/hotspot/ri/HotSpotTypeResolved;"
-#define METHOD          "Lcom/oracle/max/cri/ri/RiMethod;"
-#define RESOLVED_METHOD "Lcom/oracle/graal/hotspot/ri/HotSpotMethodResolved;"
+#define TYPE            "Lcom/oracle/graal/api/meta/JavaType;"
+#define RESOLVED_TYPE   "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaType;"
+#define METHOD          "Lcom/oracle/graal/api/meta/JavaMethod;"
+#define RESOLVED_METHOD "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;"
 #define REFLECT_METHOD  "Ljava/lang/reflect/Method;"
-#define SIGNATURE       "Lcom/oracle/max/cri/ri/RiSignature;"
-#define FIELD           "Lcom/oracle/max/cri/ri/RiField;"
-#define RESOLVED_FIELD  "Lcom/oracle/max/cri/ri/RiResolvedField;"
-#define CONSTANT_POOL   "Lcom/oracle/max/cri/ri/RiConstantPool;"
-#define EXCEPTION_HANDLERS "[Lcom/oracle/max/cri/ri/RiExceptionHandler;"
+#define SIGNATURE       "Lcom/oracle/graal/api/meta/Signature;"
+#define FIELD           "Lcom/oracle/graal/api/meta/JavaField;"
+#define RESOLVED_FIELD  "Lcom/oracle/graal/api/meta/ResolvedJavaField;"
+#define CONSTANT_POOL   "Lcom/oracle/graal/api/meta/ConstantPool;"
+#define EXCEPTION_HANDLERS "[Lcom/oracle/graal/api/meta/ExceptionHandler;"
 #define TARGET_METHOD   "Lcom/oracle/graal/hotspot/HotSpotTargetMethod;"
 #define CONFIG          "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
-#define HS_METHOD       "Lcom/oracle/graal/hotspot/ri/HotSpotMethod;"
-#define HS_COMP_METHOD  "Lcom/oracle/graal/hotspot/ri/HotSpotCompiledMethod;"
-#define HS_CODE_INFO    "Lcom/oracle/graal/hotspot/ri/HotSpotCodeInfo;"
-#define METHOD_DATA     "Lcom/oracle/graal/hotspot/ri/HotSpotMethodData;"
-#define CI_CONSTANT     "Lcom/oracle/max/cri/ci/CiConstant;"
-#define CI_KIND         "Lcom/oracle/max/cri/ci/CiKind;"
-#define CI_RUNTIME_CALL "Lcom/oracle/max/cri/ci/CiRuntimeCall;"
+#define HS_METHOD       "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
+#define HS_COMP_METHOD  "Lcom/oracle/graal/hotspot/meta/HotSpotCompiledMethod;"
+#define HS_CODE_INFO    "Lcom/oracle/graal/hotspot/meta/HotSpotCodeInfo;"
+#define METHOD_DATA     "Lcom/oracle/graal/hotspot/meta/HotSpotMethodData;"
+#define CI_CONSTANT     "Lcom/oracle/graal/api/meta/Constant;"
+#define CI_KIND         "Lcom/oracle/graal/api/meta/Kind;"
+#define CI_RUNTIME_CALL "Lcom/oracle/graal/api/code/RuntimeCall;"
 #define STRING          "Ljava/lang/String;"
 #define OBJECT          "Ljava/lang/Object;"
 #define CLASS           "Ljava/lang/Class;"
 #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;"
 
 JNINativeMethod CompilerToVM_methods[] = {
-  {CC"RiMethod_code",                     CC"("RESOLVED_METHOD")[B",                            FN_PTR(RiMethod_1code)},
-  {CC"RiMethod_signature",                CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(RiMethod_1signature)},
-  {CC"RiMethod_exceptionHandlers",        CC"("RESOLVED_METHOD")"EXCEPTION_HANDLERS,            FN_PTR(RiMethod_1exceptionHandlers)},
-  {CC"RiMethod_hasBalancedMonitors",      CC"("RESOLVED_METHOD")Z",                             FN_PTR(RiMethod_1hasBalancedMonitors)},
-  {CC"RiMethod_uniqueConcreteMethod",     CC"("RESOLVED_METHOD")"METHOD,                        FN_PTR(RiMethod_1uniqueConcreteMethod)},
-  {CC"getRiMethod",                       CC"("REFLECT_METHOD")"METHOD,                         FN_PTR(getRiMethod)},
-  {CC"RiMethod_methodData",               CC"("RESOLVED_METHOD")"METHOD_DATA,                   FN_PTR(RiMethod_1methodData)},
-  {CC"RiMethod_invocationCount",          CC"("RESOLVED_METHOD")I",                             FN_PTR(RiMethod_1invocationCount)},
-  {CC"RiMethod_hasCompiledCode",          CC"("RESOLVED_METHOD")Z",                             FN_PTR(RiMethod_1hasCompiledCode)},
-  {CC"RiMethod_getCompiledCodeSize",      CC"("RESOLVED_METHOD")I",                             FN_PTR(RiMethod_1getCompiledCodeSize)},
-  {CC"RiSignature_lookupType",            CC"("STRING RESOLVED_TYPE"Z)"TYPE,                    FN_PTR(RiSignature_1lookupType)},
-  {CC"RiConstantPool_lookupConstant",     CC"("RESOLVED_TYPE"I)"OBJECT,                         FN_PTR(RiConstantPool_1lookupConstant)},
-  {CC"RiConstantPool_lookupMethod",       CC"("RESOLVED_TYPE"IB)"METHOD,                        FN_PTR(RiConstantPool_1lookupMethod)},
-  {CC"RiConstantPool_lookupType",         CC"("RESOLVED_TYPE"I)"TYPE,                           FN_PTR(RiConstantPool_1lookupType)},
-  {CC"RiConstantPool_loadReferencedType", CC"("RESOLVED_TYPE"IB)V",                             FN_PTR(RiConstantPool_1loadReferencedType)},
-  {CC"RiConstantPool_lookupField",        CC"("RESOLVED_TYPE"IB)"FIELD,                         FN_PTR(RiConstantPool_1lookupField)},
-  {CC"RiType_resolveMethodImpl",          CC"("RESOLVED_TYPE STRING STRING")"METHOD,            FN_PTR(RiType_3resolveMethodImpl)},
-  {CC"RiType_isSubtypeOf",                CC"("RESOLVED_TYPE TYPE")Z",                          FN_PTR(RiType_2isSubtypeOf)},
-  {CC"RiType_leastCommonAncestor",        CC"("RESOLVED_TYPE RESOLVED_TYPE")"TYPE,              FN_PTR(RiType_2leastCommonAncestor)},
-  {CC"RiType_componentType",              CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1componentType)},
-  {CC"RiType_uniqueConcreteSubtype",      CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1uniqueConcreteSubtype)},
-  {CC"RiType_superType",                  CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1superType)},
-  {CC"RiType_arrayOf",                    CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1arrayOf)},
-  {CC"RiType_fields",                     CC"("RESOLVED_TYPE")["RESOLVED_FIELD,                 FN_PTR(RiType_1fields)},
-  {CC"RiType_isInitialized",              CC"("RESOLVED_TYPE")Z",                               FN_PTR(RiType_1isInitialized)},
+  {CC"JavaMethod_code",                     CC"("RESOLVED_METHOD")[B",                            FN_PTR(JavaMethod_1code)},
+  {CC"JavaMethod_signature",                CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(JavaMethod_1signature)},
+  {CC"JavaMethod_exceptionHandlers",        CC"("RESOLVED_METHOD")"EXCEPTION_HANDLERS,            FN_PTR(JavaMethod_1exceptionHandlers)},
+  {CC"JavaMethod_hasBalancedMonitors",      CC"("RESOLVED_METHOD")Z",                             FN_PTR(JavaMethod_1hasBalancedMonitors)},
+  {CC"JavaMethod_uniqueConcreteMethod",     CC"("RESOLVED_METHOD")"METHOD,                        FN_PTR(JavaMethod_1uniqueConcreteMethod)},
+  {CC"getJavaMethod",                       CC"("REFLECT_METHOD")"METHOD,                         FN_PTR(getJavaMethod)},
+  {CC"JavaMethod_methodData",               CC"("RESOLVED_METHOD")"METHOD_DATA,                   FN_PTR(JavaMethod_1methodData)},
+  {CC"JavaMethod_invocationCount",          CC"("RESOLVED_METHOD")I",                             FN_PTR(JavaMethod_1invocationCount)},
+  {CC"JavaMethod_hasCompiledCode",          CC"("RESOLVED_METHOD")Z",                             FN_PTR(JavaMethod_1hasCompiledCode)},
+  {CC"JavaMethod_getCompiledCodeSize",      CC"("RESOLVED_METHOD")I",                             FN_PTR(JavaMethod_1getCompiledCodeSize)},
+  {CC"Signature_lookupType",            CC"("STRING RESOLVED_TYPE"Z)"TYPE,                    FN_PTR(Signature_1lookupType)},
+  {CC"ConstantPool_lookupConstant",     CC"("RESOLVED_TYPE"I)"OBJECT,                         FN_PTR(ConstantPool_1lookupConstant)},
+  {CC"ConstantPool_lookupMethod",       CC"("RESOLVED_TYPE"IB)"METHOD,                        FN_PTR(ConstantPool_1lookupMethod)},
+  {CC"ConstantPool_lookupType",         CC"("RESOLVED_TYPE"I)"TYPE,                           FN_PTR(ConstantPool_1lookupType)},
+  {CC"ConstantPool_loadReferencedType", CC"("RESOLVED_TYPE"IB)V",                             FN_PTR(ConstantPool_1loadReferencedType)},
+  {CC"ConstantPool_lookupField",        CC"("RESOLVED_TYPE"IB)"FIELD,                         FN_PTR(ConstantPool_1lookupField)},
+  {CC"JavaType_resolveMethodImpl",          CC"("RESOLVED_TYPE STRING STRING")"METHOD,            FN_PTR(JavaType_3resolveMethodImpl)},
+  {CC"JavaType_isSubtypeOf",                CC"("RESOLVED_TYPE TYPE")Z",                          FN_PTR(JavaType_2isSubtypeOf)},
+  {CC"JavaType_leastCommonAncestor",        CC"("RESOLVED_TYPE RESOLVED_TYPE")"TYPE,              FN_PTR(JavaType_2leastCommonAncestor)},
+  {CC"JavaType_componentType",              CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(JavaType_1componentType)},
+  {CC"JavaType_uniqueConcreteSubtype",      CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(JavaType_1uniqueConcreteSubtype)},
+  {CC"JavaType_superType",                  CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(JavaType_1superType)},
+  {CC"JavaType_arrayOf",                    CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(JavaType_1arrayOf)},
+  {CC"JavaType_fields",                     CC"("RESOLVED_TYPE")["RESOLVED_FIELD,                 FN_PTR(JavaType_1fields)},
+  {CC"JavaType_isInitialized",              CC"("RESOLVED_TYPE")Z",                               FN_PTR(JavaType_1isInitialized)},
   {CC"getPrimitiveArrayType",             CC"("CI_KIND")"TYPE,                                  FN_PTR(getPrimitiveArrayType)},
   {CC"getMaxCallTargetOffset",            CC"("CI_RUNTIME_CALL")J",                             FN_PTR(getMaxCallTargetOffset)},
   {CC"getType",                           CC"("CLASS")"TYPE,                                    FN_PTR(getType)},
   {CC"getConfiguration",                  CC"()"CONFIG,                                         FN_PTR(getConfiguration)},
   {CC"installMethod",                     CC"("TARGET_METHOD"Z"HS_CODE_INFO")"HS_COMP_METHOD,   FN_PTR(installMethod)},
-  {CC"installStub",                       CC"("TARGET_METHOD HS_CODE_INFO")"PROXY,              FN_PTR(installStub)},
   {CC"disassembleNative",                 CC"([BJ)"STRING,                                      FN_PTR(disassembleNative)},
   {CC"disassembleJava",                   CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(disassembleJava)},
-  {CC"RiMethod_toStackTraceElement",      CC"("RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT,          FN_PTR(RiMethod_1toStackTraceElement)},
+  {CC"JavaMethod_toStackTraceElement",      CC"("RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT,          FN_PTR(JavaMethod_1toStackTraceElement)},
   {CC"executeCompiledMethod",             CC"("HS_COMP_METHOD OBJECT OBJECT OBJECT")"OBJECT,    FN_PTR(executeCompiledMethod)},
   {CC"executeCompiledMethodVarargs",      CC"("HS_COMP_METHOD "["OBJECT")"OBJECT,               FN_PTR(executeCompiledMethodVarargs)},
-  {CC"RiMethod_vtableEntryOffset",        CC"("RESOLVED_METHOD")I",                             FN_PTR(RiMethod_vtableEntryOffset)},
+  {CC"JavaMethod_vtableEntryOffset",        CC"("RESOLVED_METHOD")I",                             FN_PTR(JavaMethod_vtableEntryOffset)},
   {CC"getDeoptedLeafGraphIds",            CC"()[J",                                             FN_PTR(getDeoptedLeafGraphIds)},
+  {CC"decodePC",                          CC"(J)"STRING,                                        FN_PTR(decodePC)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/graal/graalJavaAccess.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalJavaAccess.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -36,8 +36,9 @@
     tty->print_cr("symbol with name %s was not found in symbol table (klass=%s)", name, klass_oop->klass_part()->name()->as_C_string());
   }
 #endif
-  guarantee(name_symbol != NULL, "symbol not found - class layout changed?");
-  guarantee(signature_symbol != NULL, "symbol not found - class layout changed?");
+  if (name_symbol == NULL || signature_symbol == NULL) {
+    guarantee(false, err_msg("symbol not found - class layout of %s changed?", klass_oop->klass_part()->name()->as_C_string()));
+  }
 
   instanceKlass* ik = instanceKlass::cast(klass_oop);
   fieldDescriptor fd;
--- a/src/share/vm/graal/graalJavaAccess.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -26,12 +26,12 @@
 #include "classfile/systemDictionary.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 
-/* This macro defines the structure of the CiTargetMethod - classes.
+/* This macro defines the structure of the InstalledCode - classes.
  * It will generate classes with accessors similar to javaClasses.hpp, but with specializations for oops, Handles and jni handles.
  *
  * The public interface of these classes will look like this:
 
- * class CiStackSlot : AllStatic {
+ * class StackSlot : AllStatic {
  * public:
  *   static klassOop klass();
  *   static jint  index(oop obj);
@@ -45,48 +45,48 @@
  */
 
 #define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, static_oop_field)   \
-  start_class(HotSpotTypeResolved)                                                      \
-    oop_field(HotSpotTypeResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;")     \
-    oop_field(HotSpotTypeResolved, javaMirror, "Ljava/lang/Class;")                     \
-    oop_field(HotSpotTypeResolved, simpleName, "Ljava/lang/String;")                    \
-    int_field(HotSpotTypeResolved, accessFlags)                                         \
-    boolean_field(HotSpotTypeResolved, hasFinalizer)                                    \
-    boolean_field(HotSpotTypeResolved, hasSubclass)                                     \
-    boolean_field(HotSpotTypeResolved, hasFinalizableSubclass)                          \
-    boolean_field(HotSpotTypeResolved, isArrayClass)                                    \
-    boolean_field(HotSpotTypeResolved, isInstanceClass)                                 \
-    boolean_field(HotSpotTypeResolved, isInterface)                                     \
-    int_field(HotSpotTypeResolved, instanceSize)                                        \
-  end_class                                                                             \
-  start_class(HotSpotMethodResolved)                                                    \
-    oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;")   \
-    oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;")                        \
-    oop_field(HotSpotMethodResolved, holder, "Lcom/oracle/max/cri/ri/RiResolvedType;")  \
-    oop_field(HotSpotMethodResolved, javaMirror, "Ljava/lang/Object;")                  \
-    int_field(HotSpotMethodResolved, codeSize)                                          \
-    int_field(HotSpotMethodResolved, accessFlags)                                       \
-    int_field(HotSpotMethodResolved, maxLocals)                                         \
-    int_field(HotSpotMethodResolved, maxStackSize)                                      \
-    boolean_field(HotSpotMethodResolved, canBeInlined)                                  \
+  start_class(HotSpotResolvedJavaType)                                                      \
+    oop_field(HotSpotResolvedJavaType, javaMirror, "Ljava/lang/Class;")                     \
+    oop_field(HotSpotResolvedJavaType, simpleName, "Ljava/lang/String;")                    \
+    int_field(HotSpotResolvedJavaType, accessFlags)                                         \
+    long_field(HotSpotResolvedJavaType, prototypeHeader)                                    \
+    boolean_field(HotSpotResolvedJavaType, hasFinalizer)                                    \
+    boolean_field(HotSpotResolvedJavaType, hasFinalizableSubclass)                          \
+    int_field(HotSpotResolvedJavaType, superCheckOffset)                                    \
+    boolean_field(HotSpotResolvedJavaType, isArrayClass)                                    \
+    boolean_field(HotSpotResolvedJavaType, isInstanceClass)                                 \
+    boolean_field(HotSpotResolvedJavaType, isInterface)                                     \
+    int_field(HotSpotResolvedJavaType, instanceSize)                                        \
+  end_class                                                                                 \
+  start_class(HotSpotKlassOop)                                                              \
+    oop_field(HotSpotKlassOop, type, "Lcom/oracle/graal/api/meta/ResolvedJavaType;")        \
+    end_class                                                                               \
+  start_class(HotSpotResolvedJavaMethod)                                                    \
+    oop_field(HotSpotResolvedJavaMethod, name, "Ljava/lang/String;")                        \
+    oop_field(HotSpotResolvedJavaMethod, holder, "Lcom/oracle/graal/api/meta/ResolvedJavaType;")  \
+    oop_field(HotSpotResolvedJavaMethod, javaMirror, "Ljava/lang/Object;")                  \
+    int_field(HotSpotResolvedJavaMethod, codeSize)                                          \
+    int_field(HotSpotResolvedJavaMethod, accessFlags)                                       \
+    int_field(HotSpotResolvedJavaMethod, maxLocals)                                         \
+    int_field(HotSpotResolvedJavaMethod, maxStackSize)                                      \
+    boolean_field(HotSpotResolvedJavaMethod, canBeInlined)                                  \
   end_class                                                                             \
   start_class(HotSpotMethodData)                                                        \
-    oop_field(HotSpotMethodData, compiler, "Lcom/oracle/graal/hotspot/Compiler;")       \
     oop_field(HotSpotMethodData, hotspotMirror, "Ljava/lang/Object;")                   \
     int_field(HotSpotMethodData, normalDataSize)                                        \
     int_field(HotSpotMethodData, extraDataSize)                                         \
   end_class                                                                             \
-  start_class(HotSpotType)                                                              \
-    oop_field(HotSpotType, name, "Ljava/lang/String;")                                  \
+  start_class(HotSpotJavaType)                                                              \
+    oop_field(HotSpotJavaType, name, "Ljava/lang/String;")                                  \
   end_class                                                                             \
-  start_class(HotSpotField)                                                             \
-    oop_field(HotSpotField, constant, "Lcom/oracle/max/cri/ci/CiConstant;")             \
-    int_field(HotSpotField, offset)                                                     \
-    int_field(HotSpotField, accessFlags)                                                \
+  start_class(HotSpotResolvedJavaField)                                                             \
+    oop_field(HotSpotResolvedJavaField, constant, "Lcom/oracle/graal/api/meta/Constant;")             \
+    int_field(HotSpotResolvedJavaField, offset)                                                     \
+    int_field(HotSpotResolvedJavaField, accessFlags)                                                \
   end_class                                                                             \
   start_class(HotSpotCompiledMethod)                                                    \
-    oop_field(HotSpotCompiledMethod, compiler, "Lcom/oracle/graal/hotspot/Compiler;")   \
     long_field(HotSpotCompiledMethod, nmethod)                                          \
-    oop_field(HotSpotCompiledMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;")\
+    oop_field(HotSpotCompiledMethod, method, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;")\
   end_class                                                                             \
   start_class(HotSpotCodeInfo)                                                          \
     long_field(HotSpotCodeInfo, start)                                                  \
@@ -96,142 +96,142 @@
     static_oop_field(HotSpotProxy, DUMMY_CONSTANT_OBJ, "Ljava/lang/Long;")              \
   end_class                                                                             \
   start_class(HotSpotTargetMethod)                                                      \
-    oop_field(HotSpotTargetMethod, targetMethod, "Lcom/oracle/max/cri/ci/CiTargetMethod;") \
-    oop_field(HotSpotTargetMethod, method, "Lcom/oracle/graal/hotspot/ri/HotSpotMethodResolved;") \
+    oop_field(HotSpotTargetMethod, targetMethod, "Lcom/oracle/graal/api/code/CompilationResult;") \
+    oop_field(HotSpotTargetMethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \
     oop_field(HotSpotTargetMethod, name, "Ljava/lang/String;")                          \
-    oop_field(HotSpotTargetMethod, sites, "[Lcom/oracle/max/cri/ci/CiTargetMethod$Site;") \
-    oop_field(HotSpotTargetMethod, exceptionHandlers, "[Lcom/oracle/max/cri/ci/CiTargetMethod$ExceptionHandler;") \
+    oop_field(HotSpotTargetMethod, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;") \
+    oop_field(HotSpotTargetMethod, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;") \
   end_class                                                                             \
-  start_class(HotSpotExceptionHandler)                                                  \
-    int_field(HotSpotExceptionHandler, startBci)                                        \
-    int_field(HotSpotExceptionHandler, endBci)                                          \
-    int_field(HotSpotExceptionHandler, handlerBci)                                      \
-    int_field(HotSpotExceptionHandler, catchClassIndex)                                 \
-    oop_field(HotSpotExceptionHandler, catchClass, "Lcom/oracle/max/cri/ri/RiType;")    \
+  start_class(ExceptionHandler)                                                  \
+    int_field(ExceptionHandler, startBCI)                                        \
+    int_field(ExceptionHandler, endBCI)                                          \
+    int_field(ExceptionHandler, handlerBCI)                                      \
+    int_field(ExceptionHandler, catchTypeCPI)                                 \
+    oop_field(ExceptionHandler, catchType, "Lcom/oracle/graal/api/meta/JavaType;")    \
   end_class                                                                             \
-  start_class(CiTargetMethod)                                                           \
-    int_field(CiTargetMethod, frameSize)                                                \
-    int_field(CiTargetMethod, customStackAreaOffset)                                    \
-    oop_field(CiTargetMethod, targetCode, "[B")                                         \
-    oop_field(CiTargetMethod, assumptions, "Lcom/oracle/max/cri/ci/CiAssumptions;")     \
-    int_field(CiTargetMethod, targetCodeSize)                                           \
+  start_class(InstalledCode)                                                           \
+    int_field(InstalledCode, frameSize)                                                \
+    int_field(InstalledCode, customStackAreaOffset)                                    \
+    oop_field(InstalledCode, targetCode, "[B")                                         \
+    oop_field(InstalledCode, assumptions, "Lcom/oracle/graal/api/code/Assumptions;")     \
+    int_field(InstalledCode, targetCodeSize)                                           \
   end_class                                                                             \
-  start_class(CiAssumptions)                                                            \
-    oop_field(CiAssumptions, list, "[Lcom/oracle/max/cri/ci/CiAssumptions$Assumption;") \
+  start_class(Assumptions)                                                            \
+    oop_field(Assumptions, list, "[Lcom/oracle/graal/api/code/Assumptions$Assumption;") \
   end_class                                                                             \
-  start_class(CiAssumptions_MethodContents)                                             \
-    oop_field(CiAssumptions_MethodContents, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
+  start_class(Assumptions_MethodContents)                                             \
+    oop_field(Assumptions_MethodContents, method, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;") \
   end_class                                                                             \
-  start_class(CiAssumptions_ConcreteSubtype)                                            \
-    oop_field(CiAssumptions_ConcreteSubtype, context, "Lcom/oracle/max/cri/ri/RiResolvedType;") \
-    oop_field(CiAssumptions_ConcreteSubtype, subtype, "Lcom/oracle/max/cri/ri/RiResolvedType;") \
+  start_class(Assumptions_ConcreteSubtype)                                            \
+    oop_field(Assumptions_ConcreteSubtype, context, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \
+    oop_field(Assumptions_ConcreteSubtype, subtype, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \
   end_class                                                                             \
-  start_class(CiAssumptions_ConcreteMethod)                                             \
-    oop_field(CiAssumptions_ConcreteMethod, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
-    oop_field(CiAssumptions_ConcreteMethod, context, "Lcom/oracle/max/cri/ri/RiResolvedType;") \
-    oop_field(CiAssumptions_ConcreteMethod, impl, "Lcom/oracle/max/cri/ri/RiResolvedMethod;") \
+  start_class(Assumptions_ConcreteMethod)                                             \
+    oop_field(Assumptions_ConcreteMethod, method, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;") \
+    oop_field(Assumptions_ConcreteMethod, context, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \
+    oop_field(Assumptions_ConcreteMethod, impl, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;") \
   end_class                                                                             \
-  start_class(CiTargetMethod_Site)                                                      \
-    int_field(CiTargetMethod_Site, pcOffset)                                            \
+  start_class(InstalledCode_Site)                                                      \
+    int_field(InstalledCode_Site, pcOffset)                                            \
   end_class                                                                             \
-  start_class(CiTargetMethod_Call)                                                      \
-    oop_field(CiTargetMethod_Call, target, "Ljava/lang/Object;")                        \
-    oop_field(CiTargetMethod_Call, debugInfo, "Lcom/oracle/max/cri/ci/CiDebugInfo;")    \
+  start_class(InstalledCode_Call)                                                      \
+    oop_field(InstalledCode_Call, target, "Ljava/lang/Object;")                        \
+    oop_field(InstalledCode_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;")    \
   end_class                                                                             \
-  start_class(CiTargetMethod_DataPatch)                                                 \
-    oop_field(CiTargetMethod_DataPatch, constant, "Lcom/oracle/max/cri/ci/CiConstant;") \
-    int_field(CiTargetMethod_DataPatch, alignment)                                      \
+  start_class(InstalledCode_DataPatch)                                                 \
+    oop_field(InstalledCode_DataPatch, constant, "Lcom/oracle/graal/api/meta/Constant;") \
+    int_field(InstalledCode_DataPatch, alignment)                                      \
   end_class                                                                             \
-  start_class(CiTargetMethod_Safepoint)                                                 \
-    oop_field(CiTargetMethod_Safepoint, debugInfo, "Lcom/oracle/max/cri/ci/CiDebugInfo;") \
+  start_class(InstalledCode_Safepoint)                                                 \
+    oop_field(InstalledCode_Safepoint, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \
   end_class                                                                             \
-  start_class(CiTargetMethod_ExceptionHandler)                                          \
-    int_field(CiTargetMethod_ExceptionHandler, handlerPos)                              \
+  start_class(InstalledCode_ExceptionHandler)                                          \
+    int_field(InstalledCode_ExceptionHandler, handlerPos)                              \
   end_class                                                                             \
-  start_class(CiTargetMethod_Mark)                                                      \
-    oop_field(CiTargetMethod_Mark, id, "Ljava/lang/Object;")                            \
-    oop_field(CiTargetMethod_Mark, references, "[Lcom/oracle/max/cri/ci/CiTargetMethod$Mark;") \
+  start_class(InstalledCode_Mark)                                                      \
+    oop_field(InstalledCode_Mark, id, "Ljava/lang/Object;")                            \
+    oop_field(InstalledCode_Mark, references, "[Lcom/oracle/graal/api/code/CompilationResult$Mark;") \
   end_class                                                                             \
-  start_class(CiDebugInfo)                                                              \
-    oop_field(CiDebugInfo, codePos, "Lcom/oracle/max/cri/ci/CiCodePos;")                \
-    oop_field(CiDebugInfo, registerRefMap, "Lcom/oracle/max/cri/ci/CiBitMap;")          \
-    oop_field(CiDebugInfo, frameRefMap, "Lcom/oracle/max/cri/ci/CiBitMap;")             \
+  start_class(DebugInfo)                                                              \
+    oop_field(DebugInfo, bytecodePosition, "Lcom/oracle/graal/api/code/BytecodePosition;")                \
+    oop_field(DebugInfo, registerRefMap, "Ljava/util/BitSet;")          \
+    oop_field(DebugInfo, frameRefMap, "Ljava/util/BitSet;")             \
   end_class                                                                             \
   start_class(GraalBitMap)                                                              \
-    int_field(GraalBitMap, size)                                                        \
-    long_field(GraalBitMap, low)                                                        \
-    oop_field(GraalBitMap, extra, "[J")                                                 \
+    oop_field(GraalBitMap, words, "[J")                                                 \
   end_class                                                                             \
-  start_class(CiFrame)                                                                  \
-    oop_field(CiFrame, values, "[Lcom/oracle/max/cri/ci/CiValue;")                      \
-    int_field(CiFrame, numLocals)                                                       \
-    int_field(CiFrame, numStack)                                                        \
-    int_field(CiFrame, numLocks)                                                        \
-    long_field(CiFrame, leafGraphId)                                                    \
-    boolean_field(CiFrame, rethrowException)                                            \
-    boolean_field(CiFrame, duringCall)                                                  \
+  start_class(BytecodeFrame)                                                                  \
+    oop_field(BytecodeFrame, values, "[Lcom/oracle/graal/api/meta/Value;")                      \
+    int_field(BytecodeFrame, numLocals)                                                       \
+    int_field(BytecodeFrame, numStack)                                                        \
+    int_field(BytecodeFrame, numLocks)                                                        \
+    long_field(BytecodeFrame, leafGraphId)                                                    \
+    boolean_field(BytecodeFrame, rethrowException)                                            \
+    boolean_field(BytecodeFrame, duringCall)                                                  \
   end_class                                                                             \
-  start_class(CiCodePos)                                                                \
-    oop_field(CiCodePos, caller, "Lcom/oracle/max/cri/ci/CiCodePos;")                   \
-    oop_field(CiCodePos, method, "Lcom/oracle/max/cri/ri/RiResolvedMethod;")            \
-    int_field(CiCodePos, bci)                                                           \
+  start_class(BytecodePosition)                                                                \
+    oop_field(BytecodePosition, caller, "Lcom/oracle/graal/api/code/BytecodePosition;")                   \
+    oop_field(BytecodePosition, method, "Lcom/oracle/graal/api/meta/ResolvedJavaMethod;")            \
+    int_field(BytecodePosition, bci)                                                           \
   end_class                                                                             \
-  start_class(CiConstant)                                                               \
-    oop_field(CiConstant, kind, "Lcom/oracle/max/cri/ci/CiKind;")                       \
-    oop_field(CiConstant, object, "Ljava/lang/Object;")                                 \
-    long_field(CiConstant, primitive)                                                   \
+  start_class(Constant)                                                               \
+    oop_field(Constant, kind, "Lcom/oracle/graal/api/meta/Kind;")                       \
+    oop_field(Constant, object, "Ljava/lang/Object;")                                 \
+    long_field(Constant, primitive)                                                   \
   end_class                                                                             \
-  start_class(CiKind)                                                                   \
-    char_field(CiKind, typeChar)                                                        \
-    static_oop_field(CiKind, Boolean, "Lcom/oracle/max/cri/ci/CiKind;");                \
-    static_oop_field(CiKind, Byte, "Lcom/oracle/max/cri/ci/CiKind;");                   \
-    static_oop_field(CiKind, Char, "Lcom/oracle/max/cri/ci/CiKind;");                   \
-    static_oop_field(CiKind, Short, "Lcom/oracle/max/cri/ci/CiKind;");                  \
-    static_oop_field(CiKind, Int, "Lcom/oracle/max/cri/ci/CiKind;");                    \
-    static_oop_field(CiKind, Long, "Lcom/oracle/max/cri/ci/CiKind;");                   \
+  start_class(Kind)                                                                   \
+    char_field(Kind, typeChar)                                                        \
+    static_oop_field(Kind, Boolean, "Lcom/oracle/graal/api/meta/Kind;");                \
+    static_oop_field(Kind, Byte, "Lcom/oracle/graal/api/meta/Kind;");                   \
+    static_oop_field(Kind, Char, "Lcom/oracle/graal/api/meta/Kind;");                   \
+    static_oop_field(Kind, Short, "Lcom/oracle/graal/api/meta/Kind;");                  \
+    static_oop_field(Kind, Int, "Lcom/oracle/graal/api/meta/Kind;");                    \
+    static_oop_field(Kind, Long, "Lcom/oracle/graal/api/meta/Kind;");                   \
   end_class                                                                             \
-  start_class(CiRuntimeCall)                                                            \
-    static_oop_field(CiRuntimeCall, UnwindException, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
-    static_oop_field(CiRuntimeCall, RegisterFinalizer, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
-    static_oop_field(CiRuntimeCall, SetDeoptInfo, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");    \
-    static_oop_field(CiRuntimeCall, CreateNullPointerException, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
-    static_oop_field(CiRuntimeCall, CreateOutOfBoundsException, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
-    static_oop_field(CiRuntimeCall, JavaTimeMillis, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");  \
-    static_oop_field(CiRuntimeCall, JavaTimeNanos, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
-    static_oop_field(CiRuntimeCall, Debug, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");           \
-    static_oop_field(CiRuntimeCall, ArithmeticFrem, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");  \
-    static_oop_field(CiRuntimeCall, ArithmeticDrem, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");  \
-    static_oop_field(CiRuntimeCall, ArithmeticCos, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
-    static_oop_field(CiRuntimeCall, ArithmeticTan, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
-    static_oop_field(CiRuntimeCall, ArithmeticSin, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");   \
-    static_oop_field(CiRuntimeCall, Deoptimize, "Lcom/oracle/max/cri/ci/CiRuntimeCall;");      \
-    static_oop_field(CiRuntimeCall, GenericCallback, "Lcom/oracle/max/cri/ci/CiRuntimeCall;"); \
+  start_class(RuntimeCall)                                                            \
+    static_oop_field(RuntimeCall, UnwindException, "Lcom/oracle/graal/api/code/RuntimeCall;"); \
+    static_oop_field(RuntimeCall, RegisterFinalizer, "Lcom/oracle/graal/api/code/RuntimeCall;"); \
+    static_oop_field(RuntimeCall, SetDeoptInfo, "Lcom/oracle/graal/api/code/RuntimeCall;");    \
+    static_oop_field(RuntimeCall, CreateNullPointerException, "Lcom/oracle/graal/api/code/RuntimeCall;"); \
+    static_oop_field(RuntimeCall, CreateOutOfBoundsException, "Lcom/oracle/graal/api/code/RuntimeCall;"); \
+    static_oop_field(RuntimeCall, JavaTimeMillis, "Lcom/oracle/graal/api/code/RuntimeCall;");  \
+    static_oop_field(RuntimeCall, JavaTimeNanos, "Lcom/oracle/graal/api/code/RuntimeCall;");   \
+    static_oop_field(RuntimeCall, Debug, "Lcom/oracle/graal/api/code/RuntimeCall;");           \
+    static_oop_field(RuntimeCall, ArithmeticFrem, "Lcom/oracle/graal/api/code/RuntimeCall;");  \
+    static_oop_field(RuntimeCall, ArithmeticDrem, "Lcom/oracle/graal/api/code/RuntimeCall;");  \
+    static_oop_field(RuntimeCall, ArithmeticCos, "Lcom/oracle/graal/api/code/RuntimeCall;");   \
+    static_oop_field(RuntimeCall, ArithmeticTan, "Lcom/oracle/graal/api/code/RuntimeCall;");   \
+    static_oop_field(RuntimeCall, ArithmeticSin, "Lcom/oracle/graal/api/code/RuntimeCall;");   \
+    static_oop_field(RuntimeCall, Deoptimize, "Lcom/oracle/graal/api/code/RuntimeCall;");      \
+    static_oop_field(RuntimeCall, GenericCallback, "Lcom/oracle/graal/api/code/RuntimeCall;"); \
+    static_oop_field(RuntimeCall, LogPrimitive, "Lcom/oracle/graal/api/code/RuntimeCall;");    \
+    static_oop_field(RuntimeCall, LogObject, "Lcom/oracle/graal/api/code/RuntimeCall;");       \
   end_class                                                                             \
-  start_class(RiMethod)                                                                 \
+  start_class(JavaMethod)                                                                 \
   end_class                                                                             \
-  start_class(CiValue)                                                                  \
-    oop_field(CiValue, kind, "Lcom/oracle/max/cri/ci/CiKind;")                          \
-    static_oop_field(CiValue, IllegalValue, "Lcom/oracle/max/cri/ci/CiValue;");         \
+  start_class(Value)                                                                  \
+    oop_field(Value, kind, "Lcom/oracle/graal/api/meta/Kind;")                          \
+    static_oop_field(Value, IllegalValue, "Lcom/oracle/graal/api/meta/Value;");         \
   end_class                                                                             \
-  start_class(CiRegisterValue)                                                          \
-    oop_field(CiRegisterValue, reg, "Lcom/oracle/max/cri/ci/CiRegister;")               \
+  start_class(RegisterValue)                                                          \
+    oop_field(RegisterValue, reg, "Lcom/oracle/graal/api/code/Register;")               \
   end_class                                                                             \
-  start_class(CiRegister)                                                               \
-    int_field(CiRegister, number)                                                       \
+  start_class(code_Register)                                                               \
+    int_field(code_Register, number)                                                       \
   end_class                                                                             \
-  start_class(CiStackSlot)                                                              \
-    int_field(CiStackSlot, offset)                                                      \
-    boolean_field(CiStackSlot, addFrameSize)                                            \
+  start_class(StackSlot)                                                              \
+    int_field(StackSlot, offset)                                                      \
+    boolean_field(StackSlot, addFrameSize)                                            \
   end_class                                                                             \
-  start_class(CiVirtualObject)                                                          \
-    int_field(CiVirtualObject, id)                                                      \
-    oop_field(CiVirtualObject, type, "Lcom/oracle/max/cri/ri/RiType;")                  \
-    oop_field(CiVirtualObject, values, "[Lcom/oracle/max/cri/ci/CiValue;")              \
+  start_class(VirtualObject)                                                          \
+    int_field(VirtualObject, id)                                                      \
+    oop_field(VirtualObject, type, "Lcom/oracle/graal/api/meta/JavaType;")                  \
+    oop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/Value;")              \
   end_class                                                                             \
-  start_class(CiMonitorValue)                                                           \
-    oop_field(CiMonitorValue, owner, "Lcom/oracle/max/cri/ci/CiValue;")                 \
-    oop_field(CiMonitorValue, lockData, "Lcom/oracle/max/cri/ci/CiValue;")              \
-    boolean_field(CiMonitorValue, eliminated)                                           \
+  start_class(code_MonitorValue)                                                           \
+    oop_field(code_MonitorValue, owner, "Lcom/oracle/graal/api/meta/Value;")                 \
+    oop_field(code_MonitorValue, lockData, "Lcom/oracle/graal/api/meta/Value;")              \
+    boolean_field(code_MonitorValue, eliminated)                                           \
   end_class                                                                             \
   /* end*/
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalRuntime.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+#include "precompiled.hpp"
+
+#include "graal/graalVMToCompiler.hpp"
+
+// JVM_InitializeGraalRuntime
+JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
+  return VMToCompiler::compilerPermObject();
+JVM_END
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/graal/graalRuntime.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -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.
+ */
+
+class GraalRuntime : public AllStatic {
+
+private:
+  jobject _runtimeObject;
+
+public:
+  static jobject instance() { return _runtimeObject; }
+
+};
\ No newline at end of file
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -40,8 +40,8 @@
 
 Handle VMToCompiler::compilerInstance() {
   if (JNIHandles::resolve(_compilerPermObject) == NULL) {
-    KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_hotspot_CompilerImpl(), SystemDictionary::java_system_loader(), NULL, Thread::current());
-    check_not_null(compilerImplKlass(), "Couldn't find class com.sun.hotspot.graal.CompilerImpl");
+    KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+    check_not_null(compilerImplKlass(), "Couldn't find class com.sun.hotspot.graal.HotSpotGraalRuntime");
 
     JavaValue result(T_OBJECT);
     JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::getInstance_name(), vmSymbols::getInstance_signature(), Thread::current());
@@ -53,28 +53,19 @@
 
 Handle VMToCompiler::instance() {
   if (JNIHandles::resolve(_vmToCompilerPermObject) == NULL) {
-    KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_hotspot_Compiler(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+    KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime(), SystemDictionary::java_system_loader(), NULL, Thread::current());
     check_not_null(compilerKlass(), "Couldn't find class com.sun.hotspot.graal.Compiler");
 
     JavaValue result(T_OBJECT);
     JavaCallArguments args;
     args.set_receiver(compilerInstance());
-    JavaCalls::call_interface(&result, compilerKlass, vmSymbols::getVMToCompiler_name(), vmSymbols::getVMToCompiler_signature(), &args, Thread::current());
+    JavaCalls::call_virtual(&result, compilerKlass, vmSymbols::getVMToCompiler_name(), vmSymbols::getVMToCompiler_signature(), &args, Thread::current());
     check_pending_exception("Couldn't get VMToCompiler");
     _vmToCompilerPermObject = JNIHandles::make_global((oop) result.get_jobject());
   }
   return Handle(JNIHandles::resolve_non_null(_vmToCompilerPermObject));
 }
 
-void VMToCompiler::initializeCompiler() {
-  KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_hotspot_CompilerImpl(), SystemDictionary::java_system_loader(), NULL, Thread::current());
-  check_not_null(compilerImplKlass(), "Couldn't find class com.sun.hotspot.graal.CompilerImpl");
-
-  JavaValue result(T_VOID);
-  JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::initialize_name(), vmSymbols::void_method_signature(), Thread::current());
-  check_pending_exception("Couldn't initialize compiler");
-}
-
 jboolean VMToCompiler::setOption(Handle option) {
   assert(!option.is_null(), "");
   KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions(), SystemDictionary::java_system_loader(), NULL, Thread::current());
@@ -150,19 +141,19 @@
   check_pending_exception("Error while calling boostrap");
 }
 
-oop VMToCompiler::createRiMethodResolved(jlong vmId, Handle name, TRAPS) {
+oop VMToCompiler::createResolvedJavaMethod(jlong vmId, Handle name, TRAPS) {
   assert(!name.is_null(), "just checking");
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_long(vmId);
   args.push_oop(name);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createRiMethodResolved_name(), vmSymbols::createRiMethodResolved_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiMethodResolved");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createResolvedJavaMethod_name(), vmSymbols::createResolvedJavaMethod_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createResolvedJavaMethod");
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS) {
+oop VMToCompiler::createJavaMethod(Handle name, Handle signature, Handle holder, TRAPS) {
   assert(!name.is_null(), "just checking");
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
@@ -170,12 +161,12 @@
   args.push_oop(name);
   args.push_oop(signature);
   args.push_oop(holder);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createRiMethodUnresolved_name(), vmSymbols::createRiMethodUnresolved_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiMethodUnresolved");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createJavaMethod_name(), vmSymbols::createJavaMethod_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createJavaMethod");
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createRiField(Handle holder, Handle name, Handle type, int index, int flags, TRAPS) {
+oop VMToCompiler::createJavaField(Handle holder, Handle name, Handle type, int index, int flags, TRAPS) {
   assert(!holder.is_null(), "just checking");
   assert(!name.is_null(), "just checking");
   assert(!type.is_null(), "just checking");
@@ -187,95 +178,83 @@
   args.push_oop(type);
   args.push_int(index);
   args.push_int(flags);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createRiField_name(), vmSymbols::createRiField_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiField");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createJavaField_name(), vmSymbols::createJavaField_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createJavaField");
   assert(result.get_type() == T_OBJECT, "just checking");
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createRiType(jlong vmId, Handle name, TRAPS) {
-  assert(!name.is_null(), "just checking");
-  JavaValue result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_long(vmId);
-  args.push_oop(name);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createRiType_name(), vmSymbols::createRiType_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiType");
-  return (oop) result.get_jobject();
-}
-
-oop VMToCompiler::createRiTypePrimitive(int basic_type, TRAPS) {
+oop VMToCompiler::createPrimitiveJavaType(int basic_type, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_int(basic_type);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createRiTypePrimitive_name(), vmSymbols::createRiTypePrimitive_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiTypePrimitive");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createPrimitiveJavaType_name(), vmSymbols::createPrimitiveJavaType_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createPrimitiveJavaType");
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createRiTypeUnresolved(Handle name, TRAPS) {
+oop VMToCompiler::createJavaType(Handle name, TRAPS) {
   assert(!name.is_null(), "just checking");
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_oop(name);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createRiTypeUnresolved_name(), vmSymbols::createRiTypeUnresolved_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiTypeUnresolved");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createJavaType_name(), vmSymbols::createJavaType_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createJavaType");
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createRiSignature(Handle name, TRAPS) {
+oop VMToCompiler::createSignature(Handle name, TRAPS) {
   assert(!name.is_null(), "just checking");
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_oop(name);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createRiSignature_name(), vmSymbols::createRiSignature_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createRiSignature");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createSignature_name(), vmSymbols::createSignature_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createSignature");
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createCiConstant(Handle kind, jlong value, TRAPS) {
+oop VMToCompiler::createConstant(Handle kind, jlong value, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_oop(kind());
   args.push_long(value);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createCiConstant_name(), vmSymbols::createCiConstant_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createCiConstantFloat");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createConstant_name(), vmSymbols::createConstant_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createConstantFloat");
   return (oop) result.get_jobject();
 
 }
 
-oop VMToCompiler::createCiConstantFloat(jfloat value, TRAPS) {
+oop VMToCompiler::createConstantFloat(jfloat value, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_float(value);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createCiConstantFloat_name(), vmSymbols::createCiConstantFloat_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createCiConstantFloat");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createConstantFloat_name(), vmSymbols::createConstantFloat_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createConstantFloat");
   return (oop) result.get_jobject();
 
 }
 
-oop VMToCompiler::createCiConstantDouble(jdouble value, TRAPS) {
+oop VMToCompiler::createConstantDouble(jdouble value, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   args.push_oop(instance());
   args.push_double(value);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createCiConstantDouble_name(), vmSymbols::createCiConstantDouble_signature(), &args, THREAD);
-  check_pending_exception("Error while calling createCiConstantDouble");
+  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createConstantDouble_name(), vmSymbols::createConstantDouble_signature(), &args, THREAD);
+  check_pending_exception("Error while calling createConstantDouble");
   return (oop) result.get_jobject();
 }
 
-oop VMToCompiler::createCiConstantObject(Handle object, TRAPS) {
+oop VMToCompiler::createConstantObject(Handle object, TRAPS) {
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
-  KlassHandle klass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_max_cri_ci_CiConstant(), SystemDictionary::java_system_loader(), NULL, Thread::current());
-  JavaCalls::call_static(&result, klass(), vmSymbols::forObject_name(), vmSymbols::createCiConstantObject_signature(), object, THREAD);
-  check_pending_exception("Error while calling CiConstant.forObject");
+  KlassHandle klass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_api_meta_Constant(), SystemDictionary::java_system_loader(), NULL, Thread::current());
+  JavaCalls::call_static(&result, klass(), vmSymbols::forObject_name(), vmSymbols::createConstantObject_signature(), object, THREAD);
+  check_pending_exception("Error while calling Constant.forObject");
   return (oop) result.get_jobject();
 }
 
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -40,9 +40,11 @@
   static Handle instance();
 
 public:
-  static void initializeCompiler();
+  static Handle compilerInstance();
 
-  static Handle compilerInstance();
+  static jobject compilerPermObject() {
+    return _compilerPermObject;
+  }
 
   // public static boolean HotSpotOptions.setOption(String option);
   static jboolean setOption(Handle option);
@@ -62,38 +64,35 @@
   // public abstract void bootstrap();
   static void bootstrap();
 
-  // public abstract RiMethod createRiMethodResolved(long vmId, String name);
-  static oop createRiMethodResolved(jlong vmId, Handle name, TRAPS);
+  // public abstract JavaMethod createResolvedJavaMethod(long vmId, String name);
+  static oop createResolvedJavaMethod(jlong vmId, Handle name, TRAPS);
 
-  // public abstract RiMethod createRiMethodUnresolved(String name, String signature, RiType holder);
-  static oop createRiMethodUnresolved(Handle name, Handle signature, Handle holder, TRAPS);
+  // public abstract JavaMethod createJavaMethod(String name, String signature, JavaType holder);
+  static oop createJavaMethod(Handle name, Handle signature, Handle holder, TRAPS);
 
-  // public abstract RiField createRiField(RiType holder, String name, RiType type, int flags, int offset);
-  static oop createRiField(Handle holder, Handle name, Handle type, int index, int flags, TRAPS);
+  // public abstract JavaField createJavaField(JavaType holder, String name, JavaType type, int flags, int offset);
+  static oop createJavaField(Handle holder, Handle name, Handle type, int index, int flags, TRAPS);
 
-  // public abstract RiType createRiType(long vmId, String name);
-  static oop createRiType(jlong vmId, Handle name, TRAPS);
+  // public abstract JavaType createJavaType(String name);
+  static oop createJavaType(Handle name, TRAPS);
 
-  // public abstract RiType createRiTypeUnresolved(String name);
-  static oop createRiTypeUnresolved(Handle name, TRAPS);
+  // public abstract JavaType createPrimitiveJavaType(int basicType);
+  static oop createPrimitiveJavaType(int basicType, TRAPS);
 
-  // public abstract RiType createRiTypePrimitive(int basicType);
-  static oop createRiTypePrimitive(int basicType, TRAPS);
+  // public abstract Signature createSignature(String signature);
+  static oop createSignature(Handle name, TRAPS);
 
-  // public abstract RiSignature createRiSignature(String signature);
-  static oop createRiSignature(Handle name, TRAPS);
-
-  // public abstract CiConstant createCiConstant(CiKind kind, long value);
-  static oop createCiConstant(Handle kind, jlong value, TRAPS);
+  // public abstract Constant createConstant(Kind kind, long value);
+  static oop createConstant(Handle kind, jlong value, TRAPS);
 
-  // public abstract CiConstant createCiConstantFloat(float value);
-  static oop createCiConstantFloat(jfloat value, TRAPS);
+  // public abstract Constant createConstantFloat(float value);
+  static oop createConstantFloat(jfloat value, TRAPS);
 
-  // public abstract CiConstant createCiConstantDouble(double value);
-  static oop createCiConstantDouble(jdouble value, TRAPS);
+  // public abstract Constant createConstantDouble(double value);
+  static oop createConstantDouble(jdouble value, TRAPS);
 
-  // public abstract CiConstant createCiConstantObject(long vmId);
-  static oop createCiConstantObject(Handle object, TRAPS);
+  // public abstract Constant createConstantObject(long vmId);
+  static oop createConstantObject(Handle object, TRAPS);
 };
 
 inline void check_pending_exception(const char* message, bool dump_core = false) {
--- a/src/share/vm/oops/klass.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/oops/klass.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -239,7 +239,7 @@
   klassOop    _primary_supers[_primary_super_limit];
   // java/lang/Class instance mirroring this class
   oop       _java_mirror;
-  // com/oracle/graal/hotspot/HotSpotTypeResolved mirroring this class
+  // com/oracle/graal/hotspot/HotSpotResolvedJavaType mirroring this class
   oop       _graal_mirror;
   // Superclass
   klassOop  _super;
--- a/src/share/vm/oops/methodOop.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/oops/methodOop.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -665,7 +665,7 @@
 #ifdef GRAAL
   oop graal_mirror = this->graal_mirror();
   if (graal_mirror != NULL) {
-    HotSpotMethodResolved::set_canBeInlined(graal_mirror, false);
+    HotSpotResolvedJavaMethod::set_canBeInlined(graal_mirror, false);
   }
 #endif
 }
--- a/src/share/vm/oops/methodOop.hpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/oops/methodOop.hpp	Wed Jun 27 17:35:32 2012 +0200
@@ -132,7 +132,7 @@
   InvocationCounter _backedge_counter;           // Incremented before each backedge taken - used to trigger frequencey-based optimizations
 
 #ifdef GRAAL
-  oop               _graal_mirror;               // com/oracle/graal/hotspot/HotSpotMethodResolved mirroring this method
+  oop               _graal_mirror;               // com/oracle/graal/hotspot/HotSpotResolvedJavaMethod mirroring this method
   jlong             _graal_invocation_time;
   int               _graal_priority;
 #endif
--- a/src/share/vm/opto/bytecodeInfo.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/opto/bytecodeInfo.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -240,6 +240,9 @@
     // ignore heuristic controls on inlining
     return NULL;
   }
+  if (callee_method->should_not_inline()) {
+    return "disallowed by CompilerOracle";
+  }
 
   // Now perform checks which are heuristic
 
@@ -278,10 +281,6 @@
     }
   }
 
-  if (callee_method->should_not_inline()) {
-    return "disallowed by CompilerOracle";
-  }
-
   if (UseStringCache) {
     // Do not inline StringCache::profile() method used only at the beginning.
     if (callee_method->name() == ciSymbol::profile_name() &&
--- a/src/share/vm/prims/jvmtiLib.xsl	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/prims/jvmtiLib.xsl	Wed Jun 27 17:35:32 2012 +0200
@@ -753,7 +753,7 @@
   </xsl:template>
 
 
-<!-- ======== HotSpotType ======== -->
+<!-- ======== HotSpotJavaType ======== -->
 
 <xsl:template match="parameters" mode="HotSpotSig">
   <xsl:variable name="length" select="count(param)"/>
@@ -777,7 +777,7 @@
 <xsl:template match="param" mode="HotSpotSig">
   <xsl:param name="comma"/>
   <xsl:variable name="result">
-    <xsl:apply-templates select="child::*[position()=1]" mode="HotSpotType"/>
+    <xsl:apply-templates select="child::*[position()=1]" mode="HotSpotJavaType"/>
   </xsl:variable>
   <xsl:if test="string-length($result)!=0">
     <xsl:value-of select="$result"/>
@@ -789,7 +789,7 @@
   </xsl:if>
 </xsl:template>
 
-<xsl:template match="jthread" mode="HotSpotType">
+<xsl:template match="jthread" mode="HotSpotJavaType">
   <xsl:choose>
     <xsl:when test="count(@impl)=0 or not(contains(@impl,'noconvert'))">
       <xsl:text>JavaThread*</xsl:text>
@@ -800,23 +800,23 @@
   </xsl:choose>
 </xsl:template>
 
-<xsl:template match="jrawMonitorID" mode="HotSpotType">
+<xsl:template match="jrawMonitorID" mode="HotSpotJavaType">
   <xsl:text>JvmtiRawMonitor *</xsl:text>
 </xsl:template>
 
-<xsl:template match="jframeID" mode="HotSpotType">
+<xsl:template match="jframeID" mode="HotSpotJavaType">
   <xsl:text>jint</xsl:text>
 </xsl:template>
 
-<xsl:template match="jmethodID" mode="HotSpotType">
+<xsl:template match="jmethodID" mode="HotSpotJavaType">
   <xsl:text>methodOop</xsl:text>
 </xsl:template>
 
-<xsl:template match="jfieldID" mode="HotSpotType">
+<xsl:template match="jfieldID" mode="HotSpotJavaType">
   <xsl:text>fieldDescriptor*</xsl:text>
 </xsl:template>
 
-<xsl:template match="jclass" mode="HotSpotType">
+<xsl:template match="jclass" mode="HotSpotJavaType">
   <!--
     classes passed as part of a class/method or class/field pair are used
     by the wrapper to get the internal type but are not needed by nor 
@@ -827,38 +827,38 @@
   </xsl:if>
 </xsl:template>
 
-<xsl:template match="nullok" mode="HotSpotType">
+<xsl:template match="nullok" mode="HotSpotJavaType">
 </xsl:template>
 
-<xsl:template match="jobject|jvalue|jthreadGroup|enum|jint|jchar|jlong|jfloat|jdouble|jlocation|jboolean|char|uchar|size_t|void|struct" mode="HotSpotType">
+<xsl:template match="jobject|jvalue|jthreadGroup|enum|jint|jchar|jlong|jfloat|jdouble|jlocation|jboolean|char|uchar|size_t|void|struct" mode="HotSpotJavaType">
   <xsl:apply-templates select="." mode="btsig"/>
 </xsl:template>
 
-<xsl:template match="varargs" mode="HotSpotType">
+<xsl:template match="varargs" mode="HotSpotJavaType">
   <xsl:text> </xsl:text>
 </xsl:template>
 
-<xsl:template match="outptr|outbuf|allocfieldbuf" mode="HotSpotType">
+<xsl:template match="outptr|outbuf|allocfieldbuf" mode="HotSpotJavaType">
   <xsl:apply-templates select="child::*[position()=1]" mode="btsig"/>
   <xsl:text>*</xsl:text>
 </xsl:template>
 
-<xsl:template match="ptrtype" mode="HotSpotType">
+<xsl:template match="ptrtype" mode="HotSpotJavaType">
   <xsl:apply-templates select="child::*[position()=1]" mode="btsig"/>
 </xsl:template>
 
-<xsl:template match="inptr|inbuf|vmbuf" mode="HotSpotType">
+<xsl:template match="inptr|inbuf|vmbuf" mode="HotSpotJavaType">
   <xsl:text>const </xsl:text>
   <xsl:apply-templates select="child::*[position()=1]" mode="btsig"/>
   <xsl:text>*</xsl:text>
 </xsl:template>
 
-<xsl:template match="allocbuf|agentbuf" mode="HotSpotType">
+<xsl:template match="allocbuf|agentbuf" mode="HotSpotJavaType">
   <xsl:apply-templates select="child::*[position()=1]" mode="btsig"/>
   <xsl:text>**</xsl:text>
 </xsl:template>
 
-<xsl:template match="allocallocbuf" mode="HotSpotType">
+<xsl:template match="allocallocbuf" mode="HotSpotJavaType">
   <xsl:apply-templates select="child::*[position()=1]" mode="btsig"/>
   <xsl:text>***</xsl:text>
 </xsl:template>
--- a/src/share/vm/prims/nativeLookup.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/prims/nativeLookup.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -121,6 +121,9 @@
   void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
   void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
   void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
+#ifdef GRAAL
+  jobject JNICALL JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass);
+#endif
 }
 
 #define CC (char*)  /* cast a literal from (const char*) */
@@ -134,6 +137,10 @@
   { CC"Java_sun_misc_Unsafe_registerNatives",                      NULL, FN_PTR(JVM_RegisterUnsafeMethods)       },
   { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
   { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         }
+#ifdef GRAAL
+  ,
+  { CC"Java_com_oracle_graal_api_Graal_initializeRuntime",         NULL, FN_PTR(JVM_InitializeGraalRuntime)      }
+#endif
 };
 
 static address lookup_special_native(char* jni_name) {
--- a/src/share/vm/runtime/arguments.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/runtime/arguments.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -2130,6 +2130,10 @@
     // this declaration is checked for correctness by 'mx build' - only
     // modify its entries, not its name or shape
     const char* graal_projects[] = {
+        "com.oracle.graal.api",
+        "com.oracle.graal.api.meta",
+        "com.oracle.graal.api.code",
+        "com.oracle.graal.api.interpreter",
         "com.oracle.max.criutils",
         "com.oracle.graal.hotspot",
         "com.oracle.max.asm",
@@ -2143,6 +2147,7 @@
         "com.oracle.graal.graph",
         "com.oracle.graal.lir",
         "com.oracle.graal.lir.amd64",
+        "com.oracle.graal.bytecode",
         "com.oracle.graal.java"
     };
 
--- a/src/share/vm/runtime/frame.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/runtime/frame.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -740,8 +740,9 @@
     } else if (_cb->is_nmethod()) {
       methodOop m = ((nmethod *)_cb)->method();
       if (m != NULL) {
+        address code = _cb->code_begin();
         m->name_and_sig_as_C_string(buf, buflen);
-        st->print("J  %s", buf);
+        st->print("J  %s [" PTR_FORMAT "+%d]", buf, code, pc() - code);
       } else {
         st->print("J  " PTR_FORMAT, pc());
       }
--- a/src/share/vm/runtime/reflectionUtils.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/runtime/reflectionUtils.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -79,8 +79,8 @@
     _filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
   }
 #ifdef GRAAL
-  compute_offset(offset, SystemDictionary::HotSpotMethodResolved_klass(), "javaMirror", "Ljava/lang/Object;", false);
-  _filtered_fields->append(new FilteredField(SystemDictionary::HotSpotMethodResolved_klass(), offset));
+  compute_offset(offset, SystemDictionary::HotSpotResolvedJavaMethod_klass(), "javaMirror", "Ljava/lang/Object;", false);
+  _filtered_fields->append(new FilteredField(SystemDictionary::HotSpotResolvedJavaMethod_klass(), offset));
   compute_offset(offset, SystemDictionary::HotSpotMethodData_klass(), "hotspotMirror", "Ljava/lang/Object;", false);
   _filtered_fields->append(new FilteredField(SystemDictionary::HotSpotMethodData_klass(), offset));
 #endif
--- a/src/share/vm/runtime/vframeArray.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/runtime/vframeArray.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -252,7 +252,9 @@
       case Deoptimization::Unpack_uncommon_trap:
       case Deoptimization::Unpack_reexecute:
         // redo last byte code
+#ifdef GRAAL
         assert(should_reexecute(), "");
+#endif
         pc  = Interpreter::deopt_entry(vtos, 0);
         use_next_mdp = false;
         break;
--- a/src/share/vm/runtime/vmStructs.cpp	Wed Jun 27 11:48:26 2012 +0200
+++ b/src/share/vm/runtime/vmStructs.cpp	Wed Jun 27 17:35:32 2012 +0200
@@ -230,7 +230,7 @@
 // type name, indicating an "opaque" type to the serviceability agent.
 
 // NOTE: there is an interdependency between this file and
-// HotSpotTypeDataBase.java, which parses the type strings.
+// HotSpotJavaTypeDataBase.java, which parses the type strings.
 
 #ifndef REG_COUNT
   #define REG_COUNT 0
--- a/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Wed Jun 27 11:48:26 2012 +0200
+++ b/visualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Wed Jun 27 17:35:32 2012 +0200
@@ -1,11 +1,12 @@
 colorize("name", ".*", white);
-colorize("name", "Begin|EndNode|LoopBegin|LoopEnd|Return", orange);
-colorize("name", "Phi.*", magenta);
+colorize("name", "Begin|EndNode|LoopBegin|LoopEnd|LoopExit|Return", orange);
+colorize("name", "Phi.*|ValueProxy", magenta);
 colorize("name", "FrameState@.*", new java.awt.Color(0.5, 0.8, 1.0));
 colorize("name", "If|Merge", pink);
 colorize("name", "const.*", new java.awt.Color(0.7, 0.7, 0.7));
 colorize("name", "Local", new java.awt.Color(0.85, 0.85, 0.85));
 colorize("name", "\\+|-|\\*|/|&|\\||<<|>>|>>>", cyan);
 colorize("name", "Comp .*", yellow);
+colorize("name", "Virtual.*", green);
 
 colorize("notInOwnBlock", "true", red);
\ No newline at end of file