changeset 9983:13384d19fec0

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Tue, 11 Jun 2013 00:00:40 +0200
parents 06e176eff527 (current diff) b8b4d7f3e4aa (diff)
children f3330a4487eb fb2c8034e9b9 d9a331e2fd61
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InlineableElement.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java src/share/vm/graal/graalCodeInstaller.cpp
diffstat 104 files changed, 2705 insertions(+), 1501 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java	Tue Jun 11 00:00:40 2013 +0200
@@ -32,28 +32,39 @@
      * it's highly likely nothing will change the likelihood of the deoptimization happening again.
      * For example, a compiled array allocation where the size is negative.
      */
-    None,
+    None(false),
 
     /**
      * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is
      * triggered too often.
      */
-    RecompileIfTooManyDeopts,
+    RecompileIfTooManyDeopts(true),
 
     /**
      * Invalidate the machine code and reset the profiling information.
      */
-    InvalidateReprofile,
+    InvalidateReprofile(true),
 
     /**
      * Invalidate the machine code and immediately schedule a recompilation. This is typically used
      * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not
      * required to determine that the deoptimization will not re-occur.
      */
-    InvalidateRecompile,
+    InvalidateRecompile(true),
 
     /**
      * Invalidate the machine code and stop compiling the outermost method of this compilation.
      */
-    InvalidateStopCompiling;
+    InvalidateStopCompiling(true);
+
+    private final boolean invalidatesCompilation;
+
+    private DeoptimizationAction(boolean invalidatesCompilation) {
+        this.invalidatesCompilation = invalidatesCompilation;
+    }
+
+    public boolean doesInvalidateCompilation() {
+        return invalidatesCompilation;
+    }
+
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractJavaProfile.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AbstractJavaProfile.java	Tue Jun 11 00:00:40 2013 +0200
@@ -25,10 +25,14 @@
 import java.io.*;
 
 /**
- * This profile object represents a certain set of profiling information 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.
+ * This object holds probability information for a set of items that were profiled 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.
+ * 
+ * @param <T> a subclass of AbstractProfiledItem
+ * @param <U> the class of the items that are profiled at the specific BCI and for which
+ *            probabilities are stored. E.g., a ResolvedJavaType or a ResolvedJavaMethod.
  */
 public abstract class AbstractJavaProfile<T extends AbstractProfiledItem<U>, U> implements Serializable {
 
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Tue Jun 11 00:00:40 2013 +0200
@@ -87,6 +87,11 @@
     }
 
     @Override
+    public boolean isMature() {
+        return false;
+    }
+
+    @Override
     public String toString() {
         return "BaseProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Tue Jun 11 00:00:40 2013 +0200
@@ -112,4 +112,12 @@
      */
     int getDeoptimizationCount(DeoptimizationReason reason);
 
+    /**
+     * Returns true if the profiling information can be assumed as sufficiently accurate.
+     * 
+     * @return true if the profiling information was recorded often enough mature enough, false
+     *         otherwise.
+     */
+    boolean isMature();
+
 }
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue Jun 11 00:00:40 2013 +0200
@@ -90,6 +90,20 @@
         }
     }
 
+    public static class Fmt2e {
+        public Fmt2e(SPARCAssembler asm, int op, int c4lo, int cc2, int rs1, int d10lo, int regOrImmediate) {
+            assert op == 0;
+            assert (cc2 & 0xFFFFFFFE) == 0;
+            assert c4lo >= 0 && rs1 < 0x10;
+            assert rs1 >= 0 && rs1 < 0x20;
+            assert (regOrImmediate & 0x1F) < 0x20;
+            assert (regOrImmediate & 0xFFFFC000) == 0;
+            assert (d10lo & 0xFFFFFC00) == 0;
+
+            asm.emitInt(op << 30 | 1 << 28 | 3 << 22 | cc2 << 21 | (d10lo >> 8) << 19 | rs1 << 14 | (d10lo & 0xff) << 5 | regOrImmediate);
+        }
+    }
+
     public static class Fmt3a {
         public Fmt3a(SPARCAssembler masm, int op, int rd, int op3, int rs1, int rs2) {
             assert  op == 2 || op == 3;
@@ -158,6 +172,18 @@
         }
     }
 
+    public static class Fmt3n {
+        public Fmt3n(SPARCAssembler masm, int op, int op3, int opf, int rs2, int rd) {
+            assert  op == 2 || op == 3;
+            assert op3 >= 0 && op3 < 0x40;
+            assert opf >= 0 && opf < 0x200;
+            assert rs2 >= 0 && rs2 < 0x20;
+            assert  rd >= 0 &&  rd < 0x20;
+
+            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2);
+        }
+    }
+
     public static class Fmt3p {
         public Fmt3p(SPARCAssembler masm, int op, int op3, int opf, int rs1, int rs2, int rd) {
             assert  op == 2 || op == 3;
@@ -171,18 +197,6 @@
         }
     }
 
-    public static class Fmt3n {
-        public Fmt3n(SPARCAssembler masm, int op, int op3, int opf, int rs2, int rd) {
-            assert  op == 2 || op == 3;
-            assert op3 >= 0 && op3 < 0x40;
-            assert opf >= 0 && opf < 0x200;
-            assert rs2 >= 0 && rs2 < 0x20;
-            assert  rd >= 0 &&  rd < 0x20;
-
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2);
-        }
-    }
-
     public static class Fmt3q {
         public Fmt3q(SPARCAssembler masm, int op, int op3, int rs1, int rd) {
             assert  op == 2 || op == 3;
@@ -239,6 +253,20 @@
         }
     }
 
+    public static class Fmt5a {
+        public Fmt5a(SPARCAssembler masm, int op, int op3, int op5, int rs1, int rs2, int rs3, int rd) {
+            assert   op == 2;
+            assert  op3 >= 0 &&  op3 < 0x40;
+            assert  op5 >= 0 &&  op5 < 0x10;
+            assert  rs1 >= 0 &&  rs1 < 0x20;
+            assert  rs2 >= 0 &&  rs2 < 0x20;
+            assert  rs3 >= 0 &&  rs3 < 0x20;
+            assert  rd  >= 0 &&  rd  < 0x20;
+
+            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rs3 << 9 | op5 << 5 | rs2);
+        }
+    }
+
     public static final int ImmedTrue = 0x00002000;
 
     public enum Ops {
@@ -389,6 +417,27 @@
         }
     }
 
+    public enum Op5s {
+        Fmadds(0x1),
+        Fmaddd(0x2),
+        Fmsubs(0x5),
+        Fmsubd(0x6),
+        Fnmsubs(0x9),
+        Fnmsubd(0xA),
+        Fnmadds(0xD),
+        Fnmaddd(0xE);
+
+        private final int value;
+
+        private Op5s(int value) {
+            this.value = value;
+        }
+
+        public int getValue() {
+            return value;
+        }
+    }
+
     public enum Opfs {
         Fmovs(0x01, "fmovs"),
         Fmovd(0x02, "fmovd"),
@@ -399,6 +448,62 @@
         Fabss(0x09, "fabss"),
         Fabsd(0x0A, "fabsd"),
         Fabsq(0x0B, "fabsq"),
+
+        // start VIS1
+        Edge8cc(0x0, "edge8cc"),
+        Edge8n(0x1, "edge8n"),
+        Edge8lcc(0x2, "edge8lcc"),
+        Edge8ln(0x3, "edge8ln"),
+        Edge16cc(0x4, "edge16cc"),
+        Edge16n(0x5, "edge16n"),
+        Edge16lcc(0x6, "edge16lcc"),
+        Edge16ln(0x7, "edge16ln"),
+        Edge32cc(0x8, "edge32cc"),
+        Edge32n(0x9, "edge32n"),
+        Edge32lcc(0xA, "edge32lcc"),
+        Edge32ln(0xB, "edge32ln"),
+        Array8(0x10, "array8"),
+        Array16(0x12, "array16"),
+        Array32(0x14, "array32"),
+        AlignAddress(0x18, "alignaddress"),
+        AlignAddressLittle(0x1A, "alignaddress_little"),
+        Fmul8x16(0x31, "fmul8x16"),
+        Fmul8x16au(0x33, "fmul8x16au"),
+        Fmul8x16al(0x35, "fmul8x16al"),
+        Fmul8sux16(0x36, "fmul8sux16"),
+        Fmul8ulx16(0x37, "fmul8ulx16"),
+        Fmuld8sux16(0x38, "fmuld8sux16"),
+        Fmuld8ulx16(0x39, "fmuld8ulx16"),
+        Faligndatag(0x48, "faligndata"),
+        Fnhadds(0x71, "fnhadds"),
+        Fnhaddd(0x72, "fnhaddd"),
+        // end VIS1
+
+        // start VIS2
+        Bmask(0x19, "bmask"),
+        Bshuffle(0x4c, "bshuffle"),
+        // end VIS2 only
+
+        // start VIS3
+        Addxc(0x11, "addxc"),
+        Addxccc(0x13, "addxccc"),
+        Cmask8(0x1B, "cmask8"),
+        Cmask16(0x1D, "cmask16"),
+        Cmask32(0x1F, "cmask32"),
+        Fmean16(0x40, "fmean16"),
+        Fnadds(0x51, "fnadds"),
+        Fnaddd(0x52, "fnaddd"),
+        // end VIS3
+
+        // start CAMMELLIA
+        CammelliaFl(0x13C, "cammelia_fl"),
+        CammelliaFli(0x13D, "cammellia_fli"),
+        // end CAMMELLIA
+
+        // start CRYPTO
+        Crc32c(0x147, "crc32c"),
+        // end CRYPTO
+
         Fadds(0x41, "fadds"),
         Faddd(0x42, "faddd"),
         Faddq(0x43, "faddq"),
@@ -663,6 +768,38 @@
         }
     }
 
+    public static class Addxc extends Fmt3p {
+        public Addxc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS3 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Addxc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Addxccc extends Fmt3p {
+        public Addxccc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS3 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Addxccc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Alignaddr extends Fmt3p {
+        public Alignaddr(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.AlignAddress.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Alignaddrl extends Fmt3p {
+        public Alignaddrl(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.AlignAddressLittle.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
     public static class And extends Fmt3b {
         public And(SPARCAssembler masm, Register src1, int simm13, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.And.getValue(), src1.encoding(), simm13, dst.encoding());
@@ -699,6 +836,38 @@
         }
     }
 
+    public static class Array8 extends Fmt3p {
+        public Array8(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Array8.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Array16 extends Fmt3p {
+        public Array16(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Array16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Array32 extends Fmt3p {
+        public Array32(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Array32.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Bmask extends Fmt3p {
+        public Bmask(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS2 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Bmask.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
     public static class Bpa extends Fmt2c {
         public Bpa(SPARCAssembler masm, int simmm19) {
             super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(),
@@ -891,11 +1060,456 @@
         }
     }
 
+    public static class Bshuffle extends Fmt3p {
+        public Bshuffle(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS2 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Bshuffle.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class CammelliaFl extends Fmt3p {
+        public CammelliaFl(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* CAMELLIA only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.CammelliaFl.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class CammelliaFli extends Fmt3p {
+        public CammelliaFli(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* CAMELLIA only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.CammelliaFli.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
     private static int patchUnbound(SPARCAssembler masm, Label label) {
         label.addPatchAt(masm.codeBuffer.position());
         return 0;
     }
 
+    public static class Cmask8 extends Fmt3n {
+        public Cmask8(SPARCAssembler asm, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask8.getValue(),
+                            src2.encoding(), 0);
+        }
+    }
+
+    public static class Cmask16 extends Fmt3n {
+        public Cmask16(SPARCAssembler asm, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask16.getValue(),
+                            src2.encoding(), 0);
+        }
+    }
+
+    public static class Cmask32 extends Fmt3n {
+        public Cmask32(SPARCAssembler asm, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask32.getValue(),
+                            src2.encoding(), 0);
+        }
+    }
+
+    public static class Crc32c extends Fmt3p {
+        public Crc32c(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* CRYPTO only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Crc32c.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Cwbcc extends Fmt2e {
+        public Cwbcc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbcc(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbcs extends Fmt2e {
+        public Cwbcs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbcs(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbe extends Fmt2e {
+        public Cwbe(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbe(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbg extends Fmt2e {
+        public Cwbg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbg(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbge extends Fmt2e {
+        public Cwbge(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbge(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbgu extends Fmt2e {
+        public Cwbgu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbgu(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbl extends Fmt2e {
+        public Cwbl(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbl(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwble extends Fmt2e {
+        public Cwble(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwble(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbleu extends Fmt2e {
+        public Cwbleu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbleu(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbne extends Fmt2e {
+        public Cwbne(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbne(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbneg extends Fmt2e {
+        public Cwbneg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbneg(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbpos extends Fmt2e {
+        public Cwbpos(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbpos(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbvc extends Fmt2e {
+        public Cwbvc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbvc(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cwbvs extends Fmt2e {
+        public Cwbvs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 0,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cwbvs(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 0,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbcc extends Fmt2e {
+        public Cxbcc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbcc(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbcs extends Fmt2e {
+        public Cxbcs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbcs(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbe extends Fmt2e {
+        public Cxbe(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbe(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbg extends Fmt2e {
+        public Cxbg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbg(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbge extends Fmt2e {
+        public Cxbge(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbge(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbgu extends Fmt2e {
+        public Cxbgu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbgu(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbl extends Fmt2e {
+        public Cxbl(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbl(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxble extends Fmt2e {
+        public Cxble(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxble(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbleu extends Fmt2e {
+        public Cxbleu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbleu(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbne extends Fmt2e {
+        public Cxbne(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbne(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbneg extends Fmt2e {
+        public Cxbneg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbneg(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbpos extends Fmt2e {
+        public Cxbpos(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbpos(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbvc extends Fmt2e {
+        public Cxbvc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbvc(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Cxbvs extends Fmt2e {
+        public Cxbvs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 1,
+                            src1.encoding(), simm10, src2.encoding());
+        }
+        public Cxbvs(SPARCAssembler asm, Register src1, int immed5, int simm10) {
+            super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 1,
+                            src1.encoding(), simm10, immed5 | ImmedTrue);
+        }
+    }
+
+    public static class Edge8cc extends Fmt3p {
+        public Edge8cc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8cc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge8n extends Fmt3p {
+        public Edge8n(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8n.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge8lcc extends Fmt3p {
+        public Edge8lcc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8lcc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge8ln extends Fmt3p {
+        public Edge8ln(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8ln.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge16cc extends Fmt3p {
+        public Edge16cc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16cc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge16n extends Fmt3p {
+        public Edge16n(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16n.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge16lcc extends Fmt3p {
+        public Edge16lcc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16lcc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge16ln extends Fmt3p {
+        public Edge16ln(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16ln.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge32cc extends Fmt3p {
+        public Edge32cc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32cc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge32n extends Fmt3p {
+        public Edge32n(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32n.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge32lcc extends Fmt3p {
+        public Edge32lcc(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32lcc.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Edge32ln extends Fmt3p {
+        public Edge32ln(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32ln.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
     public static class Fadds extends Fmt3p {
         public Fadds(SPARCAssembler masm, Register src1, Register src2, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fadds.getValue(),
@@ -917,6 +1531,13 @@
         }
     }
 
+    public static class Faligndata extends Fmt3p {
+        public Faligndata(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Faligndatag.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
     public static class Fdivs extends Fmt3p {
         public Fdivs(SPARCAssembler masm, Register src1, Register src2, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivs.getValue(),
@@ -931,6 +1552,86 @@
         }
     }
 
+    public static class Fmadds extends Fmt5a {
+        public Fmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmadds.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmaddd extends Fmt5a {
+        public Fmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmaddd.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmean16 extends Fmt3p {
+        public Fmean16(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS3 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmean16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmsubs extends Fmt5a {
+        public Fmsubs(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubs.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmsubd extends Fmt5a {
+        public Fmsubd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubd.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnadds extends Fmt3p {
+        public Fnadds(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS3 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnadds.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnaddd extends Fmt3p {
+        public Fnaddd(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS3 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnaddd.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnmadds extends Fmt5a {
+        public Fnmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmadds.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnmaddd extends Fmt5a {
+        public Fnmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmaddd.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnmsubs extends Fmt5a {
+        public Fnmsubs(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubs.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fnmsubd extends Fmt5a {
+        public Fnmsubd(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) {
+            super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubd.getValue(),
+                            src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding());
+        }
+    }
+
     public static class Fmuls extends Fmt3p {
         public Fmuls(SPARCAssembler masm, Register src1, Register src2, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuls.getValue(),
@@ -945,6 +1646,62 @@
         }
     }
 
+    public static class Fmul8x16 extends Fmt3p {
+        public Fmul8x16(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8x16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmul8x16au extends Fmt3p {
+        public Fmul8x16au(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8x16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmul8x16al extends Fmt3p {
+        public Fmul8x16al(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8x16al.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmul8sux16 extends Fmt3p {
+        public Fmul8sux16(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8sux16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmul8ulx16 extends Fmt3p {
+        public Fmul8ulx16(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8ulx16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmuld8sux16 extends Fmt3p {
+        public Fmuld8sux16(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmuld8sux16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
+    public static class Fmuld8ulx16 extends Fmt3p {
+        public Fmuld8ulx16(SPARCAssembler asm, Register src1, Register src2, Register dst) {
+            /* VIS1 only */
+            super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmuld8ulx16.getValue(),
+                            src1.encoding(), src2.encoding(), dst.encoding());
+        }
+    }
+
     public static class Fnegs extends Fmt3n {
         public Fnegs(SPARCAssembler masm, Register src2, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegs.getValue(),
@@ -1463,6 +2220,127 @@
         }
     }
 
+    public static class Tcc extends Fmt4a {
+        public Tcc(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.CarryClear.getValue());
+        }
+        public Tcc(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.CarryClear.getValue());
+        }
+    }
+
+    public static class Tcs extends Fmt4a {
+        public Tcs(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.CarrySet.getValue());
+        }
+        public Tcs(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.CarrySet.getValue());
+        }
+    }
+
+    public static class Te extends Fmt4a {
+        public Te(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.Equal.getValue());
+        }
+        public Te(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.Equal.getValue());
+        }
+    }
+
+    public static class Tg extends Fmt4a {
+        public Tg(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.Greater.getValue());
+        }
+        public Tg(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.Greater.getValue());
+        }
+    }
+
+    public static class Tge extends Fmt4a {
+        public Tge(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.GreaterEqual.getValue());
+        }
+        public Tge(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.GreaterEqual.getValue());
+        }
+    }
+
+    public static class Tle extends Fmt4a {
+        public Tle(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.LessEqual.getValue());
+        }
+        public Tle(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.LessEqual.getValue());
+        }
+    }
+
+    public static class Tleu extends Fmt4a {
+        public Tleu(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.LessEqualUnsigned.getValue());
+        }
+        public Tleu(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.LessEqualUnsigned.getValue());
+        }
+    }
+
+    public static class Tn extends Fmt4a {
+        public Tn(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.Never.getValue());
+        }
+        public Tn(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.Never.getValue());
+        }
+    }
+
+    public static class Tne extends Fmt4a {
+        public Tne(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.NotEqual.getValue());
+        }
+        public Tne(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.NotEqual.getValue());
+        }
+    }
+
+    public static class Tneg extends Fmt4a {
+        public Tneg(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.Negative.getValue());
+        }
+        public Tneg(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.Negative.getValue());
+        }
+    }
+
+    public static class Tpos extends Fmt4a {
+        public Tpos(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.Positive.getValue());
+        }
+        public Tpos(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.Positive.getValue());
+        }
+    }
+
     public static class Tsubcc extends Fmt3b {
         public Tsubcc(SPARCAssembler masm, Register src1, int simm13, Register dst) {
             super(masm, Ops.ArithOp.getValue(), Op3s.Tsubcc.getValue(), src1.encoding(), simm13, dst.encoding());
@@ -1484,6 +2362,28 @@
         }
     }
 
+    public static class Tvc extends Fmt4a {
+        public Tvc(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.OverflowClear.getValue());
+        }
+        public Tvc(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.OverflowClear.getValue());
+        }
+    }
+
+    public static class Tvs extends Fmt4a {
+        public Tvs(SPARCAssembler asm, CC cc, Register src1, int trap) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), trap, ConditionFlag.OverflowSet.getValue());
+        }
+        public Tvs(SPARCAssembler asm, CC cc, Register src1, Register src2) {
+            super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(),
+                  src1.encoding(), src2.encoding(), ConditionFlag.OverflowSet.getValue());
+        }
+    }
+
     @Deprecated
     public static class Udiv extends Fmt3b {
         @Deprecated
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Tue Jun 11 00:00:40 2013 +0200
@@ -212,6 +212,19 @@
     }
 
     @SuppressWarnings("unused")
+    public static class Mov {
+
+        public Mov(SPARCAssembler asm, Register src1, Register dst) {
+            assert src1.encoding() != dst.encoding();
+            new Or(asm, SPARC.g0, src1, dst);
+        }
+
+        public Mov(SPARCAssembler asm, int simm13, Register dst) {
+            new Or(asm, SPARC.g0, simm13, dst);
+        }
+    }
+
+    @SuppressWarnings("unused")
     public static class Not {
 
         public Not(SPARCAssembler asm, Register src1, Register dst) {
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -39,6 +39,7 @@
 import com.oracle.graal.phases.OptimisticOptimizations;
 import com.oracle.graal.phases.PhasePlan;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
+import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.ptx.PTX;
 
 public abstract class PTXTestBase extends GraalCompilerTest {
@@ -57,8 +58,14 @@
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PTXPhase());
         new PTXPhase().apply(graph);
         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
+        /*
+         * Use Suites.createDefaultSuites() instead of GraalCompilerTest.suites. The
+         * GraalCompilerTest.suites variable contains the Suites for the HotSpotRuntime. This code
+         * will not run on hotspot, so it should use the plain Graal default suites, without hotspot
+         * specific phases.
+         */
         CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, graalRuntime().getReplacements(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE,
-                        new SpeculationLog());
+                        new SpeculationLog(), Suites.createDefaultSuites());
         return result;
     }
 
--- a/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCTestBase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCTestBase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -55,9 +55,8 @@
         GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-        CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, graalRuntime().getReplacements(),
-                                                              sparcBackend, target, null, phasePlan, OptimisticOptimizations.NONE,
-                                                              new SpeculationLog());
+        CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, graalRuntime().getReplacements(), sparcBackend, target, null, phasePlan,
+                        OptimisticOptimizations.NONE, new SpeculationLog(), suites);
         return result;
     }
 
@@ -66,4 +65,3 @@
     }
 
 }
-
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Jun 11 00:00:40 2013 +0200
@@ -119,6 +119,13 @@
 
     @Override
     public void emitMove(AllocatableValue dst, Value src) {
+        // XXX SPARCAddress loads
+        /*
+         * if (src instanceof SPARCAddressValue) { public LoadOp(Kind kind, AllocatableValue result,
+         * SPARCAddressValue address, LIRFrameState state) {
+         * 
+         * return new LoadOp(result.getKind(), result, (SPARCAddressValue) src); }
+         */
         if (isRegister(src) || isStackSlot(dst)) {
             append(new MoveFromRegOp(dst, src));
         } else {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -309,7 +309,7 @@
         Assumptions assumptions = new Assumptions(false);
         HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
         new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
-        new PartialEscapeAnalysisPhase(false, false, new CanonicalizerPhase(true)).apply(graph, context);
+        new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
         new CullFrameStatesPhase().apply(graph);
     }
 
@@ -333,7 +333,7 @@
                 }
                 new DeadCodeEliminationPhase().apply(graph);
                 canonicalizer.apply(graph, context);
-                new PartialEscapeAnalysisPhase(false, false, canonicalizer).apply(graph, context);
+                new PartialEscapePhase(false, canonicalizer).apply(graph, context);
 
                 new CullFrameStatesPhase().apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -48,9 +48,9 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.test.*;
-import com.oracle.graal.hotspot.phases.WriteBarrierAdditionPhase;
 
 /**
  * Base class for Graal compiler unit tests.
@@ -76,11 +76,13 @@
     protected final GraalCodeCacheProvider runtime;
     protected final Replacements replacements;
     protected final Backend backend;
+    protected final Suites suites;
 
     public GraalCompilerTest() {
         this.replacements = Graal.getRequiredCapability(Replacements.class);
         this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
         this.backend = Graal.getRequiredCapability(Backend.class);
+        this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
     }
 
     @BeforeClass
@@ -430,11 +432,10 @@
                 final StructuredGraph graphCopy = graph.copy();
                 GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
                 phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-                phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase());
                 editPhasePlan(method, graph, phasePlan);
                 CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
                 final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
-                                new SpeculationLog());
+                                new SpeculationLog(), suites);
                 if (printCompilation) {
                     TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
                 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -60,7 +60,7 @@
         final StructuredGraph graph = parse(method);
         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
         final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(),
-                        OptimisticOptimizations.ALL, new SpeculationLog());
+                        OptimisticOptimizations.ALL, new SpeculationLog(), suites);
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
             if (sp instanceof Call) {
@@ -82,7 +82,7 @@
         assertTrue(graphLineSPs > 0);
         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
         final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(true),
-                        OptimisticOptimizations.ALL, new SpeculationLog());
+                        OptimisticOptimizations.ALL, new SpeculationLog(), suites);
         int lineSPs = 0;
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -128,7 +128,11 @@
     }
 
     public static Serializable checkCastSnippet(Object obj) {
-        return (Serializable) obj;
+        try {
+            return (Serializable) obj;
+        } catch (ClassCastException e) {
+            return null;
+        }
     }
 
     @Test
@@ -250,19 +254,30 @@
 
     @Test
     public void testNullSeen() {
-        ProfilingInfo info = profile("instanceOfSnippet", 1);
+        testNullSeen("instanceOfSnippet");
+        testNullSeen("checkCastSnippet");
+    }
+
+    private void testNullSeen(String snippet) {
+        ProfilingInfo info = profile(snippet, 1);
         Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
 
-        continueProfiling("instanceOfSnippet", "ABC");
+        continueProfiling(snippet, "ABC");
         Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
 
-        continueProfiling("instanceOfSnippet", (Object) null);
+        continueProfiling(snippet, new Object());
+        Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
+
+        continueProfiling(snippet, (Object) null);
         Assert.assertEquals(TriState.TRUE, info.getNullSeen(1));
 
-        continueProfiling("instanceOfSnippet", 0.0);
+        continueProfiling(snippet, 0.0);
         Assert.assertEquals(TriState.TRUE, info.getNullSeen(1));
 
-        resetProfile("instanceOfSnippet");
+        continueProfiling(snippet, new Object());
+        Assert.assertEquals(TriState.TRUE, info.getNullSeen(1));
+
+        resetProfile(snippet);
         Assert.assertEquals(TriState.FALSE, info.getNullSeen(1));
     }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -119,7 +119,7 @@
 
             @Override
             public LIR call() {
-                return GraalCompiler.emitHIR(runtime, backend.target, graph, replacements, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog());
+                return GraalCompiler.emitHIR(runtime, backend.target, graph, replacements, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites);
             }
         });
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -222,7 +222,7 @@
                 HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
                 new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
-                new PartialEscapeAnalysisPhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context);
+                new PartialEscapePhase(iterativeEscapeAnalysis, new CanonicalizerPhase(true)).apply(graph, context);
                 Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count());
                 ReturnNode returnNode = graph.getNodes(ReturnNode.class).first();
                 if (expectedConstantResult != null) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
-import static com.oracle.graal.phases.GraalOptions.*;
 import static org.junit.Assert.*;
 
 import java.util.concurrent.*;
@@ -81,19 +80,6 @@
         assertEquals(graph.getLocal(0), result);
     }
 
-    @SuppressWarnings("all")
-    public static int testSimpleReadSnippet(TestObject a, int b) throws Exception {
-        a.callable = new TestInt(b, 9);
-        return a.callable.call();
-    }
-
-    @Test
-    public void testSimpleRead() {
-        ValueNode result = getReturn("testSimpleReadSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
-        assertEquals(graph.getLocal(1), result);
-    }
-
     final ReturnNode getReturn(String snippet) {
         processMethod(snippet);
         assertEquals(1, graph.getNodes(ReturnNode.class).count());
@@ -102,8 +88,7 @@
 
     private void processMethod(final String snippet) {
         graph = parse(snippet);
-        OptEarlyReadElimination.setValue(true);
         HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements);
-        new IterativeInliningPhase(replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, false, new CanonicalizerPhase(true)).apply(graph, context);
+        new IterativeInliningPhase(null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, new CanonicalizerPhase(true)).apply(graph, context);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.compiler.test.ea;
-
-import static org.junit.Assert.*;
-
-import java.util.concurrent.*;
-
-import org.junit.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.virtual.phases.ea.*;
-
-public class PEAReadEliminationTest extends GraalCompilerTest {
-
-    private StructuredGraph graph;
-
-    public static Object staticField;
-
-    public static class TestObject implements Callable<Integer> {
-
-        public int x;
-        public int y;
-
-        public TestObject(int x, int y) {
-            this.x = x;
-            this.y = y;
-        }
-
-        @Override
-        public Integer call() throws Exception {
-            return x;
-        }
-    }
-
-    public static class TestObject2 {
-
-        public Object x;
-        public Object y;
-
-        public TestObject2(Object x, Object y) {
-            this.x = x;
-            this.y = y;
-        }
-    }
-
-    @SuppressWarnings("all")
-    public static int testSimpleSnippet(TestObject a) {
-        a.x = 2;
-        staticField = a;
-        return a.x;
-    }
-
-    @Test
-    public void testSimple() {
-        ValueNode result = getReturn("testSimpleSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
-        assertTrue(result.isConstant());
-        assertEquals(2, result.asConstant().asInt());
-    }
-
-    @SuppressWarnings("all")
-    public static int testSimpleConflictSnippet(TestObject a, TestObject b) {
-        a.x = 2;
-        b.x = 3;
-        staticField = a;
-        return a.x;
-    }
-
-    @Test
-    public void testSimpleConflict() {
-        ValueNode result = getReturn("testSimpleConflictSnippet").result();
-        assertFalse(result.isConstant());
-        assertTrue(result instanceof LoadFieldNode);
-    }
-
-    @SuppressWarnings("all")
-    public static int testParamSnippet(TestObject a, int b) {
-        a.x = b;
-        return a.x;
-    }
-
-    @Test
-    public void testParam() {
-        ValueNode result = getReturn("testParamSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
-        assertEquals(graph.getLocal(1), result);
-    }
-
-    @SuppressWarnings("all")
-    public static int testMaterializedSnippet(int a) {
-        TestObject obj = new TestObject(a, 0);
-        staticField = obj;
-        return obj.x;
-    }
-
-    @Test
-    public void testMaterialized() {
-        ValueNode result = getReturn("testMaterializedSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
-        assertEquals(graph.getLocal(0), result);
-    }
-
-    @SuppressWarnings("all")
-    public static int testSimpleLoopSnippet(TestObject obj, int a, int b) {
-        obj.x = a;
-        for (int i = 0; i < 10; i++) {
-            staticField = obj;
-        }
-        return obj.x;
-    }
-
-    @Test
-    public void testSimpleLoop() {
-        ValueNode result = getReturn("testSimpleLoopSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
-        assertEquals(graph.getLocal(1), result);
-    }
-
-    @SuppressWarnings("all")
-    public static int testBadLoopSnippet(TestObject obj, TestObject obj2, int a, int b) {
-        obj.x = a;
-        for (int i = 0; i < 10; i++) {
-            staticField = obj;
-            obj2.x = 10;
-            obj.x = 0;
-        }
-        return obj.x;
-    }
-
-    @Test
-    public void testBadLoop() {
-        ValueNode result = getReturn("testBadLoopSnippet").result();
-        assertEquals(0, graph.getNodes(LoadFieldNode.class).count());
-        assertTrue(result instanceof ProxyNode);
-        assertTrue(((ProxyNode) result).value() instanceof PhiNode);
-    }
-
-    @SuppressWarnings("all")
-    public static int testBadLoop2Snippet(TestObject obj, TestObject obj2, int a, int b) {
-        obj.x = a;
-        for (int i = 0; i < 10; i++) {
-            obj.x = 0;
-            obj2.x = 10;
-        }
-        return obj.x;
-    }
-
-    @Test
-    public void testBadLoop2() {
-        ValueNode result = getReturn("testBadLoop2Snippet").result();
-        assertEquals(1, graph.getNodes(LoadFieldNode.class).count());
-        assertTrue(result instanceof LoadFieldNode);
-    }
-
-    @SuppressWarnings("all")
-    public static int testPhiSnippet(TestObject a, int b) {
-        if (b < 0) {
-            a.x = 1;
-        } else {
-            a.x = 2;
-        }
-        return a.x;
-    }
-
-    @Test
-    public void testPhi() {
-        ValueNode result = getReturn("testPhiSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
-        assertTrue(result instanceof PhiNode);
-        PhiNode phi = (PhiNode) result;
-        assertTrue(phi.valueAt(0).isConstant());
-        assertTrue(phi.valueAt(1).isConstant());
-        assertEquals(1, phi.valueAt(0).asConstant().asInt());
-        assertEquals(2, phi.valueAt(1).asConstant().asInt());
-    }
-
-    @SuppressWarnings("all")
-    public static void testSimpleStoreSnippet(TestObject a, int b) {
-        a.x = b;
-        a.x = b;
-    }
-
-    @Test
-    public void testSimpleStore() {
-        processMethod("testSimpleStoreSnippet");
-        assertEquals(1, graph.getNodes().filter(StoreFieldNode.class).count());
-    }
-
-    final ReturnNode getReturn(String snippet) {
-        processMethod(snippet);
-        assertEquals(1, graph.getNodes(ReturnNode.class).count());
-        return graph.getNodes(ReturnNode.class).first();
-    }
-
-    private void processMethod(final String snippet) {
-        graph = parse(snippet);
-        Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
-        new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
-        new PartialEscapeAnalysisPhase(false, true, new CanonicalizerPhase(true)).apply(graph, context);
-    }
-}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -166,7 +166,7 @@
                 new DeadCodeEliminationPhase().apply(graph);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
                 canonicalizer.apply(graph, context);
-                new PartialEscapeAnalysisPhase(false, false, canonicalizer).apply(graph, context);
+                new PartialEscapePhase(false, canonicalizer).apply(graph, context);
 
                 new CullFrameStatesPhase().apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Jun 11 00:00:40 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.options.*;
@@ -74,7 +75,7 @@
      */
     public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final GraalCodeCacheProvider runtime,
                     final Replacements replacements, final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts,
-                    final SpeculationLog speculationLog) {
+                    final SpeculationLog speculationLog, final Suites suites) {
         final CompilationResult compilationResult = new CompilationResult();
         Debug.scope("GraalCompiler", new Object[]{graph, runtime}, new Runnable() {
 
@@ -83,7 +84,7 @@
                 final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() {
 
                     public LIR call() {
-                        return emitHIR(runtime, target, graph, replacements, assumptions, cache, plan, optimisticOpts, speculationLog);
+                        return emitHIR(runtime, target, graph, replacements, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
                     }
                 });
                 final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable<LIRGenerator>() {
@@ -123,7 +124,7 @@
      * @param target
      */
     public static LIR emitHIR(GraalCodeCacheProvider runtime, TargetDescription target, final StructuredGraph graph, Replacements replacements, Assumptions assumptions, GraphCache cache,
-                    PhasePlan plan, OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog) {
+                    PhasePlan plan, OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) {
 
         if (speculationLog != null) {
             speculationLog.snapshot();
@@ -149,7 +150,7 @@
 
         if (Inline.getValue() && !plan.isPhaseDisabled(InliningPhase.class)) {
             if (IterativeInlining.getValue()) {
-                new IterativeInliningPhase(replacements, cache, plan, optimisticOpts, OptEarlyReadElimination.getValue(), canonicalizer).apply(graph, highTierContext);
+                new IterativeInliningPhase(cache, plan, optimisticOpts, canonicalizer).apply(graph, highTierContext);
             } else {
                 new InliningPhase(runtime, null, replacements, assumptions, cache, plan, optimisticOpts).apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
@@ -163,16 +164,19 @@
         TypeProfileProxyNode.cleanFromGraph(graph);
 
         plan.runPhases(PhasePosition.HIGH_LEVEL, graph);
-        Suites.DEFAULT.getHighTier().apply(graph, highTierContext);
+        suites.getHighTier().apply(graph, highTierContext);
 
         MidTierContext midTierContext = new MidTierContext(runtime, assumptions, replacements, target, optimisticOpts);
-        Suites.DEFAULT.getMidTier().apply(graph, midTierContext);
-
-        plan.runPhases(PhasePosition.LOW_LEVEL, graph);
+        suites.getMidTier().apply(graph, midTierContext);
 
         LowTierContext lowTierContext = new LowTierContext(runtime, assumptions, replacements, target);
-        Suites.DEFAULT.getLowTier().apply(graph, lowTierContext);
-        InliningPhase.storeStatisticsAfterLowTier(graph);
+        suites.getLowTier().apply(graph, lowTierContext);
+
+        // we do not want to store statistics about OSR compilations because it may prevent inlining
+        boolean isOSRCompilation = graph.start() instanceof OSRStartNode;
+        if (!isOSRCompilation) {
+            InliningPhase.storeStatisticsAfterLowTier(graph);
+        }
 
         final SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Tue Jun 11 00:00:40 2013 +0200
@@ -46,7 +46,6 @@
 import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.nodes.cfg.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -1578,7 +1577,7 @@
                     // check for duplicate edges between the same blocks (can happen with switch
                     // blocks)
                     if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
-                        if (GraalOptions.TraceLinearScanLevel.getValue() >= 3) {
+                        if (TraceLinearScanLevel.getValue() >= 3) {
                             TTY.println(" processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
                         }
                         alreadyResolved.set(toBlock.getLinearScanNumber());
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Jun 11 00:00:40 2013 +0200
@@ -68,12 +68,6 @@
     protected Block currentBlock;
     private ValueNode currentInstruction;
     private ValueNode lastInstructionPrinted; // Debugging only
-    private FrameState lastState;
-
-    /**
-     * Mapping from blocks to the last encountered frame state at the end of the block.
-     */
-    private final BlockMap<FrameState> blockLastState;
 
     /**
      * Checks whether the supplied constant can be used without loading it into a register for store
@@ -100,7 +94,6 @@
         this.nodeOperands = graph.createNodeMap();
         this.lir = lir;
         this.debugInfoBuilder = createDebugInfoBuilder(nodeOperands);
-        this.blockLastState = new BlockMap<>(lir.cfg);
     }
 
     @SuppressWarnings("hiding")
@@ -291,41 +284,8 @@
         if (block == lir.cfg.getStartBlock()) {
             assert block.getPredecessorCount() == 0;
             emitPrologue();
-
         } else {
             assert block.getPredecessorCount() > 0;
-            FrameState fs = null;
-
-            for (Block pred : block.getPredecessors()) {
-                if (fs == null) {
-                    fs = blockLastState.get(pred);
-                } 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 (TraceLIRGeneratorLevel.getValue() >= 2) {
-                if (fs == null) {
-                    TTY.println("STATE RESET");
-                } else {
-                    TTY.println("STATE CHANGE (singlePred)");
-                    if (TraceLIRGeneratorLevel.getValue() >= 3) {
-                        TTY.println(fs.toString(Node.Verbosity.Debugger));
-                    }
-                }
-            }
-            lastState = fs;
         }
 
         List<ScheduledNode> nodes = lir.nodesFor(block);
@@ -334,10 +294,6 @@
             if (TraceLIRGeneratorLevel.getValue() >= 3) {
                 TTY.println("LIRGen for " + instr);
             }
-            FrameState stateAfter = null;
-            if (instr instanceof StateSplit && !(instr instanceof InfopointNode)) {
-                stateAfter = ((StateSplit) instr).stateAfter();
-            }
             if (instr instanceof ValueNode) {
                 ValueNode valueNode = (ValueNode) instr;
                 if (operand(valueNode) == null) {
@@ -355,16 +311,6 @@
                     // before by other instructions.
                 }
             }
-            if (stateAfter != null) {
-                lastState = stateAfter;
-                assert checkStateReady(lastState);
-                if (TraceLIRGeneratorLevel.getValue() >= 2) {
-                    TTY.println("STATE CHANGE");
-                    if (TraceLIRGeneratorLevel.getValue() >= 3) {
-                        TTY.println(stateAfter.toString(Node.Verbosity.Debugger));
-                    }
-                }
-            }
         }
         if (block.getSuccessorCount() >= 1 && !endsWithJump(block)) {
             NodeClassIterable successors = block.getEndNode().successors();
@@ -377,11 +323,6 @@
             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;
-
-        blockLastState.put(block, lastState);
         currentBlock = null;
 
         if (PrintIRWithLIR.getValue()) {
@@ -391,19 +332,6 @@
 
     protected abstract boolean peephole(ValueNode valueNode);
 
-    private boolean checkStateReady(FrameState state) {
-        FrameState fs = state;
-        while (fs != null) {
-            for (ValueNode v : fs.values()) {
-                if (v != null && !(v instanceof VirtualObjectNode)) {
-                    assert operand(v) != null : "Value " + v + " in " + fs + " is not ready!";
-                }
-            }
-            fs = fs.outerFrameState();
-        }
-        return true;
-    }
-
     private boolean endsWithJump(Block block) {
         List<LIRInstruction> instructions = lir.lir(block);
         if (instructions.size() == 0) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Tue Jun 11 00:00:40 2013 +0200
@@ -45,7 +45,7 @@
         }
 
         if (PartialEscapeAnalysis.getValue()) {
-            addPhase(new PartialEscapeAnalysisPhase(true, OptEarlyReadElimination.getValue(), canonicalizer));
+            addPhase(new PartialEscapePhase(true, canonicalizer));
         }
 
         if (OptConvertDeoptsToGuards.getValue()) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Tue Jun 11 00:00:40 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.sparc.*;
 
 /**
  * SPARC specific implementation of {@link HotSpotGraalRuntime}.
@@ -44,10 +45,15 @@
         return graalRuntime();
     }
 
+    protected static Architecture createArchitecture() {
+        return new SPARC();
+    }
+
     @Override
     protected TargetDescription createTarget() {
-        // SPARC: Create target description.
-        throw new InternalError("NYI");
+        final int stackFrameAlignment = 16;
+        final int implicitNullCheckLimit = 4096;
+        return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, true);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.phases.GraalOptions.*;
 
 import org.junit.*;
 
@@ -31,7 +32,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -74,20 +74,19 @@
         StructuredGraph graph = parse(test);
         ResolvedJavaMethod method = graph.method();
 
-        boolean originalSetting = GraalOptions.OptCanonicalizeReads.getValue();
-        GraalOptions.OptCanonicalizeReads.setValue(!compileAOT);
+        boolean originalSetting = OptCanonicalizeReads.getValue();
+        OptCanonicalizeReads.setValue(!compileAOT);
         PhasePlan phasePlan = new PhasePlan();
         final StructuredGraph graphCopy = graph.copy();
         GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-        phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase());
         editPhasePlan(method, graph, phasePlan);
         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
         final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
-                        new SpeculationLog());
+                        new SpeculationLog(), suites);
         addMethod(method, compResult, graphCopy);
 
-        GraalOptions.OptCanonicalizeReads.setValue(originalSetting);
+        OptCanonicalizeReads.setValue(originalSetting);
 
         return graph;
     }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import org.junit.*;
 
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.phases.*;
 
 /**
  * Tests {@link CompileTheWorld} functionality.
@@ -35,11 +36,11 @@
 
     @Test
     public void testRtJar() throws Throwable {
-        boolean originalSetting = GraalOptions.ExitVMOnException.getValue();
+        boolean originalSetting = ExitVMOnException.getValue();
         // Compile a couple classes in rt.jar
         String file = System.getProperty("java.home") + "/lib/rt.jar";
         new CompileTheWorld(file, 1, 5).compile();
-        GraalOptions.ExitVMOnException.setValue(originalSetting);
+        ExitVMOnException.setValue(originalSetting);
     }
 
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Tue Jun 11 00:00:40 2013 +0200
@@ -41,6 +41,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
 
 public final class CompilationTask implements Runnable, Comparable<CompilationTask> {
 
@@ -57,6 +58,7 @@
 
     private final HotSpotGraalRuntime graalRuntime;
     private final PhasePlan plan;
+    private final SuitesProvider suitesProvider;
     private final OptimisticOptimizations optimisticOpts;
     private final HotSpotResolvedJavaMethod method;
     private final int entryBCI;
@@ -72,6 +74,7 @@
     private CompilationTask(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id, int priority) {
         this.graalRuntime = graalRuntime;
         this.plan = plan;
+        this.suitesProvider = graalRuntime.getCapability(SuitesProvider.class);
         this.method = method;
         this.optimisticOpts = optimisticOpts;
         this.entryBCI = entryBCI;
@@ -165,7 +168,7 @@
                         HotSpotRuntime runtime = graalRuntime.getRuntime();
                         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
                         return GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts,
-                                        method.getSpeculationLog());
+                                        method.getSpeculationLog(), suitesProvider.getDefaultSuites());
                     }
                 });
             } finally {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Tue Jun 11 00:00:40 2013 +0200
@@ -31,12 +31,14 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
 
 //import static com.oracle.graal.phases.GraalOptions.*;
 
@@ -87,9 +89,11 @@
         runtime.compilerToVm = toVM;
     }
 
+    private static final String DEFAULT_GRAAL_RUNTIME = "basic";
+
     // @formatter:off
     @Option(help = "The runtime configuration to use")
-    private static final OptionValue<String> GraalRuntime = new OptionValue<>("basic");
+    private static final OptionValue<String> GraalRuntime = new OptionValue<>(DEFAULT_GRAAL_RUNTIME);
     // @formatter:on
 
     protected static HotSpotGraalRuntimeFactory findFactory(String architecture) {
@@ -98,6 +102,11 @@
                 return factory;
             }
         }
+        if (!DEFAULT_GRAAL_RUNTIME.equals(GraalRuntime.getValue())) {
+            // Fail fast if a non-default value for GraalRuntime was specified
+            // and the corresponding factory is not available
+            throw new GraalInternalError("Specified runtime \"%s\" not available for the %s architecture", GraalRuntime.getValue(), architecture);
+        }
         return null;
     }
 
@@ -310,7 +319,7 @@
         if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class) {
             return (T) getRuntime();
         }
-        if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class) {
+        if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class || clazz == SuitesProvider.class) {
             return (T) getRuntime();
         }
         if (clazz == HotSpotRuntime.class) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Tue Jun 11 00:00:40 2013 +0200
@@ -23,16 +23,28 @@
 
 package com.oracle.graal.hotspot;
 
+import static java.nio.file.Files.*;
+
+import java.io.*;
+import java.nio.charset.*;
+import java.nio.file.*;
 import java.util.*;
 
 import com.oracle.graal.hotspot.logging.*;
 import com.oracle.graal.options.*;
 
+/**
+ * Called from {@code graalCompiler.cpp} to parse any Graal specific options. Such options are
+ * (currently) distinguished by a {@code "-G:"} prefix.
+ */
 public class HotSpotOptions {
 
     private static final Map<String, OptionDescriptor> options = new HashMap<>();
 
-    static {
+    /**
+     * Initializes {@link #options} from {@link Options} services.
+     */
+    private static void initializeOptions() {
         ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
         for (Options opts : sl) {
             for (OptionDescriptor desc : opts) {
@@ -45,6 +57,38 @@
         }
     }
 
+    /**
+     * Loads default option value overrides from a {@code graal.options} file if it exists. Each
+     * line in this file starts with {@code "#"} and is ignored or must have the format of a Graal
+     * command line option without the leading {@code "-G:"} prefix. These option value are set
+     * prior to processing of any Graal options present on the command line.
+     */
+    private static void loadOptionOverrides() throws InternalError {
+        String javaHome = System.getProperty("java.home");
+        Path graalDotOptions = Paths.get(javaHome, "lib", "graal.options");
+        if (!exists(graalDotOptions)) {
+            graalDotOptions = Paths.get(javaHome, "jre", "lib", "graal.options");
+        }
+        if (exists(graalDotOptions)) {
+            try {
+                for (String line : Files.readAllLines(graalDotOptions, Charset.defaultCharset())) {
+                    if (!line.startsWith("#")) {
+                        if (!setOption(line)) {
+                            throw new InternalError("Invalid option \"" + line + "\" specified in " + graalDotOptions);
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                throw (InternalError) new InternalError().initCause(e);
+            }
+        }
+    }
+
+    static {
+        initializeOptions();
+        loadOptionOverrides();
+    }
+
     // Called from VM code
     public static boolean setOption(String option) {
         if (option.length() == 0) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jun 11 00:00:40 2013 +0200
@@ -384,6 +384,8 @@
     public int typeProfileWidth;
     public int methodProfileWidth;
 
+    public int interpreterProfilingThreshold;
+
     public long inlineCacheMissStub;
     public long handleDeoptStub;
     public long uncommonTrapStub;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Jun 11 00:00:40 2013 +0200
@@ -772,11 +772,6 @@
         if (onStackReplacement) {
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase());
         }
-        phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase());
-        if (VerifyPhases.getValue()) {
-            phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierVerificationPhase());
-
-        }
         return phasePlan;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java	Tue Jun 11 00:00:40 2013 +0200
@@ -127,13 +127,15 @@
     }
 
     @Override
-    public void put(StructuredGraph graph) {
+    public void put(StructuredGraph graph, boolean hasMatureProfilingInfo) {
         assert graph.method() != null;
-        cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method()));
-        graph.method().getCompilerStorage().put(this, graph);
+        if (hasMatureProfilingInfo) {
+            cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method()));
+            graph.method().getCompilerStorage().put(this, graph);
 
-        if (PrintGraphCache.getValue()) {
-            putCounter++;
+            if (PrintGraphCache.getValue()) {
+                putCounter++;
+            }
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Tue Jun 11 00:00:40 2013 +0200
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -376,7 +375,7 @@
         protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position);
 
         private static JavaTypeProfile createTypeProfile(TriState nullSeen, ResolvedJavaType[] types, long[] counts, long totalCount, int entries) {
-            if (entries <= 0 || totalCount < MatureExecutionsTypeProfile.getValue()) {
+            if (entries <= 0 || totalCount <= 0) {
                 return null;
             }
 
@@ -484,7 +483,7 @@
         }
 
         private static JavaMethodProfile createMethodProfile(ResolvedJavaMethod[] methods, long[] counts, long totalCount, int entries) {
-            if (entries <= 0 || totalCount < MatureExecutionsTypeProfile.getValue()) {
+            if (entries <= 0 || totalCount <= 0) {
                 return null;
             }
 
@@ -540,11 +539,7 @@
             long notTakenCount = data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET);
             long total = takenCount + notTakenCount;
 
-            if (total < MatureExecutionsBranch.getValue()) {
-                return -1;
-            } else {
-                return takenCount / (double) total;
-            }
+            return total <= 0 ? -1 : takenCount / (double) total;
         }
 
         @Override
@@ -607,7 +602,7 @@
                 result[i - 1] = count;
             }
 
-            if (totalCount < MatureExecutionsPerSwitchCase.getValue() * length) {
+            if (totalCount <= 0) {
                 return null;
             } else {
                 for (int i = 0; i < length; i++) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,6 +22,9 @@
  */
 package com.oracle.graal.hotspot.meta;
 
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
@@ -31,23 +34,24 @@
     private static final long serialVersionUID = -8307682725047864875L;
     private static final DebugMetric metricInsufficentSpace = Debug.metric("InsufficientSpaceForProfilingData");
 
+    private final HotSpotMethodData methodData;
+    private final HotSpotResolvedJavaMethod method;
+
     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) {
+    public HotSpotProfilingInfo(HotSpotMethodData methodData, HotSpotResolvedJavaMethod method) {
         this.methodData = methodData;
-        this.codeSize = codeSize;
+        this.method = method;
         hintPosition = 0;
         hintBCI = -1;
     }
 
     @Override
     public int getCodeSize() {
-        return codeSize;
+        return method.getCodeSize();
     }
 
     @Override
@@ -158,6 +162,11 @@
     }
 
     @Override
+    public boolean isMature() {
+        return method.invocationCount() >= graalRuntime().getConfig().interpreterProfilingThreshold + MatureProfilingInformationThreshold.getValue();
+    }
+
+    @Override
     public String toString() {
         return "HotSpotProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue Jun 11 00:00:40 2013 +0200
@@ -288,7 +288,7 @@
             // case of a deoptimization.
             info = DefaultProfilingInfo.get(TriState.FALSE);
         } else {
-            info = new HotSpotProfilingInfo(methodData, codeSize);
+            info = new HotSpotProfilingInfo(methodData, this);
         }
         return info;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Jun 11 00:00:40 2013 +0200
@@ -73,6 +73,7 @@
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.java.*;
@@ -86,6 +87,7 @@
 import com.oracle.graal.nodes.spi.Lowerable.LoweringType;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
@@ -93,7 +95,7 @@
 /**
  * HotSpot implementation of {@link GraalCodeCacheProvider}.
  */
-public abstract class HotSpotRuntime implements GraalCodeCacheProvider, DisassemblerProvider, BytecodeDisassemblerProvider {
+public abstract class HotSpotRuntime implements GraalCodeCacheProvider, DisassemblerProvider, BytecodeDisassemblerProvider, SuitesProvider {
 
     public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class);
     public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class);
@@ -104,6 +106,7 @@
 
     protected final RegisterConfig regConfig;
     protected final HotSpotGraalRuntime graalRuntime;
+    private final Suites defaultSuites;
 
     private CheckCastSnippets.Templates checkcastSnippets;
     private InstanceOfSnippets.Templates instanceofSnippets;
@@ -179,6 +182,7 @@
         this.config = c;
         this.graalRuntime = graalRuntime;
         regConfig = createRegisterConfig();
+        defaultSuites = createSuites();
     }
 
     protected abstract RegisterConfig createRegisterConfig();
@@ -1061,4 +1065,19 @@
     public String disassemble(ResolvedJavaMethod method) {
         return new BytecodeDisassembler().disassemble(method);
     }
+
+    public Suites getDefaultSuites() {
+        return defaultSuites;
+    }
+
+    public Suites createSuites() {
+        Suites ret = Suites.createDefaultSuites();
+
+        ret.getMidTier().addPhase(new WriteBarrierAdditionPhase());
+        if (VerifyPhases.getValue()) {
+            ret.getMidTier().addPhase(new WriteBarrierVerificationPhase());
+        }
+
+        return ret;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -116,10 +116,22 @@
         return position >= 0 && position + length <= virtualObject.entryCount();
     }
 
-    private static boolean checkEntryTypes(int srcPos, int length, State srcState, ResolvedJavaType destComponentType) {
+    private static boolean checkEntryTypes(int srcPos, int length, State srcState, ResolvedJavaType destComponentType, VirtualizerTool tool) {
         if (destComponentType.getKind() == Kind.Object) {
             for (int i = 0; i < length; i++) {
-                if (!destComponentType.isAssignableFrom(srcState.getEntry(srcPos + i).objectStamp().type())) {
+                ValueNode entry = srcState.getEntry(srcPos + i);
+                State state = tool.getObjectState(entry);
+                ResolvedJavaType type;
+                if (state != null) {
+                    if (state.getState() == EscapeState.Virtual) {
+                        type = state.getVirtualObject().type();
+                    } else {
+                        type = state.getMaterializedValue().objectStamp().type();
+                    }
+                } else {
+                    type = entry.objectStamp().type();
+                }
+                if (type == null || !destComponentType.isAssignableFrom(type)) {
                     return false;
                 }
             }
@@ -139,10 +151,16 @@
             if (srcState != null && srcState.getState() == EscapeState.Virtual && destState != null && destState.getState() == EscapeState.Virtual) {
                 VirtualObjectNode srcVirtual = srcState.getVirtualObject();
                 VirtualObjectNode destVirtual = destState.getVirtualObject();
+                if (!(srcVirtual instanceof VirtualArrayNode) || !(destVirtual instanceof VirtualArrayNode)) {
+                    return;
+                }
+                if (((VirtualArrayNode) srcVirtual).componentType().getKind() != Kind.Object || ((VirtualArrayNode) destVirtual).componentType().getKind() != Kind.Object) {
+                    return;
+                }
                 if (length < 0 || !checkBounds(srcPos, length, srcVirtual) || !checkBounds(destPos, length, destVirtual)) {
                     return;
                 }
-                if (!checkEntryTypes(srcPos, length, srcState, destVirtual.type().getComponentType())) {
+                if (!checkEntryTypes(srcPos, length, srcState, destVirtual.type().getComponentType(), tool)) {
                     return;
                 }
                 for (int i = 0; i < length; i++) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Jun 11 00:00:40 2013 +0200
@@ -156,7 +156,7 @@
                     phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                     CallingConvention cc = linkage.getCallingConvention();
                     final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan,
-                                    OptimisticOptimizations.ALL, new SpeculationLog());
+                                    OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites());
 
                     assert destroyedRegisters != null;
                     code = Debug.scope("CodeInstall", new Callable<InstalledCode>() {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -919,7 +919,7 @@
         }
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.1));
+        append(new IfNode(currentGraph.unique(new IsNullNode(receiver)), trueSucc, falseSucc, 0.01));
         lastInstr = falseSucc;
 
         if (OmitHotExceptionStacktrace.getValue()) {
@@ -943,7 +943,7 @@
     private void emitBoundsCheck(ValueNode index, ValueNode length) {
         BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode());
         BlockPlaceholderNode falseSucc = currentGraph.add(new BlockPlaceholderNode());
-        append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.9));
+        append(new IfNode(currentGraph.unique(new IntegerBelowThanNode(index, length)), trueSucc, falseSucc, 0.99));
         lastInstr = trueSucc;
 
         if (OmitHotExceptionStacktrace.getValue()) {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Tue Jun 11 00:00:40 2013 +0200
@@ -373,6 +373,12 @@
             }
         } else {
             switch (opcode) {
+            // case A:  new Add(Int, dst, src1, src2);
+            // case S:  new Sub(Int, dst, src1, src2);
+            // case U:  new Shl(UnsignedInt, dst, src1, src2);
+            // case L:  new Shl(UnsignedLong, dst, src1, src2);
+            // case F:  new Add(Float, dst, src1, src2);
+            // case D:  new Mul(Double, dst, src1, src2);
             case IADD:  masm.add_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
             case ISUB:  masm.sub_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
             case IMUL:  masm.mul_s32(asIntReg(dst),    asIntReg(src1),    asIntReg(src2));    break;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,9 +22,16 @@
  */
 package com.oracle.graal.lir.sparc;
 
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Andn;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Or;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Popc;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Srlx;
+import static com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
 import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13;
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -54,6 +61,7 @@
     @SuppressWarnings("unused")
     public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
         Register dst = ValueUtil.asIntReg(result);
+        Register tmp = null;  // ??
         if (ValueUtil.isRegister(input)) {
             Register src = ValueUtil.asRegister(input);
             switch (opcode) {
@@ -65,9 +73,64 @@
                 case LPOPCNT:
                     new Popc(masm, src, dst);
                     break;
-                case BSF:  // masm.bsfq(dst, src);
-                case IBSR:  // masm.bsrl(dst, src);
-                case LBSR:  // masm.bsrq(dst, src);
+                case BSF:
+                    // countTrailingZerosI - bsfl
+                    // countTrailingZerosL - masm.bsfq(dst, src);
+                    Kind tkind = input.getKind();
+                    if (tkind == Kind.Int) {
+                        new Sub(masm, src, 1, dst);
+                        new Andn(masm, dst, src, dst);
+                        new Srl(masm, dst, SPARC.g0, dst);
+                        new Popc(masm, dst, dst);
+                    } else if (tkind == Kind.Long) {
+                        new Sub(masm, src, 1, dst);
+                        new Andn(masm, dst, src, dst);
+                        new Popc(masm, dst, dst);
+                    } else {
+                        throw GraalInternalError.shouldNotReachHere("missing: " + tkind);
+                    }
+                    break;
+                case IBSR:
+                    // countLeadingZerosI_bsr masm.bsrq(dst, src);
+                    // masm.bsrl(dst, src);
+                    Kind ikind = input.getKind();
+                    assert ikind == Kind.Int;
+                    new Srl(masm, src, 1, tmp);
+                    new Srl(masm, src, 0, dst);
+                    new Or(masm, src, tmp, dst);
+                    new Srl(masm, dst, 2, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srl(masm, dst, 4, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srl(masm, dst, 8, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srl(masm, dst, 16, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Popc(masm, dst, dst);
+                    new Mov(masm, ikind.getBitCount(), tmp);
+                    new Sub(masm, tmp, dst, dst);
+                    break;
+                case LBSR:
+                    // countLeadingZerosL_bsr masm.bsrq(dst, src);
+                    // masm.bsrq(dst, src);
+                    Kind lkind = input.getKind();
+                    assert lkind == Kind.Int;
+                    new Srlx(masm, src, 1, tmp);
+                    new Or(masm, src, tmp, dst);
+                    new Srlx(masm, dst, 2, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srlx(masm, dst, 4, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srlx(masm, dst, 8, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srlx(masm, dst, 16, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srlx(masm, dst, 32, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Popc(masm, dst, dst);
+                    new Mov(masm, lkind.getBitCount(), tmp);
+                    new Sub(masm, tmp, dst, dst);
+                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
 
@@ -87,20 +150,41 @@
             SPARCAddress src = (SPARCAddress) tasm.asAddress(input);
             switch (opcode) {
                 case IPOPCNT:
-                    // masm.popcntl(dst, src);
+                    new Ldsw(masm, src, tmp);
+                    // clear upper word for 64 bit POPC
+                    new Srl(masm, tmp, SPARC.g0, dst);
+                    new Popc(masm, tmp, dst);
                     break;
                 case LPOPCNT:
-                    // masm.popcntq(dst, src);
+                    new Ldx(masm, src, tmp);
+                    new Popc(masm, tmp, dst);
                     break;
                 case BSF:
-                    // masm.bsfq(dst, src);
+                    assert input.getKind() == Kind.Int;
+                    new Ldsw(masm, src, tmp);
+                    new Srl(masm, tmp, 1, tmp);
+                    new Srl(masm, tmp, 0, dst);
+                    new Or(masm, tmp, tmp, dst);
+                    new Srl(masm, dst, 2, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srl(masm, dst, 4, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srl(masm, dst, 8, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Srl(masm, dst, 16, tmp);
+                    new Or(masm, dst, tmp, dst);
+                    new Popc(masm, dst, dst);
+                    new Mov(masm, Kind.Int.getBitCount(), tmp);
+                    new Sub(masm, tmp, dst, dst);
                     break;
                 case IBSR:
                     // masm.bsrl(dst, src);
-                    break;
+                    // countLeadingZerosI_bsr masm.bsrq(dst, src);
+                    // masm.bsrl(dst, src);
                 case LBSR:
                     // masm.bsrq(dst, src);
-                    break;
+                default:
+                    throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
             }
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InlineableElement.java	Mon Jun 10 23:59:50 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes;
-
-public interface InlineableElement {
-
-    int getNodeCount();
-
-    Iterable<Invoke> getInvokes();
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Tue Jun 11 00:00:40 2013 +0200
@@ -35,7 +35,7 @@
  * A graph that contains at least one distinguished node : the {@link #start() start} node. This
  * node is the start of the control flow of the graph.
  */
-public class StructuredGraph extends Graph implements InlineableElement {
+public class StructuredGraph extends Graph {
 
     public static final int INVOCATION_ENTRY_BCI = -1;
     public static final long INVALID_GRAPH_ID = -1;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -29,7 +29,7 @@
 import com.oracle.graal.nodes.spi.*;
 
 @NodeInfo(shortName = "*")
-public final class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
+public class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
 
     public IntegerMulNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -29,7 +29,7 @@
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "-")
-public final class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
+public class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable {
 
     public IntegerSubNode(Kind kind, ValueNode x, ValueNode y) {
         super(kind, x, y);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -105,10 +105,15 @@
     @Override
     public void setDeoptimizationState(FrameState f) {
         updateUsages(deoptState, f);
-        if (deoptState != null) {
-            throw new IllegalStateException(toString(Verbosity.Debugger));
+        assert deoptState == null && canDeoptimize() : "shouldn't assign deoptState to " + this;
+        deoptState = f;
+    }
+
+    @Override
+    public void setStateAfter(FrameState x) {
+        if (hasSideEffect() || canDeoptimize()) {
+            super.setStateAfter(x);
         }
-        deoptState = f;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -56,9 +56,12 @@
     }
 
     private boolean assertProbabilities() {
+        double total = 0;
         for (double d : keyProbabilities) {
+            total += d;
             assert d >= 0.0 : "Cannot have negative probabilities in switch node: " + d;
         }
+        assert total > 0.999 && total < 1.001;
         return true;
     }
 
@@ -73,6 +76,32 @@
         return sum;
     }
 
+    public void setProbability(Node successor, double value) {
+        double changeInProbability = 0;
+        int nonZeroProbabilityCases = 0;
+        for (int i = 0; i < keySuccessors.length; i++) {
+            if (successors.get(keySuccessors[i]) == successor) {
+                changeInProbability += keyProbabilities[i] - value;
+                keyProbabilities[i] = value;
+            } else if (keyProbabilities[i] > 0) {
+                nonZeroProbabilityCases++;
+            }
+        }
+
+        if (nonZeroProbabilityCases > 0) {
+            double changePerEntry = changeInProbability / nonZeroProbabilityCases;
+            if (changePerEntry != 0) {
+                for (int i = 0; i < keyProbabilities.length; i++) {
+                    if (keyProbabilities[i] > 0) {
+                        keyProbabilities[i] = keyProbabilities[i] + changePerEntry;
+                    }
+                }
+            }
+        }
+
+        assertProbabilities();
+    }
+
     public ValueNode value() {
         return value;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -79,13 +79,6 @@
             if (fieldIndex != -1) {
                 tool.replaceWith(state.getEntry(fieldIndex));
             }
-        } else {
-            ValueNode cachedValue = tool.getReadCache(object(), field());
-            if (cachedValue != null) {
-                tool.replaceWithValue(cachedValue);
-            } else {
-                tool.addReadCache(object(), field(), this);
-            }
         }
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -77,12 +77,6 @@
                 tool.setVirtualEntry(state, fieldIndex, value());
                 tool.delete();
             }
-        } else {
-            if (value() == tool.getReadCache(object(), field())) {
-                tool.delete();
-            }
-            tool.killReadCache(field());
-            tool.addReadCache(object(), field(), value());
         }
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java	Tue Jun 11 00:00:40 2013 +0200
@@ -27,7 +27,7 @@
 
 public interface GraphCache {
 
-    void put(StructuredGraph graph);
+    void put(StructuredGraph graph, boolean hasMatureProfilingInfo);
 
     StructuredGraph get(ResolvedJavaMethod method);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java	Tue Jun 11 00:00:40 2013 +0200
@@ -43,8 +43,6 @@
 
         public abstract VirtualObjectNode getVirtualObject();
 
-        public abstract void setEntry(int index, ValueNode value);
-
         public abstract ValueNode getEntry(int index);
 
         public abstract void addLock(int depth);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Tue Jun 11 00:00:40 2013 +0200
@@ -153,10 +153,4 @@
      */
     void replaceWith(ValueNode value);
 
-    void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value);
-
-    ValueNode getReadCache(ValueNode object, ResolvedJavaField identity);
-
-    void killReadCache(ResolvedJavaField identity);
-
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -37,6 +37,11 @@
         this.fields = type.getInstanceFields(true);
     }
 
+    public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) {
+        this.type = type;
+        this.fields = fields;
+    }
+
     @Override
     public ResolvedJavaType type() {
         return type;
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Tue Jun 11 00:00:40 2013 +0200
@@ -159,7 +159,7 @@
                 String help = option.help;
                 String location = pkg + "." + option.declaringClass + "." + option.field.getSimpleName();
                 String comma = i == info.options.size() - 1 ? "" : ",";
-                out.printf("            new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s%n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma);
+                out.printf("            new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s\n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma);
                 i++;
             }
             out.println("        );");
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -119,7 +119,7 @@
             if (newNodesMark > 0) {
                 workList.addAll(graph.getNewNodes(newNodesMark));
             }
-            tool = new Tool(workList, runtime, assumptions, canonicalizeReads);
+            tool = new Tool();
             processWorkSet(graph);
         }
 
@@ -309,19 +309,7 @@
             }
         }
 
-        private static final class Tool implements SimplifierTool {
-
-            private final NodeWorkList nodeWorkSet;
-            private final MetaAccessProvider runtime;
-            private final Assumptions assumptions;
-            private final boolean canonicalizeReads;
-
-            public Tool(NodeWorkList nodeWorkSet, MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads) {
-                this.nodeWorkSet = nodeWorkSet;
-                this.runtime = runtime;
-                this.assumptions = assumptions;
-                this.canonicalizeReads = canonicalizeReads;
-            }
+        private final class Tool implements SimplifierTool {
 
             @Override
             public void deleteBranch(FixedNode branch) {
@@ -345,7 +333,7 @@
 
             @Override
             public void addToWorkList(Node node) {
-                nodeWorkSet.addAgain(node);
+                workList.addAgain(node);
             }
 
             @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
@@ -43,6 +45,6 @@
     protected void run(StructuredGraph graph, C context) {
         int mark = graph.getMark();
         super.run(graph, context);
-        new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), GraalOptions.OptCanonicalizeReads.getValue(), mark, customCanonicalizer).apply(graph);
+        new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), OptCanonicalizeReads.getValue(), mark, customCanonicalizer).apply(graph);
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -40,7 +40,9 @@
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
 import com.oracle.graal.phases.common.InliningUtil.InlineInfo;
+import com.oracle.graal.phases.common.InliningUtil.Inlineable;
 import com.oracle.graal.phases.common.InliningUtil.InlineableMacroNode;
+import com.oracle.graal.phases.common.InliningUtil.InlineableGraph;
 import com.oracle.graal.phases.common.InliningUtil.InliningPolicy;
 import com.oracle.graal.phases.graph.*;
 
@@ -149,19 +151,16 @@
         if (info != null) {
             double invokeProbability = graphInfo.invokeProbability(invoke);
             double invokeRelevance = graphInfo.invokeRelevance(invoke);
-
-            if (inliningPolicy.isWorthInlining(info, data.inliningDepth(), invokeProbability, invokeRelevance, false)) {
-                MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance);
+            MethodInvocation calleeInvocation = data.pushInvocation(info, parentAssumptions, invokeProbability, invokeRelevance);
 
-                for (int i = 0; i < info.numberOfMethods(); i++) {
-                    InlineableElement elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions());
-                    info.setInlinableElement(i, elem);
-                    if (elem instanceof StructuredGraph) {
-                        data.pushGraph((StructuredGraph) elem, invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
-                    } else {
-                        assert elem instanceof InlineableMacroNode;
-                        data.pushDummyGraph();
-                    }
+            for (int i = 0; i < info.numberOfMethods(); i++) {
+                Inlineable elem = getInlineableElement(info.methodAt(i), info.invoke(), calleeInvocation.assumptions());
+                info.setInlinableElement(i, elem);
+                if (elem instanceof InlineableGraph) {
+                    data.pushGraph(((InlineableGraph) elem).getGraph(), invokeProbability * info.probabilityAt(i), invokeRelevance * info.relevanceAt(i));
+                } else {
+                    assert elem instanceof InlineableMacroNode;
+                    data.pushDummyGraph();
                 }
             }
         }
@@ -215,12 +214,12 @@
         }
     }
 
-    private InlineableElement getInlineableElement(final ResolvedJavaMethod method, Invoke invoke, Assumptions assumptions) {
+    private Inlineable getInlineableElement(final ResolvedJavaMethod method, Invoke invoke, Assumptions assumptions) {
         Class<? extends FixedWithNextNode> macroNodeClass = InliningUtil.getMacroNodeClass(replacements, method);
         if (macroNodeClass != null) {
             return new InlineableMacroNode(macroNodeClass);
         } else {
-            return buildGraph(method, invoke, assumptions);
+            return new InlineableGraph(buildGraph(method, invoke, assumptions));
         }
     }
 
@@ -296,6 +295,8 @@
     }
 
     private StructuredGraph parseBytecodes(StructuredGraph newGraph, Assumptions assumptions) {
+        boolean hasMatureProfilingInfo = newGraph.method().getProfilingInfo().isMature();
+
         if (plan != null) {
             plan.runPhases(PhasePosition.AFTER_PARSING, newGraph);
         }
@@ -311,7 +312,7 @@
             new CullFrameStatesPhase().apply(newGraph);
         }
         if (CacheGraphs.getValue() && cache != null) {
-            cache.put(newGraph.copy());
+            cache.put(newGraph.copy(), hasMatureProfilingInfo);
         }
         return newGraph;
     }
@@ -387,7 +388,7 @@
         protected static int determineNodeCount(InlineInfo info) {
             int nodes = 0;
             for (int i = 0; i < info.numberOfMethods(); i++) {
-                InlineableElement elem = info.inlineableElementAt(i);
+                Inlineable elem = info.inlineableElementAt(i);
                 if (elem != null) {
                     nodes += elem.getNodeCount();
                 }
@@ -398,10 +399,10 @@
         protected static double determineInvokeProbability(InlineInfo info) {
             double invokeProbability = 0;
             for (int i = 0; i < info.numberOfMethods(); i++) {
-                InlineableElement callee = info.inlineableElementAt(i);
+                Inlineable callee = info.inlineableElementAt(i);
                 Iterable<Invoke> invokes = callee.getInvokes();
                 if (invokes.iterator().hasNext()) {
-                    NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure((StructuredGraph) callee).apply();
+                    NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(((InlineableGraph) callee).getGraph()).apply();
                     for (Invoke invoke : invokes) {
                         invokeProbability += nodeProbabilities.get(invoke.asNode());
                     }
@@ -433,15 +434,16 @@
             }
 
             double inliningBonus = getInliningBonus(info);
-
+            int nodes = determineNodeCount(info);
             int lowLevelGraphSize = previousLowLevelGraphSize(info);
+
             if (SmallCompiledLowLevelGraphSize.getValue() > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue() * inliningBonus) {
-                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph: %d", lowLevelGraphSize);
+                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)",
+                                lowLevelGraphSize, relevance, probability, inliningBonus, nodes);
             }
 
-            int nodes = determineNodeCount(info);
             if (nodes < TrivialInliningSize.getValue() * inliningBonus) {
-                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (nodes=%d)", nodes);
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
             }
 
             /*
@@ -452,16 +454,17 @@
              */
             double invokes = determineInvokeProbability(info);
             if (LimitInlinedInvokes.getValue() > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue() * inliningBonus) {
-                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (%f)", invokes);
+                return InliningUtil.logNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes,
+                                relevance, probability, inliningBonus, nodes);
             }
 
             double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue() * inliningBonus));
             if (nodes <= maximumNodes) {
-                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= max=%f)", relevance, probability,
+                return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability,
                                 inliningBonus, nodes, maximumNodes);
             }
 
-            return InliningUtil.logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > max=%f)", relevance, probability, inliningBonus, nodes,
+            return InliningUtil.logNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes,
                             maximumNodes);
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Tue Jun 11 00:00:40 2013 +0200
@@ -66,7 +66,37 @@
         boolean isWorthInlining(InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed);
     }
 
-    public static class InlineableMacroNode implements InlineableElement {
+    public interface Inlineable {
+
+        int getNodeCount();
+
+        Iterable<Invoke> getInvokes();
+    }
+
+    public static class InlineableGraph implements Inlineable {
+
+        private final StructuredGraph graph;
+
+        public InlineableGraph(StructuredGraph graph) {
+            this.graph = graph;
+        }
+
+        @Override
+        public int getNodeCount() {
+            return graph.getNodeCount();
+        }
+
+        @Override
+        public Iterable<Invoke> getInvokes() {
+            return graph.getInvokes();
+        }
+
+        public StructuredGraph getGraph() {
+            return graph;
+        }
+    }
+
+    public static class InlineableMacroNode implements Inlineable {
 
         private final Class<? extends FixedWithNextNode> macroNodeClass;
 
@@ -238,13 +268,13 @@
 
         ResolvedJavaMethod methodAt(int index);
 
-        InlineableElement inlineableElementAt(int index);
+        Inlineable inlineableElementAt(int index);
 
         double probabilityAt(int index);
 
         double relevanceAt(int index);
 
-        void setInlinableElement(int index, InlineableElement inlineableElement);
+        void setInlinableElement(int index, Inlineable inlineableElement);
 
         /**
          * Performs the inlining described by this object and returns the node that represents the
@@ -277,10 +307,10 @@
             return invoke;
         }
 
-        protected static void inline(Invoke invoke, ResolvedJavaMethod concrete, InlineableElement inlineable, Assumptions assumptions, boolean receiverNullCheck) {
+        protected static void inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) {
             StructuredGraph graph = invoke.asNode().graph();
-            if (inlineable instanceof StructuredGraph) {
-                StructuredGraph calleeGraph = (StructuredGraph) inlineable;
+            if (inlineable instanceof InlineableGraph) {
+                StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph();
                 InliningUtil.inline(invoke, calleeGraph, receiverNullCheck);
 
                 graph.getLeafGraphIds().add(calleeGraph.graphId());
@@ -331,11 +361,12 @@
     private static class ExactInlineInfo extends AbstractInlineInfo {
 
         protected final ResolvedJavaMethod concrete;
-        private InlineableElement inlineableElement;
+        private Inlineable inlineableElement;
 
         public ExactInlineInfo(Invoke invoke, ResolvedJavaMethod concrete) {
             super(invoke);
             this.concrete = concrete;
+            assert concrete != null;
         }
 
         @Override
@@ -377,13 +408,13 @@
         }
 
         @Override
-        public InlineableElement inlineableElementAt(int index) {
+        public Inlineable inlineableElementAt(int index) {
             assert index == 0;
             return inlineableElement;
         }
 
         @Override
-        public void setInlinableElement(int index, InlineableElement inlineableElement) {
+        public void setInlinableElement(int index, Inlineable inlineableElement) {
             assert index == 0;
             this.inlineableElement = inlineableElement;
         }
@@ -398,7 +429,7 @@
 
         private final ResolvedJavaMethod concrete;
         private final ResolvedJavaType type;
-        private InlineableElement inlineableElement;
+        private Inlineable inlineableElement;
 
         public TypeGuardInlineInfo(Invoke invoke, ResolvedJavaMethod concrete, ResolvedJavaType type) {
             super(invoke);
@@ -418,7 +449,7 @@
         }
 
         @Override
-        public InlineableElement inlineableElementAt(int index) {
+        public Inlineable inlineableElementAt(int index) {
             assert index == 0;
             return inlineableElement;
         }
@@ -436,7 +467,7 @@
         }
 
         @Override
-        public void setInlinableElement(int index, InlineableElement inlineableElement) {
+        public void setInlinableElement(int index, Inlineable inlineableElement) {
             assert index == 0;
             this.inlineableElement = inlineableElement;
         }
@@ -491,7 +522,7 @@
         private final ArrayList<ProfiledType> ptypes;
         private final ArrayList<Double> concretesProbabilities;
         private final double notRecordedTypeProbability;
-        private final InlineableElement[] inlineableElements;
+        private final Inlineable[] inlineableElements;
 
         public MultiTypeGuardInlineInfo(Invoke invoke, ArrayList<ResolvedJavaMethod> concretes, ArrayList<Double> concretesProbabilities, ArrayList<ProfiledType> ptypes,
                         ArrayList<Integer> typesToConcretes, double notRecordedTypeProbability) {
@@ -504,7 +535,7 @@
             this.ptypes = ptypes;
             this.typesToConcretes = typesToConcretes;
             this.notRecordedTypeProbability = notRecordedTypeProbability;
-            this.inlineableElements = new InlineableElement[concretes.size()];
+            this.inlineableElements = new Inlineable[concretes.size()];
             this.methodProbabilities = computeMethodProbabilities();
             this.maximumMethodProbability = maximumMethodProbability();
             assert maximumMethodProbability > 0;
@@ -540,7 +571,7 @@
         }
 
         @Override
-        public InlineableElement inlineableElementAt(int index) {
+        public Inlineable inlineableElementAt(int index) {
             assert index >= 0 && index < concretes.size();
             return inlineableElements[index];
         }
@@ -556,7 +587,7 @@
         }
 
         @Override
-        public void setInlinableElement(int index, InlineableElement inlineableElement) {
+        public void setInlinableElement(int index, Inlineable inlineableElement) {
             assert index >= 0 && index < concretes.size();
             inlineableElements[index] = inlineableElement;
         }
@@ -907,16 +938,12 @@
         @Override
         public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) {
             if (hasSingleMethod()) {
-                tryToDevirtualizeSingleMethod(graph(), runtime);
+                devirtualizeWithTypeSwitch(graph(), InvokeKind.Special, concretes.get(0), runtime);
             } else {
                 tryToDevirtualizeMultipleMethods(graph(), runtime);
             }
         }
 
-        private void tryToDevirtualizeSingleMethod(StructuredGraph graph, MetaAccessProvider runtime) {
-            devirtualizeWithTypeSwitch(graph, InvokeKind.Special, concretes.get(0), runtime);
-        }
-
         private void tryToDevirtualizeMultipleMethods(StructuredGraph graph, MetaAccessProvider runtime) {
             MethodCallTargetNode methodCallTarget = (MethodCallTargetNode) invoke.callTarget();
             if (methodCallTarget.invokeKind() == InvokeKind.Interface) {
@@ -1156,7 +1183,7 @@
                 ArrayList<ResolvedJavaMethod> newConcreteMethods = new ArrayList<>();
                 ArrayList<Double> newConcreteMethodsProbabilities = new ArrayList<>();
                 for (int i = 0; i < concreteMethods.size(); ++i) {
-                    if (concreteMethodsProbabilities.get(i) >= GraalOptions.MegamorphicInliningMinMethodProbability.getValue()) {
+                    if (concreteMethodsProbabilities.get(i) >= MegamorphicInliningMinMethodProbability.getValue()) {
                         newConcreteMethods.add(concreteMethods.get(i));
                         newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i));
                     }
@@ -1229,7 +1256,7 @@
     private static boolean checkTargetConditions(InliningData data, Replacements replacements, Invoke invoke, ResolvedJavaMethod method, OptimisticOptimizations optimisticOpts) {
         if (method == null) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "the method is not resolved");
-        } else if (Modifier.isNative(method.getModifiers()) && (!GraalOptions.Intrinsify.getValue() || !InliningUtil.canIntrinsify(replacements, method))) {
+        } else if (Modifier.isNative(method.getModifiers()) && (!Intrinsify.getValue() || !InliningUtil.canIntrinsify(replacements, method))) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is a non-intrinsic native method");
         } else if (Modifier.isAbstract(method.getModifiers())) {
             return logNotInlinedMethodAndReturnFalse(invoke, data.inliningDepth(), method, "it is an abstract method");
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 
 import com.oracle.graal.graph.Graph.NodeChangedListener;
@@ -44,7 +46,7 @@
             if (canonicalizationRoots.isEmpty()) {
                 break;
             }
-            new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), GraalOptions.OptCanonicalizeReads.getValue(), canonicalizationRoots, null).apply(graph);
+            new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), OptCanonicalizeReads.getValue(), canonicalizationRoots, null).apply(graph);
             canonicalizationRoots.clear();
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -300,7 +300,7 @@
                     phi.setMerge(mergeAfter);
                 }
             }
-            new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), GraalOptions.OptCanonicalizeReads.getValue(), graph.getNewNodes(startMark), null).apply(graph);
+            new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), OptCanonicalizeReads.getValue(), graph.getNewNodes(startMark), null).apply(graph);
             Debug.dump(graph, "After tail duplication at %s", merge);
         }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Jun 11 00:00:40 2013 +0200
@@ -87,11 +87,7 @@
     @Option(help = "")
     public static final OptionValue<Integer> DeoptsToDisableOptimisticOptimization = new OptionValue<>(40);
     @Option(help = "")
-    public static final OptionValue<Integer> MatureExecutionsBranch = new OptionValue<>(1);
-    @Option(help = "")
-    public static final OptionValue<Integer> MatureExecutionsPerSwitchCase = new OptionValue<>(1);
-    @Option(help = "")
-    public static final OptionValue<Integer> MatureExecutionsTypeProfile = new OptionValue<>(1);
+    public static final OptionValue<Integer> MatureProfilingInformationThreshold = new OptionValue<>(100);
 
     // comilation queue
     @Option(help = "")
@@ -261,8 +257,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> OptReadElimination = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Boolean> OptEarlyReadElimination = new OptionValue<>(true);
-    @Option(help = "")
     public static final OptionValue<Boolean> OptCanonicalizer = new OptionValue<>(true);
     @Option(help = "")
     public static final OptionValue<Boolean> OptCanonicalizeReads = new OptionValue<>(true);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhasePlan.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhasePlan.java	Tue Jun 11 00:00:40 2013 +0200
@@ -50,8 +50,7 @@
      */
     public static enum PhasePosition {
         AFTER_PARSING,
-        HIGH_LEVEL,
-        LOW_LEVEL
+        HIGH_LEVEL
     }
     // @formatter:on
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Tue Jun 11 00:00:40 2013 +0200
@@ -35,8 +35,6 @@
     private static final OptionValue<String> CompilerConfiguration = new OptionValue<>("basic");
     // @formatter:on
 
-    public static final Suites DEFAULT;
-
     private final PhaseSuite<HighTierContext> highTier;
     private final PhaseSuite<MidTierContext> midTier;
     private final PhaseSuite<LowTierContext> lowTier;
@@ -64,8 +62,6 @@
             }
             configurations.put(name.toLowerCase(), config);
         }
-
-        DEFAULT = createDefaultSuites();
     }
 
     private Suites(CompilerConfiguration config) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/SuitesProvider.java	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.tiers;
+
+public interface SuitesProvider {
+
+    /**
+     * Get the default phase suites of this compiler.
+     */
+    Suites getDefaultSuites();
+
+    /**
+     * Create a new set of phase suites. Initially, the suites are the same as the
+     * {@link #getDefaultSuites default} suites.
+     */
+    Suites createSuites();
+}
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java	Tue Jun 11 00:00:40 2013 +0200
@@ -63,7 +63,7 @@
     }
 
     /**
-     * Tests monitor operations on {@link PartialEscapeAnalysisPhase virtual objects}.
+     * Tests monitor operations on {@link PartialEscapePhase virtual objects}.
      */
     @Test
     public void test3() {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,17 +22,20 @@
  */
 package com.oracle.graal.replacements.nodes;
 
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+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.spi.*;
 import com.oracle.graal.phases.common.*;
 
-public class MacroNode extends AbstractStateSplit implements Lowerable {
+public class MacroNode extends AbstractStateSplit implements Lowerable, MemoryCheckpoint {
 
     @Input protected final NodeInputList<ValueNode> arguments;
 
@@ -106,4 +109,9 @@
             }
         }
     }
+
+    @Override
+    public LocationIdentity[] getLocationIdentities() {
+        return new LocationIdentity[]{ANY_LOCATION};
+    }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java	Mon Jun 10 23:59:50 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +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.virtual.phases.ea;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
-import com.oracle.graal.nodes.virtual.*;
-
-public class BlockState {
-
-    protected final IdentityHashMap<VirtualObjectNode, ObjectState> objectStates = new IdentityHashMap<>();
-    protected final IdentityHashMap<ValueNode, VirtualObjectNode> objectAliases;
-    protected final IdentityHashMap<ValueNode, ValueNode> scalarAliases;
-    final HashMap<ReadCacheEntry, ValueNode> readCache;
-
-    static class ReadCacheEntry {
-
-        public final ResolvedJavaField identity;
-        public final ValueNode object;
-
-        public ReadCacheEntry(ResolvedJavaField identity, ValueNode object) {
-            this.identity = identity;
-            this.object = object;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = 31 + ((identity == null) ? 0 : identity.hashCode());
-            return 31 * result + ((object == null) ? 0 : object.hashCode());
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            ReadCacheEntry other = (ReadCacheEntry) obj;
-            return identity == other.identity && object == other.object;
-        }
-
-        @Override
-        public String toString() {
-            return object + ":" + identity;
-        }
-    }
-
-    public BlockState() {
-        objectAliases = new IdentityHashMap<>();
-        scalarAliases = new IdentityHashMap<>();
-        readCache = new HashMap<>();
-    }
-
-    public BlockState(BlockState other) {
-        for (Map.Entry<VirtualObjectNode, ObjectState> entry : other.objectStates.entrySet()) {
-            objectStates.put(entry.getKey(), entry.getValue().cloneState());
-        }
-        objectAliases = new IdentityHashMap<>(other.objectAliases);
-        scalarAliases = new IdentityHashMap<>(other.scalarAliases);
-        readCache = new HashMap<>(other.readCache);
-    }
-
-    public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) {
-        ValueNode cacheObject;
-        ObjectState obj = getObjectState(object);
-        if (obj != null) {
-            assert !obj.isVirtual();
-            cacheObject = obj.getMaterializedValue();
-        } else {
-            cacheObject = object;
-        }
-        readCache.put(new ReadCacheEntry(identity, cacheObject), value);
-    }
-
-    public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) {
-        ValueNode cacheObject;
-        ObjectState obj = getObjectState(object);
-        if (obj != null) {
-            assert !obj.isVirtual();
-            cacheObject = obj.getMaterializedValue();
-        } else {
-            cacheObject = object;
-        }
-        ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject));
-        obj = getObjectState(cacheValue);
-        if (obj != null) {
-            assert !obj.isVirtual();
-            cacheValue = obj.getMaterializedValue();
-        } else {
-            cacheValue = getScalarAlias(cacheValue);
-        }
-        return cacheValue;
-    }
-
-    public void killReadCache() {
-        readCache.clear();
-    }
-
-    public void killReadCache(ResolvedJavaField identity) {
-        Iterator<Map.Entry<ReadCacheEntry, ValueNode>> iter = readCache.entrySet().iterator();
-        while (iter.hasNext()) {
-            Map.Entry<ReadCacheEntry, ValueNode> entry = iter.next();
-            if (entry.getKey().identity == identity) {
-                iter.remove();
-            }
-        }
-    }
-
-    public ObjectState getObjectState(VirtualObjectNode object) {
-        assert objectStates.containsKey(object);
-        return objectStates.get(object);
-    }
-
-    public ObjectState getObjectStateOptional(VirtualObjectNode object) {
-        return objectStates.get(object);
-    }
-
-    public ObjectState getObjectState(ValueNode value) {
-        VirtualObjectNode object = objectAliases.get(value);
-        return object == null ? null : getObjectState(object);
-    }
-
-    public BlockState cloneState() {
-        return new BlockState(this);
-    }
-
-    public BlockState cloneEmptyState() {
-        return new BlockState();
-    }
-
-    public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) {
-        PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment();
-        List<AllocatedObjectNode> objects = new ArrayList<>(2);
-        List<ValueNode> values = new ArrayList<>(8);
-        List<int[]> locks = new ArrayList<>(2);
-        List<ValueNode> otherAllocations = new ArrayList<>(2);
-        materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state);
-
-        materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations);
-    }
-
-    private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List<AllocatedObjectNode> objects, List<int[]> locks, List<ValueNode> values, List<ValueNode> otherAllocations,
-                    EscapeState state) {
-        VirtualUtil.trace("materializing %s", virtual);
-        ObjectState obj = getObjectState(virtual);
-
-        ValueNode[] entries = obj.getEntries();
-        ValueNode representation = virtual.getMaterializedRepresentation(fixed, entries, obj.getLocks());
-        obj.escape(representation, state);
-        if (representation instanceof AllocatedObjectNode) {
-            objects.add((AllocatedObjectNode) representation);
-            locks.add(obj.getLocks());
-            int pos = values.size();
-            while (values.size() < pos + entries.length) {
-                values.add(null);
-            }
-            for (int i = 0; i < entries.length; i++) {
-                ObjectState entryObj = getObjectState(entries[i]);
-                if (entryObj != null) {
-                    if (entryObj.isVirtual()) {
-                        materializeWithCommit(fixed, entryObj.getVirtualObject(), objects, locks, values, otherAllocations, state);
-                    }
-                    values.set(pos + i, entryObj.getMaterializedValue());
-                } else {
-                    values.set(pos + i, entries[i]);
-                }
-            }
-            if (virtual instanceof VirtualInstanceNode) {
-                VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
-                for (int i = 0; i < entries.length; i++) {
-                    readCache.put(new ReadCacheEntry(instance.field(i), representation), values.get(pos + i));
-                }
-            }
-        } else {
-            otherAllocations.add(representation);
-            assert obj.getLocks().length == 0;
-        }
-    }
-
-    void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) {
-        objectAliases.put(node, virtual);
-        if (node.isAlive()) {
-            for (Node usage : node.usages()) {
-                markVirtualUsages(usage, usages);
-            }
-        }
-    }
-
-    private void markVirtualUsages(Node node, NodeBitMap usages) {
-        if (!usages.isNew(node)) {
-            usages.mark(node);
-        }
-        if (node instanceof VirtualState) {
-            for (Node usage : node.usages()) {
-                markVirtualUsages(usage, usages);
-            }
-        }
-    }
-
-    public void addObject(VirtualObjectNode virtual, ObjectState state) {
-        objectStates.put(virtual, state);
-    }
-
-    public void addScalarAlias(ValueNode alias, ValueNode value) {
-        scalarAliases.put(alias, value);
-    }
-
-    public ValueNode getScalarAlias(ValueNode alias) {
-        ValueNode result = scalarAliases.get(alias);
-        return result == null ? alias : result;
-    }
-
-    public Iterable<ObjectState> getStates() {
-        return objectStates.values();
-    }
-
-    public Collection<VirtualObjectNode> getVirtualObjects() {
-        return objectAliases.values();
-    }
-
-    @Override
-    public String toString() {
-        return objectStates + " " + readCache;
-    }
-
-    public void meetAliases(List<? extends BlockState> states) {
-        objectAliases.putAll(states.get(0).objectAliases);
-        scalarAliases.putAll(states.get(0).scalarAliases);
-        for (int i = 1; i < states.size(); i++) {
-            BlockState state = states.get(i);
-            meetMaps(objectAliases, state.objectAliases);
-            meetMaps(scalarAliases, state.scalarAliases);
-        }
-    }
-
-    public Map<ReadCacheEntry, ValueNode> getReadCache() {
-        return readCache;
-    }
-
-    public boolean equivalentTo(BlockState other) {
-        if (this == other) {
-            return true;
-        }
-        boolean objectAliasesEqual = compareMaps(objectAliases, other.objectAliases);
-        boolean objectStatesEqual = compareMaps(objectStates, other.objectStates);
-        boolean readCacheEqual = compareMapsNoSize(readCache, other.readCache);
-        boolean scalarAliasesEqual = scalarAliases.equals(other.scalarAliases);
-        return objectAliasesEqual && objectStatesEqual && readCacheEqual && scalarAliasesEqual;
-    }
-
-    protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
-        if (left.size() != right.size()) {
-            return false;
-        }
-        return compareMapsNoSize(left, right);
-    }
-
-    protected static <K, V> boolean compareMapsNoSize(Map<K, V> left, Map<K, V> right) {
-        if (left == right) {
-            return true;
-        }
-        for (Map.Entry<K, V> entry : right.entrySet()) {
-            K key = entry.getKey();
-            V value = entry.getValue();
-            assert value != null;
-            V otherValue = left.get(key);
-            if (otherValue != value && !value.equals(otherValue)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    protected static <U, V> void meetMaps(Map<U, V> target, Map<U, V> source) {
-        Iterator<Map.Entry<U, V>> iter = target.entrySet().iterator();
-        while (iter.hasNext()) {
-            Map.Entry<U, V> entry = iter.next();
-            if (source.containsKey(entry.getKey())) {
-                assert source.get(entry.getKey()) == entry.getValue();
-            } else {
-                iter.remove();
-            }
-        }
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,105 @@
+/*
+ * 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.virtual.phases.ea;
+
+import java.util.*;
+
+import com.oracle.graal.nodes.*;
+
+public abstract class EffectsBlockState<T extends EffectsBlockState<T>> {
+
+    protected final IdentityHashMap<ValueNode, ValueNode> scalarAliases;
+
+    protected EffectsBlockState() {
+        scalarAliases = new IdentityHashMap<>();
+    }
+
+    protected EffectsBlockState(EffectsBlockState<T> other) {
+        scalarAliases = new IdentityHashMap<>(other.scalarAliases);
+    }
+
+    public void addScalarAlias(ValueNode alias, ValueNode value) {
+        scalarAliases.put(alias, value);
+    }
+
+    public ValueNode getScalarAlias(ValueNode alias) {
+        ValueNode result = scalarAliases.get(alias);
+        return result == null ? alias : result;
+    }
+
+    @Override
+    public String toString() {
+        return "Scalar Aliases: " + scalarAliases.toString();
+    }
+
+    public void meetAliases(List<T> states) {
+        scalarAliases.putAll(states.get(0).scalarAliases);
+        for (int i = 1; i < states.size(); i++) {
+            EffectsBlockState<T> state = states.get(i);
+            meetMaps(scalarAliases, state.scalarAliases);
+        }
+    }
+
+    public boolean equivalentTo(T other) {
+        if (this == other) {
+            return true;
+        }
+        return scalarAliases.equals(other.scalarAliases);
+    }
+
+    protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
+        if (left.size() != right.size()) {
+            return false;
+        }
+        return compareMapsNoSize(left, right);
+    }
+
+    protected static <K, V> boolean compareMapsNoSize(Map<K, V> left, Map<K, V> right) {
+        if (left == right) {
+            return true;
+        }
+        for (Map.Entry<K, V> entry : right.entrySet()) {
+            K key = entry.getKey();
+            V value = entry.getValue();
+            assert value != null;
+            V otherValue = left.get(key);
+            if (otherValue != value && !value.equals(otherValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    protected static <U, V> void meetMaps(Map<U, V> target, Map<U, V> source) {
+        Iterator<Map.Entry<U, V>> iter = target.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry<U, V> entry = iter.next();
+            if (source.containsKey(entry.getKey())) {
+                assert source.get(entry.getKey()) == entry.getValue();
+            } else {
+                iter.remove();
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,203 @@
+/*
+ * 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.virtual.phases.ea;
+
+import java.util.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
+import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo;
+import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.virtual.phases.ea.EffectList.Effect;
+
+public abstract class EffectsClosure<BlockT extends EffectsBlockState<BlockT>> extends EffectsPhase.Closure<BlockT> {
+
+    private final SchedulePhase schedule;
+
+    protected final BlockMap<GraphEffectList> blockEffects;
+    private final IdentityHashMap<Loop, GraphEffectList> loopMergeEffects = new IdentityHashMap<>();
+
+    private boolean changed;
+
+    public EffectsClosure(SchedulePhase schedule) {
+        this.schedule = schedule;
+        this.blockEffects = new BlockMap<>(schedule.getCFG());
+        for (Block block : schedule.getCFG().getBlocks()) {
+            blockEffects.put(block, new GraphEffectList());
+        }
+    }
+
+    @Override
+    public boolean hasChanged() {
+        return changed;
+    }
+
+    @Override
+    public void applyEffects() {
+        final StructuredGraph graph = schedule.getCFG().graph;
+        final ArrayList<Node> obsoleteNodes = new ArrayList<>(0);
+        BlockIteratorClosure<Void> closure = new BlockIteratorClosure<Void>() {
+
+            @Override
+            protected Void getInitialState() {
+                return null;
+            }
+
+            private void apply(GraphEffectList effects, Object context) {
+                if (!effects.isEmpty()) {
+                    Debug.log(" ==== effects for %s", context);
+                    for (Effect effect : effects) {
+                        effect.apply(graph, obsoleteNodes);
+                        if (effect.isVisible()) {
+                            Debug.log("    %s", effect);
+                        }
+                    }
+                }
+            }
+
+            @Override
+            protected Void processBlock(Block block, Void currentState) {
+                apply(blockEffects.get(block), block);
+                Debug.dump(graph, "after processing block %s", block);
+                return currentState;
+            }
+
+            @Override
+            protected Void merge(Block merge, List<Void> states) {
+                return null;
+            }
+
+            @Override
+            protected Void cloneState(Void oldState) {
+                return oldState;
+            }
+
+            @Override
+            protected List<Void> processLoop(Loop loop, Void initialState) {
+                LoopInfo<Void> info = ReentrantBlockIterator.processLoop(this, loop, initialState);
+                apply(loopMergeEffects.get(loop), loop);
+                return info.exitStates;
+            }
+        };
+        ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
+        assert VirtualUtil.assertNonReachable(graph, obsoleteNodes);
+    }
+
+    @Override
+    protected BlockT processBlock(Block block, BlockT state) {
+        VirtualUtil.trace("\nBlock: %s (", block);
+
+        GraphEffectList effects = blockEffects.get(block);
+        FixedWithNextNode lastFixedNode = null;
+        for (Node node : schedule.getBlockToNodesMap().get(block)) {
+            changed |= processNode(node, state, effects, lastFixedNode);
+            if (node instanceof FixedWithNextNode) {
+                lastFixedNode = (FixedWithNextNode) node;
+            }
+        }
+        VirtualUtil.trace(")\n    end state: %s\n", state);
+        return state;
+    }
+
+    protected abstract boolean processNode(Node node, BlockT state, GraphEffectList effects, FixedWithNextNode lastFixedNode);
+
+    @Override
+    protected BlockT merge(Block merge, List<BlockT> states) {
+        assert blockEffects.get(merge).isEmpty();
+        MergeProcessor processor = createMergeProcessor(merge);
+        processor.merge(states);
+        blockEffects.get(merge).addAll(processor.mergeEffects);
+        blockEffects.get(merge).addAll(processor.afterMergeEffects);
+        return processor.newState;
+    }
+
+    @Override
+    protected final List<BlockT> processLoop(Loop loop, BlockT initialState) {
+        BlockT loopEntryState = initialState;
+        BlockT lastMergedState = initialState;
+        MergeProcessor mergeProcessor = createMergeProcessor(loop.header);
+        for (int iteration = 0; iteration < 10; iteration++) {
+            LoopInfo<BlockT> info = ReentrantBlockIterator.processLoop(this, loop, cloneState(lastMergedState));
+
+            List<BlockT> states = new ArrayList<>();
+            states.add(initialState);
+            states.addAll(info.endStates);
+            mergeProcessor.merge(states);
+
+            Debug.log("================== %s", loop.header);
+            Debug.log("%s", mergeProcessor.newState);
+            Debug.log("===== vs.");
+            Debug.log("%s", lastMergedState);
+
+            if (mergeProcessor.newState.equivalentTo(lastMergedState)) {
+                blockEffects.get(loop.header).insertAll(mergeProcessor.mergeEffects, 0);
+                loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects);
+
+                assert info.exitStates.size() == loop.exits.size();
+                for (int i = 0; i < loop.exits.size(); i++) {
+                    BlockT exitState = info.exitStates.get(i);
+                    assert exitState != null : "no loop exit state at " + loop.exits.get(i) + " / " + loop.header;
+                    processLoopExit((LoopExitNode) loop.exits.get(i).getBeginNode(), loopEntryState, exitState, blockEffects.get(loop.exits.get(i)));
+                }
+
+                return info.exitStates;
+            } else {
+                lastMergedState = mergeProcessor.newState;
+                for (Block block : loop.blocks) {
+                    blockEffects.get(block).clear();
+                }
+            }
+        }
+        throw new GraalInternalError("too many iterations at %s", loop);
+    }
+
+    protected abstract void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects);
+
+    protected abstract MergeProcessor createMergeProcessor(Block merge);
+
+    protected class MergeProcessor {
+
+        protected final Block mergeBlock;
+        protected final MergeNode merge;
+
+        protected final GraphEffectList mergeEffects;
+        protected final GraphEffectList afterMergeEffects;
+        protected BlockT newState;
+
+        public MergeProcessor(Block mergeBlock) {
+            this.mergeBlock = mergeBlock;
+            this.merge = (MergeNode) mergeBlock.getBeginNode();
+            this.mergeEffects = new GraphEffectList();
+            this.afterMergeEffects = new GraphEffectList();
+        }
+
+        protected void merge(List<BlockT> states) {
+            newState = getInitialState();
+            newState.meetAliases(states);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,98 @@
+/*
+ * 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.virtual.phases.ea;
+
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import java.util.concurrent.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.tiers.*;
+
+public abstract class EffectsPhase<PhaseContextT extends PhaseContext> extends BasePhase<PhaseContextT> {
+
+    public abstract static class Closure<T> extends ReentrantBlockIterator.BlockIteratorClosure<T> {
+
+        public abstract boolean hasChanged();
+
+        public abstract void applyEffects();
+    }
+
+    private final int maxIterations;
+    private CanonicalizerPhase canonicalizer;
+
+    public EffectsPhase(int maxIterations, CanonicalizerPhase canonicalizer) {
+        this.maxIterations = maxIterations;
+        this.canonicalizer = canonicalizer;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph, PhaseContextT context) {
+        runAnalysis(graph, context);
+    }
+
+    public boolean runAnalysis(final StructuredGraph graph, final PhaseContextT context) {
+        boolean changed = false;
+        for (int iteration = 0; iteration < maxIterations; iteration++) {
+            boolean currentChanged = Debug.scope("iteration " + iteration, new Callable<Boolean>() {
+
+                @Override
+                public Boolean call() {
+                    SchedulePhase schedule = new SchedulePhase();
+                    schedule.apply(graph, false);
+                    Closure<?> closure = createEffectsClosure(context, schedule);
+                    ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
+
+                    if (!closure.hasChanged()) {
+                        return false;
+                    }
+
+                    // apply the effects collected during this iteration
+                    closure.applyEffects();
+
+                    Debug.dump(graph, "after " + getName() + " iteration");
+
+                    new DeadCodeEliminationPhase().apply(graph);
+
+                    if (OptCanonicalizer.getValue()) {
+                        canonicalizer.apply(graph, context);
+                    }
+
+                    return true;
+                }
+            });
+            if (!currentChanged) {
+                break;
+            }
+            changed |= currentChanged;
+        }
+        return changed;
+    }
+
+    protected abstract Closure<?> createEffectsClosure(PhaseContextT context, SchedulePhase schedule);
+}
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -38,18 +38,14 @@
 
     private final PhasePlan plan;
 
-    private final Replacements replacements;
     private final GraphCache cache;
     private final OptimisticOptimizations optimisticOpts;
-    private final boolean readElimination;
     private final CanonicalizerPhase canonicalizer;
 
-    public IterativeInliningPhase(Replacements replacements, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, boolean readElimination, CanonicalizerPhase canonicalizer) {
-        this.replacements = replacements;
+    public IterativeInliningPhase(GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, CanonicalizerPhase canonicalizer) {
         this.cache = cache;
         this.plan = plan;
         this.optimisticOpts = optimisticOpts;
-        this.readElimination = readElimination;
         this.canonicalizer = canonicalizer;
     }
 
@@ -73,13 +69,13 @@
                 @Override
                 public Boolean call() {
                     boolean progress = false;
-                    PartialEscapeAnalysisPhase ea = new PartialEscapeAnalysisPhase(false, readElimination, canonicalizer);
+                    PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer);
                     boolean eaResult = ea.runAnalysis(graph, context);
                     progress |= eaResult;
 
-                    Map<Invoke, Double> hints = PEAInliningHints.getValue() ? PartialEscapeAnalysisPhase.getHints(graph) : null;
+                    Map<Invoke, Double> hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null;
 
-                    InliningPhase inlining = new InliningPhase(context.getRuntime(), hints, replacements, context.getAssumptions(), cache, plan, optimisticOpts);
+                    InliningPhase inlining = new InliningPhase(context.getRuntime(), hints, context.getReplacements(), context.getAssumptions(), cache, plan, optimisticOpts);
                     inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE);
                     inlining.apply(graph);
                     progress |= inlining.getInliningCount() > 0;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Tue Jun 11 00:00:40 2013 +0200
@@ -34,7 +34,7 @@
  * the fields or array elements (called "entries") and the lock count if the object is still
  * virtual. If the object was materialized, it contains the current materialized value.
  */
-class ObjectState extends Virtualizable.State {
+public class ObjectState extends Virtualizable.State {
 
     private static final int[] EMPTY_INT_ARRAY = new int[0];
 
@@ -131,7 +131,6 @@
         return entries[index];
     }
 
-    @Override
     public void setEntry(int index, ValueNode value) {
         assert isVirtual();
         entries[index] = value;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java	Mon Jun 10 23:59:50 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +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.virtual.phases.ea;
-
-import static com.oracle.graal.phases.GraalOptions.*;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.graph.*;
-import com.oracle.graal.phases.schedule.*;
-import com.oracle.graal.phases.tiers.*;
-
-public class PartialEscapeAnalysisPhase extends BasePhase<PhaseContext> {
-
-    public abstract static class Closure<T> extends ReentrantBlockIterator.BlockIteratorClosure<T> {
-
-        public abstract boolean hasChanged();
-
-        public abstract void applyEffects();
-    }
-
-    private final boolean iterative;
-    private final boolean readElimination;
-    private final CanonicalizerPhase canonicalizer;
-
-    public PartialEscapeAnalysisPhase(boolean iterative, boolean readElimination, CanonicalizerPhase canonicalizer) {
-        this.iterative = iterative;
-        this.readElimination = readElimination;
-        this.canonicalizer = canonicalizer;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph, PhaseContext context) {
-        runAnalysis(graph, context);
-    }
-
-    public boolean runAnalysis(final StructuredGraph graph, final PhaseContext context) {
-        if (!VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue())) {
-            return false;
-        }
-
-        if (!readElimination) {
-            boolean analyzableNodes = false;
-            for (Node node : graph.getNodes()) {
-                if (node instanceof VirtualizableAllocation) {
-                    analyzableNodes = true;
-                    break;
-                }
-            }
-            if (!analyzableNodes) {
-                return false;
-            }
-        }
-
-        boolean continueIteration = true;
-        boolean changed = false;
-        for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) {
-            boolean currentChanged = Debug.scope("iteration " + iteration, new Callable<Boolean>() {
-
-                @Override
-                public Boolean call() {
-
-                    SchedulePhase schedule = new SchedulePhase();
-                    schedule.apply(graph, false);
-                    Closure<?> closure = createAnalysisClosure(context, schedule);
-                    ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
-
-                    if (!closure.hasChanged()) {
-                        return false;
-                    }
-
-                    // apply the effects collected during the escape analysis iteration
-                    closure.applyEffects();
-
-                    Debug.dump(graph, "after PartialEscapeAnalysis iteration");
-
-                    new DeadCodeEliminationPhase().apply(graph);
-
-                    if (OptCanonicalizer.getValue()) {
-                        canonicalizer.apply(graph, context);
-                    }
-
-                    return true;
-                }
-            });
-            continueIteration = currentChanged && iterative;
-            changed |= currentChanged;
-        }
-
-        return changed;
-    }
-
-    protected Closure<?> createAnalysisClosure(PhaseContext context, SchedulePhase schedule) {
-        return new PartialEscapeClosure<>(schedule, context.getRuntime(), context.getAssumptions());
-    }
-
-    public static Map<Invoke, Double> getHints(StructuredGraph graph) {
-        NodesToDoubles probabilities = new ComputeProbabilityClosure(graph).apply();
-        Map<Invoke, Double> hints = null;
-        for (CommitAllocationNode commit : graph.getNodes(CommitAllocationNode.class)) {
-            double sum = 0;
-            double invokeSum = 0;
-            for (Node commitUsage : commit.usages()) {
-                for (Node usage : commitUsage.usages()) {
-                    if (usage instanceof FixedNode) {
-                        sum += probabilities.get((FixedNode) usage);
-                    } else {
-                        if (usage instanceof MethodCallTargetNode) {
-                            invokeSum += probabilities.get(((MethodCallTargetNode) usage).invoke().asNode());
-                        }
-                        for (Node secondLevelUage : usage.usages()) {
-                            if (secondLevelUage instanceof FixedNode) {
-                                sum += probabilities.get(((FixedNode) secondLevelUage));
-                            }
-                        }
-                    }
-                }
-            }
-            // TODO(lstadler) get rid of this magic number
-            if (sum > 100 && invokeSum > 0) {
-                for (Node commitUsage : commit.usages()) {
-                    for (Node usage : commitUsage.usages()) {
-                        if (usage instanceof MethodCallTargetNode) {
-                            if (hints == null) {
-                                hints = new HashMap<>();
-                            }
-                            Invoke invoke = ((MethodCallTargetNode) usage).invoke();
-                            hints.put(invoke, sum / invokeSum);
-                        }
-                    }
-                }
-            }
-        }
-        return hints;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,214 @@
+/*
+ * 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.virtual.phases.ea;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
+import com.oracle.graal.nodes.virtual.*;
+
+public abstract class PartialEscapeBlockState<T extends PartialEscapeBlockState<T>> extends EffectsBlockState<T> {
+
+    protected final IdentityHashMap<VirtualObjectNode, ObjectState> objectStates = new IdentityHashMap<>();
+    protected final IdentityHashMap<ValueNode, VirtualObjectNode> objectAliases;
+
+    /**
+     * Final subclass of PartialEscapeBlockState, for performance and to make everything behave
+     * nicely with generics.
+     */
+    public static final class Final extends PartialEscapeBlockState<Final> {
+
+        public Final() {
+        }
+
+        public Final(Final other) {
+            super(other);
+        }
+    }
+
+    protected PartialEscapeBlockState() {
+        objectAliases = new IdentityHashMap<>();
+    }
+
+    protected PartialEscapeBlockState(PartialEscapeBlockState<T> other) {
+        super(other);
+        for (Map.Entry<VirtualObjectNode, ObjectState> entry : other.objectStates.entrySet()) {
+            objectStates.put(entry.getKey(), entry.getValue().cloneState());
+        }
+        objectAliases = new IdentityHashMap<>(other.objectAliases);
+    }
+
+    public ObjectState getObjectState(VirtualObjectNode object) {
+        assert objectStates.containsKey(object);
+        return objectStates.get(object);
+    }
+
+    public ObjectState getObjectStateOptional(VirtualObjectNode object) {
+        return objectStates.get(object);
+    }
+
+    public ObjectState getObjectState(ValueNode value) {
+        VirtualObjectNode object = objectAliases.get(value);
+        return object == null ? null : getObjectState(object);
+    }
+
+    public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) {
+        PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment();
+        List<AllocatedObjectNode> objects = new ArrayList<>(2);
+        List<ValueNode> values = new ArrayList<>(8);
+        List<int[]> locks = new ArrayList<>(2);
+        List<ValueNode> otherAllocations = new ArrayList<>(2);
+        materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state);
+
+        materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations);
+    }
+
+    private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List<AllocatedObjectNode> objects, List<int[]> locks, List<ValueNode> values, List<ValueNode> otherAllocations,
+                    EscapeState state) {
+        ObjectState obj = getObjectState(virtual);
+
+        ValueNode[] entries = obj.getEntries();
+        ValueNode representation = virtual.getMaterializedRepresentation(fixed, entries, obj.getLocks());
+        obj.escape(representation, state);
+        if (representation instanceof AllocatedObjectNode) {
+            objects.add((AllocatedObjectNode) representation);
+            locks.add(obj.getLocks());
+            int pos = values.size();
+            while (values.size() < pos + entries.length) {
+                values.add(null);
+            }
+            for (int i = 0; i < entries.length; i++) {
+                ObjectState entryObj = getObjectState(entries[i]);
+                if (entryObj != null) {
+                    if (entryObj.isVirtual()) {
+                        materializeWithCommit(fixed, entryObj.getVirtualObject(), objects, locks, values, otherAllocations, state);
+                    }
+                    values.set(pos + i, entryObj.getMaterializedValue());
+                } else {
+                    values.set(pos + i, entries[i]);
+                }
+            }
+            objectMaterialized(virtual, (AllocatedObjectNode) representation, values.subList(pos, pos + entries.length));
+        } else {
+            VirtualUtil.trace("materialized %s as %s", virtual, representation);
+            otherAllocations.add(representation);
+            assert obj.getLocks().length == 0;
+        }
+    }
+
+    protected void objectMaterialized(VirtualObjectNode virtual, AllocatedObjectNode representation, List<ValueNode> values) {
+        VirtualUtil.trace("materialized %s as %s with values %s", virtual, representation, values);
+    }
+
+    void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) {
+        objectAliases.put(node, virtual);
+        if (node.isAlive()) {
+            for (Node usage : node.usages()) {
+                markVirtualUsages(usage, usages);
+            }
+        }
+    }
+
+    private void markVirtualUsages(Node node, NodeBitMap usages) {
+        if (!usages.isNew(node)) {
+            usages.mark(node);
+        }
+        if (node instanceof VirtualState) {
+            for (Node usage : node.usages()) {
+                markVirtualUsages(usage, usages);
+            }
+        }
+    }
+
+    public void addObject(VirtualObjectNode virtual, ObjectState state) {
+        objectStates.put(virtual, state);
+    }
+
+    public Iterable<ObjectState> getStates() {
+        return objectStates.values();
+    }
+
+    public Collection<VirtualObjectNode> getVirtualObjects() {
+        return objectAliases.values();
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + ", Object Aliases: " + objectAliases + ", Object States: " + objectStates;
+    }
+
+    @Override
+    public void meetAliases(List<T> states) {
+        super.meetAliases(states);
+        objectAliases.putAll(states.get(0).objectAliases);
+        for (int i = 1; i < states.size(); i++) {
+            meetMaps(objectAliases, states.get(i).objectAliases);
+        }
+    }
+
+    @Override
+    public boolean equivalentTo(T other) {
+        if (!compareMaps(objectAliases, other.objectAliases) || !compareMaps(objectStates, other.objectStates)) {
+            return false;
+        }
+        return super.equivalentTo(other);
+    }
+
+    protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
+        if (left.size() != right.size()) {
+            return false;
+        }
+        return compareMapsNoSize(left, right);
+    }
+
+    protected static <K, V> boolean compareMapsNoSize(Map<K, V> left, Map<K, V> right) {
+        if (left == right) {
+            return true;
+        }
+        for (Map.Entry<K, V> entry : right.entrySet()) {
+            K key = entry.getKey();
+            V value = entry.getValue();
+            assert value != null;
+            V otherValue = left.get(key);
+            if (otherValue != value && !value.equals(otherValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    protected static <U, V> void meetMaps(Map<U, V> target, Map<U, V> source) {
+        Iterator<Map.Entry<U, V>> iter = target.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry<U, V> entry = iter.next();
+            if (source.containsKey(entry.getKey())) {
+                assert source.get(entry.getKey()) == entry.getValue();
+            } else {
+                iter.remove();
+            }
+        }
+    }
+
+}
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Tue Jun 11 00:00:40 2013 +0200
@@ -22,9 +22,6 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
-import static com.oracle.graal.api.meta.LocationIdentity.*;
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -35,20 +32,14 @@
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.VirtualState.NodeClosure;
 import com.oracle.graal.nodes.cfg.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.graph.*;
-import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
-import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.virtual.nodes.*;
-import com.oracle.graal.virtual.phases.ea.BlockState.ReadCacheEntry;
-import com.oracle.graal.virtual.phases.ea.EffectList.Effect;
 
-public class PartialEscapeClosure<BlockT extends BlockState> extends PartialEscapeAnalysisPhase.Closure<BlockT> {
+public abstract class PartialEscapeClosure<BlockT extends PartialEscapeBlockState<BlockT>> extends EffectsClosure<BlockT> {
 
     public static final DebugMetric METRIC_MATERIALIZATIONS = Debug.metric("Materializations");
     public static final DebugMetric METRIC_MATERIALIZATIONS_PHI = Debug.metric("MaterializationsPhi");
@@ -61,143 +52,63 @@
     public static final DebugMetric METRIC_MEMORYCHECKOINT = Debug.metric("MemoryCheckpoint");
 
     private final NodeBitMap usages;
-    private final SchedulePhase schedule;
-
-    private final BlockMap<GraphEffectList> blockEffects;
-    private final IdentityHashMap<Loop, GraphEffectList> loopMergeEffects = new IdentityHashMap<>();
-
     private final VirtualizerToolImpl tool;
-
     private final Map<Invoke, Double> hints = new IdentityHashMap<>();
 
-    private boolean changed;
+    /**
+     * Final subclass of PartialEscapeClosure, for performance and to make everything behave nicely
+     * with generics.
+     */
+    public static final class Final extends PartialEscapeClosure<PartialEscapeBlockState.Final> {
 
-    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
-        this.usages = schedule.getCFG().graph.createNodeBitMap();
-        this.schedule = schedule;
-        this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions);
-        this.blockEffects = new BlockMap<>(schedule.getCFG());
-        for (Block block : schedule.getCFG().getBlocks()) {
-            blockEffects.put(block, new GraphEffectList());
+        public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
+            super(schedule, metaAccess, assumptions);
+        }
+
+        @Override
+        protected PartialEscapeBlockState.Final getInitialState() {
+            return new PartialEscapeBlockState.Final();
+        }
+
+        @Override
+        protected PartialEscapeBlockState.Final cloneState(PartialEscapeBlockState.Final oldState) {
+            return new PartialEscapeBlockState.Final(oldState);
         }
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    protected BlockT getInitialState() {
-        return (BlockT) new BlockState();
-    }
-
-    @Override
-    public boolean hasChanged() {
-        return changed;
-    }
-
-    @Override
-    public void applyEffects() {
-        final StructuredGraph graph = schedule.getCFG().graph;
-        final ArrayList<Node> obsoleteNodes = new ArrayList<>(0);
-        BlockIteratorClosure<Void> closure = new BlockIteratorClosure<Void>() {
-
-            @Override
-            protected Void getInitialState() {
-                return null;
-            }
-
-            private void apply(GraphEffectList effects, Object context) {
-                if (!effects.isEmpty()) {
-                    Debug.log(" ==== effects for %s", context);
-                    for (Effect effect : effects) {
-                        effect.apply(graph, obsoleteNodes);
-                        if (effect.isVisible()) {
-                            Debug.log("    %s", effect);
-                        }
-                    }
-                }
-            }
-
-            @Override
-            protected Void processBlock(Block block, Void currentState) {
-                apply(blockEffects.get(block), block);
-                return currentState;
-            }
-
-            @Override
-            protected Void merge(Block merge, List<Void> states) {
-                return null;
-            }
-
-            @Override
-            protected Void cloneState(Void oldState) {
-                return oldState;
-            }
-
-            @Override
-            protected List<Void> processLoop(Loop loop, Void initialState) {
-                LoopInfo<Void> info = ReentrantBlockIterator.processLoop(this, loop, initialState);
-                apply(loopMergeEffects.get(loop), loop);
-                return info.exitStates;
-            }
-        };
-        ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
-        assert VirtualUtil.assertNonReachable(graph, obsoleteNodes);
+    public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
+        super(schedule);
+        this.usages = schedule.getCFG().graph.createNodeBitMap();
+        this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions);
     }
 
     public Map<Invoke, Double> getHints() {
         return hints;
     }
 
+    /**
+     * @return true if the node was deleted, false otherwise
+     */
     @Override
-    protected BlockT processBlock(Block block, BlockT state) {
-        GraphEffectList effects = blockEffects.get(block);
-        tool.setEffects(effects);
-
-        VirtualUtil.trace("\nBlock: %s (", block);
-        List<ScheduledNode> nodeList = schedule.getBlockToNodesMap().get(block);
-
-        FixedWithNextNode lastFixedNode = null;
-        for (Node node : nodeList) {
-            boolean deleted;
-            boolean isMarked = usages.isMarked(node);
-            if (isMarked || node instanceof VirtualizableRoot) {
-                VirtualUtil.trace("[[%s]] ", node);
-                FixedNode nextFixedNode = lastFixedNode == null ? null : lastFixedNode.next();
-                deleted = processNode((ValueNode) node, nextFixedNode, state, effects, isMarked);
-            } else {
-                VirtualUtil.trace("%s ", node);
-                deleted = false;
-            }
-            if (OptEarlyReadElimination.getValue()) {
-                if (!deleted && node instanceof MemoryCheckpoint) {
-                    METRIC_MEMORYCHECKOINT.increment();
-                    MemoryCheckpoint checkpoint = (MemoryCheckpoint) node;
-                    for (LocationIdentity identity : checkpoint.getLocationIdentities()) {
-                        if (identity instanceof ResolvedJavaField) {
-                            state.killReadCache((ResolvedJavaField) identity);
-                        } else if (identity == ANY_LOCATION) {
-                            state.killReadCache();
-                        }
-                    }
-                }
-            }
-            if (node instanceof FixedWithNextNode) {
-                lastFixedNode = (FixedWithNextNode) node;
-            }
+    protected boolean processNode(Node node, BlockT state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
+        boolean isMarked = usages.isMarked(node);
+        if (isMarked || node instanceof VirtualizableRoot) {
+            VirtualUtil.trace("[[%s]] ", node);
+            FixedNode nextFixedNode = lastFixedNode == null ? null : lastFixedNode.next();
+            return processNode((ValueNode) node, nextFixedNode, state, effects, isMarked);
+        } else {
+            VirtualUtil.trace("%s ", node);
+            return false;
         }
-        VirtualUtil.trace(")\n    end state: %s\n", state);
-        return state;
     }
 
     private boolean processNode(final ValueNode node, FixedNode insertBefore, final BlockT state, final GraphEffectList effects, boolean isMarked) {
-        tool.reset(state, node, insertBefore);
+        tool.reset(state, node, insertBefore, effects);
         if (node instanceof Virtualizable) {
             ((Virtualizable) node).virtualize(tool);
         }
         if (tool.isDeleted()) {
-            if (!(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode)) {
-                changed = true;
-            }
-            return true;
+            return !(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode);
         }
         if (isMarked) {
             if (node instanceof StateSplit) {
@@ -289,7 +200,7 @@
         return false;
     }
 
-    private static void ensureMaterialized(BlockState state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
+    private static void ensureMaterialized(PartialEscapeBlockState state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
         assert obj != null;
         if (obj.getState() == EscapeState.Virtual) {
             metric.increment();
@@ -300,70 +211,13 @@
         assert !obj.isVirtual();
     }
 
-    private static void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockState state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
+    private static void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, PartialEscapeBlockState state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
         ensureMaterialized(state, obj, materializeBefore, effects, metric);
         effects.replaceFirstInput(usage, value, obj.getMaterializedValue());
     }
 
     @Override
-    protected BlockT merge(Block merge, List<BlockT> states) {
-        assert blockEffects.get(merge).isEmpty();
-        MergeProcessor<BlockT> processor = new MergeProcessor<>(merge, usages, blockEffects);
-        processor.merge(states);
-        blockEffects.get(merge).addAll(processor.mergeEffects);
-        blockEffects.get(merge).addAll(processor.afterMergeEffects);
-        return processor.newState;
-
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected BlockT cloneState(BlockState oldState) {
-        return (BlockT) oldState.cloneState();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    protected List<BlockT> processLoop(Loop loop, BlockT initialState) {
-        BlockState loopEntryState = initialState;
-        BlockState lastMergedState = initialState;
-        MergeProcessor<BlockT> mergeProcessor = new MergeProcessor<>(loop.header, usages, blockEffects);
-        for (int iteration = 0; iteration < 10; iteration++) {
-            LoopInfo<BlockT> info = ReentrantBlockIterator.processLoop(this, loop, (BlockT) lastMergedState.cloneState());
-
-            List<BlockT> states = new ArrayList<>();
-            states.add(initialState);
-            states.addAll(info.endStates);
-            mergeProcessor.merge(states);
-
-            Debug.log("================== %s", loop.header);
-            Debug.log("%s", mergeProcessor.newState);
-            Debug.log("===== vs.");
-            Debug.log("%s", lastMergedState);
-
-            if (mergeProcessor.newState.equivalentTo(lastMergedState)) {
-                blockEffects.get(loop.header).insertAll(mergeProcessor.mergeEffects, 0);
-                loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects);
-
-                assert info.exitStates.size() == loop.exits.size();
-                for (int i = 0; i < loop.exits.size(); i++) {
-                    BlockState exitState = info.exitStates.get(i);
-                    assert exitState != null : "no loop exit state at " + loop.exits.get(i) + " / " + loop.header;
-                    processLoopExit((LoopExitNode) loop.exits.get(i).getBeginNode(), loopEntryState, exitState, blockEffects.get(loop.exits.get(i)));
-                }
-
-                return info.exitStates;
-            } else {
-                lastMergedState = mergeProcessor.newState;
-                for (Block block : loop.blocks) {
-                    blockEffects.get(block).clear();
-                }
-            }
-        }
-        throw new GraalInternalError("too many iterations at %s", loop);
-    }
-
-    private static void processLoopExit(LoopExitNode exitNode, BlockState initialState, BlockState exitState, GraphEffectList effects) {
+    protected void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects) {
         HashMap<VirtualObjectNode, ProxyNode> proxies = new HashMap<>();
 
         for (ProxyNode proxy : exitNode.proxies()) {
@@ -404,41 +258,25 @@
                 }
             }
         }
-
-        for (Map.Entry<ReadCacheEntry, ValueNode> entry : exitState.getReadCache().entrySet()) {
-            if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) {
-                ProxyNode proxy = new ProxyNode(exitState.getReadCache(entry.getKey().object, entry.getKey().identity), exitNode, PhiType.Value, null);
-                effects.addFloatingNode(proxy, "readCacheProxy");
-                entry.setValue(proxy);
-            }
-        }
     }
 
-    private static class MergeProcessor<BlockT extends BlockState> {
+    @Override
+    protected MergeProcessor createMergeProcessor(Block merge) {
+        return new MergeProcessor(merge);
+    }
 
-        private final Block mergeBlock;
-        private final MergeNode merge;
-        private final NodeBitMap usages;
-        private final BlockMap<GraphEffectList> blockEffects;
-        private final GraphEffectList mergeEffects;
-        private final GraphEffectList afterMergeEffects;
+    protected class MergeProcessor extends EffectsClosure<BlockT>.MergeProcessor {
 
         private final HashMap<Object, PhiNode> materializedPhis = new HashMap<>();
         private final IdentityHashMap<VirtualObjectNode, PhiNode[]> valuePhis = new IdentityHashMap<>();
         private final IdentityHashMap<PhiNode, PhiNode[]> valueObjectMergePhis = new IdentityHashMap<>();
         private final IdentityHashMap<PhiNode, VirtualObjectNode> valueObjectVirtuals = new IdentityHashMap<>();
-        private BlockT newState;
 
-        public MergeProcessor(Block mergeBlock, NodeBitMap usages, BlockMap<GraphEffectList> blockEffects) {
-            this.usages = usages;
-            this.mergeBlock = mergeBlock;
-            this.blockEffects = blockEffects;
-            this.merge = (MergeNode) mergeBlock.getBeginNode();
-            this.mergeEffects = new GraphEffectList();
-            this.afterMergeEffects = new GraphEffectList();
+        public MergeProcessor(Block mergeBlock) {
+            super(mergeBlock);
         }
 
-        private <T> PhiNode getCachedPhi(T virtual, Kind kind) {
+        protected <T> PhiNode getCachedPhi(T virtual, Kind kind) {
             PhiNode result = materializedPhis.get(virtual);
             if (result == null) {
                 result = new PhiNode(kind, merge);
@@ -474,10 +312,9 @@
             return result;
         }
 
-        @SuppressWarnings("unchecked")
-        private void merge(List<BlockT> states) {
-            newState = (BlockT) states.get(0).cloneEmptyState();
-            newState.meetAliases(states);
+        @Override
+        protected void merge(List<BlockT> states) {
+            super.merge(states);
 
             /*
              * Iterative processing: Merging the materialized/virtual state of virtual objects can
@@ -519,7 +356,7 @@
                             PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object);
                             mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi");
                             for (int i = 0; i < states.size(); i++) {
-                                BlockState state = states.get(i);
+                                PartialEscapeBlockState state = states.get(i);
                                 ObjectState obj = objStates[i];
                                 materialized |= obj.isVirtual();
                                 Block predecessor = mergeBlock.getPredecessors().get(i);
@@ -578,8 +415,6 @@
                     }
                 }
             } while (materialized);
-
-            mergeReadCache(states);
         }
 
         private boolean processPhi(PhiNode phi, List<BlockT> states) {
@@ -665,62 +500,5 @@
             }
             return materialized;
         }
-
-        private void mergeReadCache(List<BlockT> states) {
-            for (Map.Entry<ReadCacheEntry, ValueNode> entry : states.get(0).readCache.entrySet()) {
-                ReadCacheEntry key = entry.getKey();
-                ValueNode value = entry.getValue();
-                boolean phi = false;
-                for (int i = 1; i < states.size(); i++) {
-                    ValueNode otherValue = states.get(i).readCache.get(key);
-                    if (otherValue == null) {
-                        value = null;
-                        phi = false;
-                        break;
-                    }
-                    if (!phi && otherValue != value) {
-                        phi = true;
-                    }
-                }
-                if (phi) {
-                    PhiNode phiNode = getCachedPhi(entry, value.kind());
-                    mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
-                    for (int i = 0; i < states.size(); i++) {
-                        afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity));
-                    }
-                    newState.readCache.put(key, phiNode);
-                } else if (value != null) {
-                    newState.readCache.put(key, value);
-                }
-            }
-            for (PhiNode phi : merge.phis()) {
-                if (phi.kind() == Kind.Object) {
-                    for (Map.Entry<ReadCacheEntry, ValueNode> entry : states.get(0).readCache.entrySet()) {
-                        if (entry.getKey().object == phi.valueAt(0)) {
-                            mergeReadCachePhi(phi, entry.getKey().identity, states);
-                        }
-                    }
-
-                }
-            }
-        }
-
-        private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List<BlockT> states) {
-            ValueNode[] values = new ValueNode[phi.valueCount()];
-            for (int i = 0; i < phi.valueCount(); i++) {
-                ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity);
-                if (value == null) {
-                    return;
-                }
-                values[i] = value;
-            }
-
-            PhiNode phiNode = getCachedPhi(new ReadCacheEntry(identity, phi), values[0].kind());
-            mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi");
-            for (int i = 0; i < values.length; i++) {
-                afterMergeEffects.addPhiInput(phiNode, values[i]);
-            }
-            newState.readCache.put(new ReadCacheEntry(identity, phi), phiNode);
-        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,106 @@
+/*
+ * 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.virtual.phases.ea;
+
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import java.util.*;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.graph.*;
+import com.oracle.graal.phases.schedule.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class PartialEscapePhase extends EffectsPhase<PhaseContext> {
+
+    public PartialEscapePhase(boolean iterative, CanonicalizerPhase canonicalizer) {
+        super(iterative ? EscapeAnalysisIterations.getValue() : 1, canonicalizer);
+    }
+
+    @Override
+    protected void run(StructuredGraph graph, PhaseContext context) {
+        if (VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue())) {
+            boolean analyzableNodes = false;
+            for (Node node : graph.getNodes()) {
+                if (node instanceof VirtualizableAllocation) {
+                    analyzableNodes = true;
+                    break;
+                }
+            }
+            if (analyzableNodes) {
+                runAnalysis(graph, context);
+            }
+        }
+    }
+
+    @Override
+    protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule) {
+        return new PartialEscapeClosure.Final(schedule, context.getRuntime(), context.getAssumptions());
+    }
+
+    public static Map<Invoke, Double> getHints(StructuredGraph graph) {
+        NodesToDoubles probabilities = new ComputeProbabilityClosure(graph).apply();
+        Map<Invoke, Double> hints = null;
+        for (CommitAllocationNode commit : graph.getNodes(CommitAllocationNode.class)) {
+            double sum = 0;
+            double invokeSum = 0;
+            for (Node commitUsage : commit.usages()) {
+                for (Node usage : commitUsage.usages()) {
+                    if (usage instanceof FixedNode) {
+                        sum += probabilities.get((FixedNode) usage);
+                    } else {
+                        if (usage instanceof MethodCallTargetNode) {
+                            invokeSum += probabilities.get(((MethodCallTargetNode) usage).invoke().asNode());
+                        }
+                        for (Node secondLevelUage : usage.usages()) {
+                            if (secondLevelUage instanceof FixedNode) {
+                                sum += probabilities.get(((FixedNode) secondLevelUage));
+                            }
+                        }
+                    }
+                }
+            }
+            // TODO(lstadler) get rid of this magic number
+            if (sum > 100 && invokeSum > 0) {
+                for (Node commitUsage : commit.usages()) {
+                    for (Node usage : commitUsage.usages()) {
+                        if (usage instanceof MethodCallTargetNode) {
+                            if (hints == null) {
+                                hints = new HashMap<>();
+                            }
+                            Invoke invoke = ((MethodCallTargetNode) usage).invoke();
+                            hints.put(invoke, sum / invokeSum);
+                        }
+                    }
+                }
+            }
+        }
+        return hints;
+    }
+}
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Tue Jun 11 00:00:40 2013 +0200
@@ -111,7 +111,7 @@
         }
     }
 
-    static boolean matches(StructuredGraph graph, String filter) {
+    public static boolean matches(StructuredGraph graph, String filter) {
         if (filter != null) {
             if (filter.startsWith("~")) {
                 ResolvedJavaMethod method = graph.method();
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Tue Jun 11 00:00:40 2013 +0200
@@ -39,7 +39,6 @@
     private final NodeBitMap usages;
     private final MetaAccessProvider metaAccess;
     private final Assumptions assumptions;
-    private GraphEffectList effects;
 
     VirtualizerToolImpl(NodeBitMap usages, MetaAccessProvider metaAccess, Assumptions assumptions) {
         this.usages = usages;
@@ -48,9 +47,10 @@
     }
 
     private boolean deleted;
-    private BlockState state;
+    private PartialEscapeBlockState state;
     private ValueNode current;
     private FixedNode position;
+    private GraphEffectList effects;
 
     @Override
     public MetaAccessProvider getMetaAccessProvider() {
@@ -62,15 +62,12 @@
         return assumptions;
     }
 
-    public void setEffects(GraphEffectList effects) {
-        this.effects = effects;
-    }
-
-    public void reset(BlockState newState, ValueNode newCurrent, FixedNode newPosition) {
+    public void reset(PartialEscapeBlockState newState, ValueNode newCurrent, FixedNode newPosition, GraphEffectList newEffects) {
         deleted = false;
         state = newState;
         current = newCurrent;
         position = newPosition;
+        effects = newEffects;
     }
 
     public boolean isDeleted() {
@@ -87,16 +84,24 @@
         ObjectState obj = (ObjectState) objectState;
         assert obj != null && obj.isVirtual() : "not virtual: " + obj;
         ObjectState valueState = state.getObjectState(value);
+        ValueNode newValue = value;
         if (valueState == null) {
-            obj.setEntry(index, getReplacedValue(value));
+            newValue = getReplacedValue(value);
+            assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue));
         } else {
-            ValueNode newValue = value;
             if (valueState.getState() != EscapeState.Virtual) {
                 newValue = valueState.getMaterializedValue();
+                assert newValue.kind() == Kind.Object;
+            } else {
+                newValue = valueState.getVirtualObject();
             }
-            assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind();
-            obj.setEntry(index, newValue);
+            assert obj.getEntry(index) == null || isObjectEntry(obj.getEntry(index));
         }
+        obj.setEntry(index, newValue);
+    }
+
+    private static boolean isObjectEntry(ValueNode value) {
+        return value.kind() == Kind.Object || value instanceof VirtualObjectNode;
     }
 
     @Override
@@ -128,7 +133,6 @@
 
     @Override
     public void delete() {
-        assert current instanceof FixedWithNextNode;
         effects.deleteFixedNode((FixedWithNextNode) current);
         deleted = true;
     }
@@ -181,26 +185,4 @@
             }
         }
     }
-
-    @Override
-    public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) {
-        if (OptEarlyReadElimination.getValue()) {
-            state.addReadCache(object, identity, value);
-        }
-    }
-
-    @Override
-    public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) {
-        if (OptEarlyReadElimination.getValue()) {
-            return state.getReadCache(object, identity);
-        }
-        return null;
-    }
-
-    @Override
-    public void killReadCache(ResolvedJavaField identity) {
-        if (OptEarlyReadElimination.getValue()) {
-            state.killReadCache(identity);
-        }
-    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Tue Jun 11 00:00:40 2013 +0200
@@ -170,4 +170,13 @@
      * @return the new materialized frame
      */
     MaterializedFrame materialize();
+
+    /**
+     * To check whether the given {@link FrameSlot} has been initialized or not. An initialized slot
+     * has previously been read or modified.
+     * 
+     * @param slot the slot
+     * @return true if the slot is uninitialized.
+     */
+    boolean isInitialized(FrameSlot slot);
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java	Tue Jun 11 00:00:40 2013 +0200
@@ -112,6 +112,13 @@
         return clonedFrameDescriptor;
     }
 
+    public FrameDescriptor shallowCopy() {
+        FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.typeConversion);
+        clonedFrameDescriptor.slots.addAll(slots);
+        clonedFrameDescriptor.identifierToSlotMap.putAll(identifierToSlotMap);
+        return clonedFrameDescriptor;
+    }
+
     void updateVersion() {
         version.invalidate();
         version = createVersion();
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java	Tue Jun 11 00:00:40 2013 +0200
@@ -29,7 +29,7 @@
     private final int index;
     private FrameSlotKind kind;
 
-    protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, FrameSlotKind kind) {
+    public FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, FrameSlotKind kind) {
         this.descriptor = descriptor;
         this.identifier = identifier;
         this.index = index;
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java	Tue Jun 11 00:00:40 2013 +0200
@@ -133,4 +133,9 @@
     public FrameDescriptor getFrameDescriptor() {
         throw new UnsupportedOperationException("native frame");
     }
+
+    @Override
+    public boolean isInitialized(FrameSlot slot) {
+        throw new UnsupportedOperationException("native frame");
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Tue Jun 11 00:00:40 2013 +0200
@@ -122,4 +122,9 @@
     public FrameDescriptor getFrameDescriptor() {
         return wrapped.getFrameDescriptor();
     }
+
+    @Override
+    public boolean isInitialized(FrameSlot slot) {
+        return wrapped.isInitialized(slot);
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Mon Jun 10 23:59:50 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Tue Jun 11 00:00:40 2013 +0200
@@ -201,4 +201,9 @@
             tags = Arrays.copyOf(tags, newSize);
         }
     }
+
+    @Override
+    public boolean isInitialized(FrameSlot slot) {
+        return (this.tags[slot.getIndex()] != FrameSlotKind.Illegal.ordinal());
+    }
 }
--- a/make/Makefile	Mon Jun 10 23:59:50 2013 +0200
+++ b/make/Makefile	Tue Jun 11 00:00:40 2013 +0200
@@ -516,6 +516,10 @@
 $(EXPORT_JRE_LIB_DIR)/%.jar: $(SHARED_DIR)/%.jar
 	$(install-file)
 
+# Shared options files
+$(EXPORT_JRE_LIB_DIR)/%.options: $(SHARED_DIR)/%.options
+	$(install-file)
+	
 # Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
 $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
 	$(install-file)
--- a/make/build-graal.xml	Mon Jun 10 23:59:50 2013 +0200
+++ b/make/build-graal.xml	Tue Jun 11 00:00:40 2013 +0200
@@ -28,7 +28,7 @@
   <property name="classes.dir" value="${shared.dir}/graal"/>
   <property name="jar.dir" value="${shared.dir}"/>
   <property name="jar.file" value="${jar.dir}/graal.jar"/>
-  <target depends="jar" name="main"/>
+  <target depends="options,jar" name="main"/>
   <target depends="cleanclasses" name="compile">
     <mkdir dir="${classes.dir}"/>
     <javac debug="on" destdir="${classes.dir}" includeantruntime="false">
@@ -101,6 +101,14 @@
   <target name="cleanclasses">
     <delete dir="${classes.dir}"/>
   </target>
+  <target if="graal.options.exists" name="options">
+    <copy todir="${jar.dir}">
+      <filelist dir="${gamma.dir}" files="graal.options"/>
+    </copy>
+  </target>
+  <target name="check-graal-options-exists">
+    <available file="${gamma.dir}/graal.options" property="graal.options.exists"/>
+  </target>
   <target depends="cleanclasses" name="clean">
     <delete file="${jar.file}"/>
   </target>
--- a/make/solaris/makefiles/buildtree.make	Mon Jun 10 23:59:50 2013 +0200
+++ b/make/solaris/makefiles/buildtree.make	Tue Jun 11 00:00:40 2013 +0200
@@ -229,7 +229,9 @@
 	echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os/posix/vm)"; \
+	echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \
+	echo "$(call gamma-path,altsrc,gpu/ptx) \\"; \
+	echo "$(call gamma-path,commonsrc,gpu/ptx)"; \
 	echo; \
 	echo "Src_Dirs_I = \\"; \
 	echo "$(call gamma-path,altsrc,share/vm/prims) \\"; \
@@ -244,8 +246,9 @@
 	echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(ARCH)/vm) \\"; \
 	echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \
 	echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \
-	echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \
-	echo "$(call gamma-path,commonsrc,os/posix/vm)"; \
+	echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \
+	echo "$(call gamma-path,altsrc,gpu) \\"; \
+	echo "$(call gamma-path,commonsrc,gpu)"; \
 	[ -n "$(CFLAGS_BROWSE)" ] && \
 	    echo && echo "CFLAGS_BROWSE = $(CFLAGS_BROWSE)"; \
 	[ -n "$(ENABLE_FULL_DEBUG_SYMBOLS)" ] && \
--- a/make/solaris/makefiles/vm.make	Mon Jun 10 23:59:50 2013 +0200
+++ b/make/solaris/makefiles/vm.make	Tue Jun 11 00:00:40 2013 +0200
@@ -194,7 +194,9 @@
 COMPILER2_PATHS +=  $(GENERATED)/adfiles
 
 GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/share/vm/graal)
+GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/gpu/ptx)
 GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/graal
+GRAAL_PATHS += $(HS_COMMON_SRC)/gpu/ptx
 
 # Include dirs per type.
 Src_Dirs/CORE      := $(CORE_PATHS)
--- a/mx/commands.py	Mon Jun 10 23:59:50 2013 +0200
+++ b/mx/commands.py	Tue Jun 11 00:00:40 2013 +0200
@@ -232,6 +232,8 @@
     machine = platform.uname()[4]
     if machine in ['amd64', 'AMD64', 'x86_64', 'i86pc']:
         return 'amd64'
+    if machine in ['sun4v']:
+        return 'sparc'
     if machine == 'i386' and mx.get_os() == 'darwin':
         try:
             # Support for Snow Leopard and earlier version of MacOSX
@@ -343,6 +345,7 @@
 
 def _installGraalJarInJdks(graalDist):
     graalJar = graalDist.path
+    graalOptions = join(_graal_home, 'graal.options')
     jdks = join(_graal_home, 'jdk' + str(mx.java().version))
     if exists(jdks):
         for e in os.listdir(jdks):
@@ -353,6 +356,9 @@
                 shutil.copyfile(graalJar, tmp)
                 os.close(fd)
                 shutil.move(tmp, join(jreLibDir, 'graal.jar'))
+                
+                if exists(graalOptions):
+                    shutil.copy(graalOptions, join(jreLibDir, 'graal.options'))
 
 # run a command in the windows SDK Debug Shell
 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo={}):
@@ -458,7 +464,7 @@
     out.element('property', {'name' : 'jar.dir', 'value' : '${shared.dir}'})
     out.element('property', {'name' : 'jar.file', 'value' : '${jar.dir}/graal.jar'})
     
-    out.element('target', {'name' : 'main', 'depends' : 'jar'})
+    out.element('target', {'name' : 'main', 'depends' : 'options,jar'})
 
     serviceMap = {};
     def addService(service, provider):
@@ -513,6 +519,16 @@
     out.element('delete', {'dir' : '${classes.dir}'})
     out.close('target')
 
+    out.open('target', {'name' : 'options', 'if' : 'graal.options.exists'})
+    out.open('copy', {'todir' : '${jar.dir}'})
+    out.element('filelist', {'dir' : '${gamma.dir}', 'files' : 'graal.options'})
+    out.close('copy')
+    out.close('target')
+
+    out.open('target', {'name' : 'check-graal-options-exists'})
+    out.element('available', {'property' : 'graal.options.exists', 'file' : '${gamma.dir}/graal.options'})
+    out.close('target')
+    
     out.open('target', {'name' : 'clean', 'depends' : 'cleanclasses'})
     out.element('delete', {'file' : '${jar.file}'})
     out.close('target')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/sparc/vm/codeInstaller_sparc.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#ifndef CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
+#define CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
+
+inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  fatal("CodeInstaller::pd_next_offset - sparc unimp");
+  return 0;
+}
+
+inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined,
+                                             address instruction, int alignment, char typeChar) {
+  fatal("CodeInstaller::pd_site_DataPatch - sparc unimp");
+}
+
+inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp");
+}
+
+inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  fatal("CodeInstaller::pd_relocate_ForeignCall - sparc unimp");
+}
+
+inline void CodeInstaller::pd_relocate_JavaMethod(oop method, jint pc_offset) {
+  fatal("CodeInstaller::pd_relocate_JavaMethod - sparc unimp");
+}
+
+inline int32_t* CodeInstaller::pd_locate_operand(address instruction) {
+  fatal("CodeInstaller::pd_locate_operand - sparc unimp");
+  return (int32_t*)0;
+}
+
+#endif // CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP
--- a/src/cpu/sparc/vm/graalGlobals_sparc.hpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/cpu/sparc/vm/graalGlobals_sparc.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -31,6 +31,32 @@
 // Sets the default values for platform dependent flags used by the Graal compiler.
 // (see graalGlobals.hpp)
 
-define_pd_global(intx, GraalSafepointPollOffset,     0    );
+#if !defined(COMPILER1) && !defined(COMPILER2)
+define_pd_global(bool, BackgroundCompilation,        true );
+define_pd_global(bool, UseTLAB,                      true );
+define_pd_global(bool, ResizeTLAB,                   true );
+define_pd_global(bool, InlineIntrinsics,             true );
+define_pd_global(bool, PreferInterpreterNativeStubs, false);
+define_pd_global(bool, TieredCompilation,            false);
+define_pd_global(intx, BackEdgeThreshold,            100000);
+
+define_pd_global(intx, OnStackReplacePercentage,     933  );
+define_pd_global(intx, FreqInlineSize,               325  );
+define_pd_global(intx, NewSizeThreadIncrease,        4*K  );
+define_pd_global(uintx,MetaspaceSize,                12*M );
+define_pd_global(bool, NeverActAsServerClassMachine, false);
+define_pd_global(uint64_t,MaxRAM,                    1ULL*G);
+define_pd_global(bool, CICompileOSR,                 true );
+define_pd_global(bool, ProfileTraps,                 true );
+define_pd_global(bool, UseOnStackReplacement,        true );
+define_pd_global(intx, CompileThreshold,             10000);
+define_pd_global(intx, InitialCodeCacheSize,         16*M );
+define_pd_global(intx, ReservedCodeCacheSize,        64*M );
+define_pd_global(bool, ProfileInterpreter,           true );
+define_pd_global(intx, CodeCacheExpansionSize,       64*K );
+define_pd_global(uintx,CodeCacheMinBlockLength,      4);
+define_pd_global(intx, TypeProfileWidth,             8);
+define_pd_global(intx, MethodProfileWidth,           4);
+#endif
 
 #endif // CPU_SPARC_VM_GRAALGLOBALS_SPARC_HPP
--- a/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -27,11 +27,16 @@
 
  friend class AbstractInterpreterGenerator;
 
+  address generate_deopt_entry_for(TosState state, int step);
+
  private:
 
   address generate_normal_entry(bool synchronized);
   address generate_native_entry(bool synchronized);
-  address generate_abstract_entry(void);
+#ifdef GRAAL
+  address generate_execute_compiled_method_entry();
+#endif
+ address generate_abstract_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
   address generate_empty_entry(void);
   address generate_accessor_entry(void);
--- a/src/cpu/sparc/vm/nativeInst_sparc.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -24,6 +24,8 @@
 
 #include "precompiled.hpp"
 #include "asm/macroAssembler.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "code/codeCache.hpp"
 #include "memory/resourceArea.hpp"
 #include "nativeInst_sparc.hpp"
 #include "oops/oop.inline.hpp"
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -1826,6 +1826,20 @@
   verify_oop_args(masm, method, sig_bt, regs);
   vmIntrinsics::ID iid = method->intrinsic_id();
 
+
+#ifdef GRAAL
+  if (iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) {
+    // We are called from compiled code here. The three object arguments
+    // are already in the correct registers (j_rarg0, jrarg1, jrarg2). The
+    // fourth argument (j_rarg3) is a raw pointer to the nmethod. Make a tail
+    // call to its verified entry point.
+    __ set(nmethod::verified_entry_point_offset(), O0);
+    __ JMP(O0, 0);
+    __ delayed()->nop();
+    return;
+  }
+#endif
+
   // Now write the args into the outgoing interpreter space
   bool     has_receiver   = false;
   Register receiver_reg   = noreg;
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -213,7 +213,7 @@
 }
 
 
-address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
+address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
   address entry = __ pc();
   __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
   { Label L;
@@ -813,6 +813,19 @@
   return generate_accessor_entry();
 }
 
+#ifdef GRAAL
+
+// Interpreter stub for calling a compiled method with 3 object arguments
+address InterpreterGenerator::generate_execute_compiled_method_entry() {
+  address entry_point = __ pc();
+
+  __ stop("graal-sparc unimp");
+
+  return entry_point;
+}
+
+#endif
+
 //
 // Interpreter stub for calling a native method. (asm interpreter)
 // This sets up a somewhat different looking stack for calling the native method
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/x86/vm/codeInstaller_x86.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+#ifndef CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+#define CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+
+#include "compiler/disassembler.hpp"
+#include "runtime/javaCalls.hpp"
+#include "graal/graalEnv.hpp"
+#include "graal/graalCompiler.hpp"
+#include "graal/graalCodeInstaller.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalRuntime.hpp"
+#include "asm/register.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "code/vmreg.hpp"
+
+inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) {
+  if (inst->is_call() || inst->is_jump()) {
+    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
+    return (pc_offset + NativeCall::instruction_size);
+  } else if (inst->is_mov_literal64()) {
+    // mov+call instruction pair
+    jint offset = pc_offset + NativeMovConstReg::instruction_size;
+    u_char* call = (u_char*) (_instructions->start() + offset);
+    assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
+    offset += 3; /* prefix byte + opcode byte + modrm byte */
+    return (offset);
+  } else if (inst->is_call_reg()) {
+    // the inlined vtable stub contains a "call register" instruction
+    assert(method != NULL, "only valid for virtual calls");
+    return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
+  } else {
+    fatal("unsupported type of instruction for call site");
+    return 0;
+  }
+}
+
+inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined,
+                                             address instruction, int alignment, char typeChar) {
+  switch (typeChar) {
+    case 'z':
+    case 'b':
+    case 's':
+    case 'c':
+    case 'i':
+      fatal("int-sized values not expected in DataPatch");
+      break;
+    case 'f':
+    case 'j':
+    case 'd': {
+      if (inlined) {
+        address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
+        *((jlong*) operand) = Constant::primitive(constant);
+      } else {
+        address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        address next_instruction = Assembler::locate_next_instruction(instruction);
+        int size = _constants->size();
+        if (alignment > 0) {
+          guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+          size = align_size_up(size, alignment);
+        }
+        // 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 = Constant::primitive(constant);
+
+        long disp = dest - next_instruction;
+        assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+        *((jint*) operand) = (jint) disp;
+
+        _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+        TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size);
+      }
+      break;
+    }
+    case 'a': {
+      address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
+      Handle obj = Constant::object(constant);
+
+      jobject value = JNIHandles::make_local(obj());
+      *((jobject*) operand) = value;
+      _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+      TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand);
+      break;
+    }
+    default:
+      fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
+      break;
+  }
+}
+
+inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+  if (cb->is_nmethod()) {
+    nmethod* nm = (nmethod*) cb;
+    nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
+  } else {
+    nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
+  }
+  _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+}
+
+inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  if (inst->is_call()) {
+    // NOTE: for call without a mov, the offset must fit a 32-bit immediate
+    //       see also CompilerToVM.getMaxCallTargetOffset()
+    NativeCall* call = nativeCall_at((address) (inst));
+    call->set_destination((address) foreign_call_destination);
+    _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
+  } else if (inst->is_mov_literal64()) {
+    NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst));
+    mov->set_data((intptr_t) foreign_call_destination);
+    _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
+  } else {
+    NativeJump* jump = nativeJump_at((address) (inst));
+    jump->set_jump_destination((address) foreign_call_destination);
+    _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+  }
+  TRACE_graal_3("relocating (foreign call)  at %p", inst);
+}
+
+inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) {
+#ifdef ASSERT
+  Method* method = NULL;
+  // we need to check, this might also be an unresolved method
+  if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
+    method = getMethodFromHotSpotMethod(hotspot_method);
+  }
+#endif
+  switch (_next_call_type) {
+    case MARK_INLINE_INVOKE:
+      break;
+    case MARK_INVOKEVIRTUAL:
+    case MARK_INVOKEINTERFACE: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
+
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                                             virtual_call_Relocation::spec(_invoke_mark_pc),
+                                             Assembler::call32_operand);
+      break;
+    }
+    case MARK_INVOKESTATIC: {
+      assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
+
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_static_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                                             relocInfo::static_call_type, Assembler::call32_operand);
+      break;
+    }
+    case MARK_INVOKESPECIAL: {
+      assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
+      NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
+      call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
+      _instructions->relocate(call->instruction_address(),
+                              relocInfo::opt_virtual_call_type, Assembler::call32_operand);
+      break;
+    }
+    default:
+      fatal("invalid _next_call_type value");
+      break;
+  }
+}
+
+inline int32_t* CodeInstaller::pd_locate_operand(address instruction) {
+  return (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+}
+
+#endif // CPU_SPARC_VM_CODEINSTALLER_X86_HPP
+
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -314,6 +314,7 @@
   template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue,        "com/oracle/graal/hotspot/meta/HotSpotMonitorValue")             \
   template(com_oracle_graal_hotspot_debug_LocalImpl,                 "com/oracle/graal/hotspot/debug/LocalImpl")                      \
   AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\
+  SPARC_ONLY(template(com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime,"com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime"))\
   /* 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")                        \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -35,18 +35,23 @@
 #include "code/vmreg.hpp"
 
 #ifdef TARGET_ARCH_x86
+# include "codeInstaller_x86.hpp"
 # include "vmreg_x86.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_sparc
+# include "codeInstaller_sparc.hpp"
 # include "vmreg_sparc.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_zero
+# include "codeInstaller_zero.hpp"
 # include "vmreg_zero.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_arm
+# include "codeInstaller_arm.hpp"
 # include "vmreg_arm.inline.hpp"
 #endif
 #ifdef TARGET_ARCH_ppc
+# include "codeInstaller_ppc.hpp"
 # include "vmreg_ppc.inline.hpp"
 #endif
 
@@ -199,8 +204,16 @@
       }
       return value;
 #else
+#ifdef TARGET_ARCH_sparc
+      ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(number)->as_VMReg()));
+      if (type == T_DOUBLE) {
+        second = value;
+      }
+      return value;
+#else
       ShouldNotReachHere("Platform currently does not support floating point values.");
 #endif
+#endif
     }
   } else if (value->is_a(StackSlot::klass())) {
     if (type == T_DOUBLE) {
@@ -674,36 +687,15 @@
   assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type");
 
   NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
-  jint next_pc_offset = 0x0;
-  if (inst->is_call() || inst->is_jump()) {
-    assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
-    next_pc_offset = pc_offset + NativeCall::instruction_size;
-  } else if (inst->is_mov_literal64()) {
-    // mov+call instruction pair
-    next_pc_offset = pc_offset + NativeMovConstReg::instruction_size;
-    u_char* call = (u_char*) (_instructions->start() + next_pc_offset);
-    assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte");
-    next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */
-  } else if (inst->is_call_reg()) {
-    // the inlined vtable stub contains a "call register" instruction
-    assert(hotspot_method != NULL, "only valid for virtual calls");
-    next_pc_offset = pc_offset + ((NativeCallReg *) inst)->next_instruction_offset();
-  } else {
-    fatal("unsupported type of instruction for call site");
-  }
-
+  jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method);
+  
   if (target->is_a(SystemDictionary::HotSpotInstalledCode_klass())) {
     assert(inst->is_jump(), "jump expected");
 
     CodeBlob* cb = (CodeBlob*) (address) HotSpotInstalledCode::codeBlob(target);
     assert(cb != NULL, "npe");
-    if (cb->is_nmethod()) {
-      nmethod* nm = (nmethod*) cb;
-      nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
-    } else {
-      nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
-    }
-    _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+    
+    CodeInstaller::pd_relocate_CodeBlob(cb, inst);
 
     return;
   }
@@ -720,65 +712,14 @@
 
   if (foreign_call != NULL) {
     jlong foreign_call_destination = HotSpotForeignCallLinkage::address(foreign_call);
-    if (inst->is_call()) {
-      // NOTE: for call without a mov, the offset must fit a 32-bit immediate
-      //       see also CompilerToVM.getMaxCallTargetOffset()
-      NativeCall* call = nativeCall_at((address) (inst));
-      call->set_destination((address) foreign_call_destination);
-      _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
-    } else if (inst->is_mov_literal64()) {
-      NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst));
-      mov->set_data((intptr_t) foreign_call_destination);
-      _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
-    } else {
-      NativeJump* jump = nativeJump_at((address) (inst));
-      jump->set_jump_destination((address) foreign_call_destination);
-      _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
-    }
-    TRACE_graal_3("relocating (foreign call)  at %p", inst);
+
+    CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination);
   } else { // method != NULL
     assert(hotspot_method != NULL, "unexpected JavaMethod");
-#ifdef ASSERT
-    Method* method = NULL;
-    // we need to check, this might also be an unresolved method
-    if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) {
-      method = getMethodFromHotSpotMethod(hotspot_method);
-    }
-#endif
     assert(debug_info != NULL, "debug info expected");
 
     TRACE_graal_3("method call");
-    switch (_next_call_type) {
-      case MARK_INLINE_INVOKE:
-        break;
-      case MARK_INVOKEVIRTUAL:
-      case MARK_INVOKEINTERFACE: {
-        assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface");
-
-        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
-        call->set_destination(SharedRuntime::get_resolve_virtual_call_stub());
-        _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand);
-        break;
-      }
-      case MARK_INVOKESTATIC: {
-        assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic");
-
-        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
-        call->set_destination(SharedRuntime::get_resolve_static_call_stub());
-        _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand);
-        break;
-      }
-      case MARK_INVOKESPECIAL: {
-        assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial");
-        NativeCall* call = nativeCall_at(_instructions->start() + pc_offset);
-        call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub());
-        _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand);
-        break;
-      }
-      default:
-        fatal("invalid _next_call_type value");
-        break;
-    }
+    CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset);
   }
   _next_call_type = MARK_INVOKE_INVALID;
   if (debug_info != NULL) {
@@ -793,59 +734,15 @@
   oop kind = Constant::kind(constant);
 
   address instruction = _instructions->start() + pc_offset;
-
   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");
-      break;
     case 'f':
     case 'j':
-    case 'd': {
+    case 'd':
       record_metadata_in_constant(constant, _oop_recorder);
-      if (inlined) {
-        address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
-        *((jlong*) operand) = Constant::primitive(constant);
-      } else {
-        address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
-        address next_instruction = Assembler::locate_next_instruction(instruction);
-        int size = _constants->size();
-        if (alignment > 0) {
-          guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
-          size = align_size_up(size, alignment);
-        }
-        // 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 = Constant::primitive(constant);
-
-        long disp = dest - next_instruction;
-        assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
-        *((jint*) operand) = (jint) disp;
-
-        _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
-        TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size);
-      }
-      break;
-    }
-    case 'a': {
-      address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
-      Handle obj = Constant::object(constant);
-
-      jobject value = JNIHandles::make_local(obj());
-      *((jobject*) operand) = value;
-      _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
-      TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand);
-      break;
-    }
-    default:
-      fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
       break;
   }
+  CodeInstaller::pd_site_DataPatch(constant, kind, inlined, instruction, alignment, typeChar);
 }
 
 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
@@ -890,7 +787,8 @@
         break;
       case MARK_POLL_NEAR: {
         NativeInstruction* ni = nativeInstruction_at(instruction);
-        int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        int32_t* disp = (int32_t*) pd_locate_operand(instruction);
+        // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
         int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
         intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
         *disp = (int32_t)new_disp;
@@ -900,7 +798,8 @@
         break;
       case MARK_POLL_RETURN_NEAR: {
         NativeInstruction* ni = nativeInstruction_at(instruction);
-        int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        int32_t* disp = (int32_t*) pd_locate_operand(instruction);
+        // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand);
         int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
         intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
         *disp = (int32_t)new_disp;
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -75,6 +75,13 @@
   Dependencies*             _dependencies;
   ExceptionHandlerTable     _exception_handler_table;
 
+  jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method);
+  void pd_site_DataPatch(oop constant, oop kind, bool inlined, address instruction, int alignment, char typeChar);
+  void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst);
+  void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination);
+  void pd_relocate_JavaMethod(oop method, jint pc_offset);
+  int32_t* pd_locate_operand(address instruction);
+
 public:
 
   CodeInstaller(Handle& comp_result, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations);
@@ -106,4 +113,20 @@
 
 };
 
+#ifdef TARGET_ARCH_x86
+# include "codeInstaller_x86.hpp"
+#endif
+#ifdef TARGET_ARCH_sparc
+# include "codeInstaller_sparc.hpp"
+#endif
+#ifdef TARGET_ARCH_zero
+# error
+#endif
+#ifdef TARGET_ARCH_arm
+# error
+#endif
+#ifdef TARGET_ARCH_ppc
+# error
+#endif
+
 #endif // SHARE_VM_GRAAL_GRAAL_CODE_INSTALLER_HPP
--- a/src/share/vm/graal/graalCompiler.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -51,7 +51,7 @@
 
   uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
   uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
-  guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)");
+  AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)"));
   NOT_LP64(error("check TLAB allocation code for address space conflicts"));
 
   _deopted_leaf_graph_count = 0;
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -658,8 +658,10 @@
   set_boolean("useAESIntrinsics", UseAESIntrinsics);
   set_boolean("useTLAB", UseTLAB);
   set_boolean("useG1GC", UseG1GC);
+#ifdef TARGET_ARCH_x86
   set_int("useSSE", UseSSE);
   set_int("useAVX", UseAVX);
+#endif
   set_int("codeEntryAlignment", CodeEntryAlignment);
   set_int("stackShadowPages", StackShadowPages);
   set_int("hubOffset", oopDesc::klass_offset_in_bytes());
@@ -695,9 +697,11 @@
   set_int("klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER);
   set_int("threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset()));
   set_int("threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset()));
+#ifdef TARGET_ARCH_x86
   set_boolean("isPollingPageFar", Assembler::is_polling_page_far());
+  set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
+#endif
   set_int("classMirrorOffset", in_bytes(Klass::java_mirror_offset()));
-  set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes);
   set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset()));
   set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset()));
   set_int("klassOffset", java_lang_Class::klass_offset_in_bytes());
@@ -734,6 +738,8 @@
   set_int("typeProfileWidth", TypeProfileWidth);
   set_int("methodProfileWidth", MethodProfileWidth);
 
+  set_int("interpreterProfilingThreshold", InvocationCounter::get_ProfileLimit());
+
   set_int("tlabAlignmentReserve", (int32_t)ThreadLocalAllocBuffer::alignment_reserve());
   set_long("tlabIntArrayMarkWord", (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
   set_long("heapTopAddress", (jlong)(address) Universe::heap()->top_addr());
@@ -742,7 +748,9 @@
   set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset()));
   set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset()));
   set_int("threadLastJavaSpOffset", in_bytes(JavaThread::last_Java_sp_offset()));
+#ifdef TARGET_ARCH_x86
   set_int("threadLastJavaFpOffset", in_bytes(JavaThread::last_Java_fp_offset()));
+#endif
   set_int("threadLastJavaPcOffset", in_bytes(JavaThread::last_Java_pc_offset()));
   set_int("threadObjectResultOffset", in_bytes(JavaThread::vm_result_offset()));
   set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset()));
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -51,6 +51,9 @@
 #ifdef AMD64
     Symbol* name = vmSymbols::com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime();
 #endif
+#ifdef SPARC
+    Symbol* name = vmSymbols::com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime();
+#endif
     KlassHandle klass = loadClass(name);
 
     JavaValue result(T_OBJECT);
--- a/src/share/vm/interpreter/invocationCounter.hpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/interpreter/invocationCounter.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -95,9 +95,9 @@
   Action action() const                          { return _action[state()]; }
   int    count() const                           { return _counter >> number_of_noncount_bits; }
 
-  int   get_InvocationLimit() const              { return InterpreterInvocationLimit >> number_of_noncount_bits; }
-  int   get_BackwardBranchLimit() const          { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
-  int   get_ProfileLimit() const                 { return InterpreterProfileLimit >> number_of_noncount_bits; }
+  static int   get_InvocationLimit()             { return InterpreterInvocationLimit >> number_of_noncount_bits; }
+  static int   get_BackwardBranchLimit()         { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
+  static int   get_ProfileLimit()                { return InterpreterProfileLimit >> number_of_noncount_bits; }
 
   // Test counter using scaled limits like the asm interpreter would do rather than doing
   // the shifts to normalize the counter.
--- a/src/share/vm/runtime/fieldDescriptor.cpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/runtime/fieldDescriptor.cpp	Tue Jun 11 00:00:40 2013 +0200
@@ -27,9 +27,6 @@
 #include "classfile/vmSymbols.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
-#include "oops/annotations.hpp"
-#include "oops/instanceKlass.hpp"
-#include "oops/fieldStreams.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/signature.hpp"
--- a/src/share/vm/runtime/fieldDescriptor.hpp	Mon Jun 10 23:59:50 2013 +0200
+++ b/src/share/vm/runtime/fieldDescriptor.hpp	Tue Jun 11 00:00:40 2013 +0200
@@ -25,7 +25,10 @@
 #ifndef SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP
 #define SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP
 
+#include "oops/annotations.hpp"
 #include "oops/constantPool.hpp"
+#include "oops/fieldStreams.hpp"
+#include "oops/instanceKlass.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/fieldType.hpp"
 #include "utilities/accessFlags.hpp"