changeset 20107:2c65cac3d940

Merge with 7815c4d4a07f92d10d27a180f32e0dbc8ca15d44
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 31 Mar 2015 19:15:45 -0700
parents 2e3cc2a27711 (current diff) 7815c4d4a07f (diff)
children 36fdc4af85d5 02a9b5d77964
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/cfg.filter src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/edgeColor.filter src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/noframestate.filter src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/slots.filter
diffstat 123 files changed, 1225 insertions(+), 1748 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java	Tue Mar 31 19:15:45 2015 -0700
@@ -23,7 +23,7 @@
 package com.oracle.graal.api.meta;
 
 /**
- * Represents the three possibilities that an exception was seen at a specific BCI.
+ * Represents a logic value that can be either {@link #TRUE}, {@link #FALSE}, or {@link #UNKNOWN}.
  */
 public enum TriState {
     TRUE,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.asm.amd64.test;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static org.junit.Assume.*;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.amd64.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.test.*;
+
+public class IncrementDecrementMacroTest extends AssemblerTest {
+
+    @Before
+    public void checkAMD64() {
+        assumeTrue("skipping AMD64 specific test", codeCache.getTarget().arch instanceof AMD64);
+    }
+
+    public static class LongField {
+        public long x;
+
+        LongField(long x) {
+            this.x = x;
+        }
+    }
+
+    private static class IncrementCodeGenTest implements CodeGenTest {
+        final int value;
+
+        public IncrementCodeGenTest(int value) {
+            this.value = value;
+        }
+
+        @Override
+        public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
+            AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
+            Register ret = registerConfig.getReturnRegister(Kind.Int);
+            try {
+                Field f = LongField.class.getDeclaredField("x");
+                AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f));
+                asm.incrementq(arg, value);
+                asm.movq(ret, arg);
+                asm.ret(0);
+                return asm.close(true);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to generate field access:", e);
+            }
+        }
+    }
+
+    private void assertIncrement(long initValue, int increment) {
+        assertReturn("longFieldStubIncrement", new IncrementCodeGenTest(increment), initValue + increment, new LongField(initValue));
+    }
+
+    private void assertIncrements(int increment) {
+        assertIncrement(0x4242_4242_4242_4242L, increment);
+    }
+
+    @SuppressWarnings("unused")
+    public static long longFieldStubIncrement(LongField arg) {
+        return 0;
+    }
+
+    private static class DecrementCodeGenTest implements CodeGenTest {
+        final int value;
+
+        public DecrementCodeGenTest(int value) {
+            this.value = value;
+        }
+
+        @Override
+        public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
+            AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
+            Register ret = registerConfig.getReturnRegister(Kind.Int);
+            try {
+                Field f = LongField.class.getDeclaredField("x");
+                AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f));
+                asm.decrementq(arg, value);
+                asm.movq(ret, arg);
+                asm.ret(0);
+                return asm.close(true);
+            } catch (Exception e) {
+                throw new RuntimeException("exception while trying to generate field access:", e);
+            }
+        }
+    }
+
+    private void assertDecrement(long initValue, int increment) {
+        assertReturn("longFieldStubDecrement", new DecrementCodeGenTest(increment), initValue - increment, new LongField(initValue));
+    }
+
+    private void assertDecrements(int increment) {
+        assertDecrement(0x4242_4242_4242_4242L, increment);
+    }
+
+    @SuppressWarnings("unused")
+    public static long longFieldStubDecrement(LongField arg) {
+        return 0;
+    }
+
+    @Test
+    public void incrementMemTest0() {
+        int increment = 0;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest1() {
+        int increment = 1;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest2() {
+        int increment = 2;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest3() {
+        int increment = Integer.MAX_VALUE;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest4() {
+        int increment = Integer.MIN_VALUE;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest5() {
+        int increment = -1;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest6() {
+        int increment = -2;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void incrementMemTest7() {
+        int increment = -0x1000_0000;
+        assertIncrements(increment);
+    }
+
+    @Test
+    public void decrementMemTest0() {
+        int decrement = 0;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest1() {
+        int decrement = 1;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest2() {
+        int decrement = 2;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest3() {
+        int decrement = Integer.MAX_VALUE;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest4() {
+        int decrement = Integer.MIN_VALUE;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest5() {
+        int decrement = -1;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest6() {
+        int decrement = -2;
+        assertDecrements(decrement);
+    }
+
+    @Test
+    public void decrementMemTest7() {
+        int decrement = -0x1000_0000;
+        assertDecrements(decrement);
+    }
+
+}
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Tue Mar 31 19:15:45 2015 -0700
@@ -27,6 +27,7 @@
 import static com.oracle.graal.asm.NumUtil.*;
 import static com.oracle.graal.asm.amd64.AMD64AsmOptions.*;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
 
 import com.oracle.graal.amd64.*;
@@ -729,6 +730,7 @@
         public static final AMD64MOp DIV  = new AMD64MOp("DIV",  0xF7, 6);
         public static final AMD64MOp IDIV = new AMD64MOp("IDIV", 0xF7, 7);
         public static final AMD64MOp INC  = new AMD64MOp("INC",  0xFF, 0);
+        public static final AMD64MOp DEC  = new AMD64MOp("DEC",  0xFF, 1);
         // @formatter:on
 
         private final int ext;
@@ -1961,6 +1963,10 @@
         ADD.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
     }
 
+    public final void addq(AMD64Address dst, int imm32) {
+        ADD.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
+    }
+
     public final void addq(Register dst, Register src) {
         ADD.rmOp.emit(this, QWORD, dst, src);
     }
@@ -2024,6 +2030,10 @@
         emitByte(0xC8 | encode);
     }
 
+    public final void decq(AMD64Address dst) {
+        DEC.emit(this, QWORD, dst);
+    }
+
     public final void incq(Register dst) {
         // Don't use it directly. Use Macroincrementq() instead.
         // Use two-byte form (one-byte from is a REX prefix in 64-bit mode)
@@ -2032,6 +2042,10 @@
         emitByte(0xC0 | encode);
     }
 
+    public final void incq(AMD64Address dst) {
+        INC.emit(this, QWORD, dst);
+    }
+
     public final void movq(Register dst, long imm64) {
         int encode = prefixqAndEncode(dst.encoding);
         emitByte(0xB8 | encode);
@@ -2130,6 +2144,10 @@
         SUB.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
     }
 
+    public final void subq(AMD64Address dst, int imm32) {
+        SUB.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32);
+    }
+
     public final void subqWide(Register dst, int imm32) {
         // don't use the sign-extending version, forcing a 32-bit immediate
         SUB.getMIOpcode(QWORD, false).emit(this, QWORD, dst, imm32);
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Tue Mar 31 19:15:45 2015 -0700
@@ -56,6 +56,25 @@
         }
     }
 
+    public final void decrementq(AMD64Address dst, int value) {
+        if (value == Integer.MIN_VALUE) {
+            subq(dst, value);
+            return;
+        }
+        if (value < 0) {
+            incrementq(dst, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && UseIncDec) {
+            decq(dst);
+        } else {
+            subq(dst, value);
+        }
+    }
+
     public void incrementq(Register reg, int value) {
         if (value == Integer.MIN_VALUE) {
             addq(reg, value);
@@ -75,6 +94,25 @@
         }
     }
 
+    public final void incrementq(AMD64Address dst, int value) {
+        if (value == Integer.MIN_VALUE) {
+            addq(dst, value);
+            return;
+        }
+        if (value < 0) {
+            decrementq(dst, -value);
+            return;
+        }
+        if (value == 0) {
+            return;
+        }
+        if (value == 1 && UseIncDec) {
+            incq(dst);
+        } else {
+            addq(dst, value);
+        }
+    }
+
     public final void movptr(Register dst, AMD64Address src) {
         movq(dst, src);
     }
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -29,6 +29,8 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.test.*;
@@ -54,21 +56,25 @@
 
     protected InstalledCode assembleMethod(Method m, CodeGenTest test) {
         ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(m);
-        RegisterConfig registerConfig = codeCache.getRegisterConfig();
-        CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false);
+        try (Scope s = Debug.scope("assembleMethod", method, codeCache)) {
+            RegisterConfig registerConfig = codeCache.getRegisterConfig();
+            CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false);
 
-        CompilationResult compResult = new CompilationResult();
-        byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc);
-        compResult.setTargetCode(targetCode, targetCode.length);
+            CompilationResult compResult = new CompilationResult();
+            byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc);
+            compResult.setTargetCode(targetCode, targetCode.length);
+
+            InstalledCode code = codeCache.addMethod(method, compResult, null, null);
 
-        InstalledCode code = codeCache.addMethod(method, compResult, null, null);
-
-        DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler();
-        if (dis != null) {
-            String disasm = dis.disassemble(code);
-            Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0);
+            DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler();
+            if (dis != null) {
+                String disasm = dis.disassemble(code);
+                Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0);
+            }
+            return code;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
         }
-        return code;
     }
 
     protected Object runTest(String methodName, CodeGenTest test, Object... args) {
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Tue Mar 31 19:15:45 2015 -0700
@@ -51,9 +51,6 @@
     @Option(help = "Maximum level of recursive inlining.", type = OptionType.Expert)
     public static final OptionValue<Integer> MaximumRecursiveInlining = new OptionValue<>(5);
 
-    @Option(help = "", type = OptionType.Debug)
-    public static final OptionValue<Boolean> IterativeInlining = new OptionValue<>(false);
-
     @Option(help = "Graphs with less than this number of nodes are trivial and therefore always inlined.", type = OptionType.Expert)
     public static final OptionValue<Integer> TrivialInliningSize = new OptionValue<>(10);
 
@@ -94,9 +91,6 @@
     @Option(help = "", type = OptionType.Expert)
     public static final OptionValue<Integer> DeoptsToDisableOptimisticOptimization = new OptionValue<>(40);
 
-    @Option(help = "", type = OptionType.Expert)
-    public static final OptionValue<Boolean> CacheGraphs = new OptionValue<>(false);
-
     @Option(help = "", type = OptionType.Debug)
     public static final OptionValue<Boolean> LoopPeeling = new OptionValue<>(true);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -27,7 +27,6 @@
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -306,7 +305,7 @@
 
     private void processMethod(final String snippet) {
         graph = parseEager(snippet, AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context);
     }
@@ -317,7 +316,7 @@
 
     private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) {
         graph = parseEager(snippet, AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         canonicalizer.apply(graph, context);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Tue Mar 31 19:15:45 2015 -0700
@@ -72,7 +72,7 @@
         PhaseSuite<HighTierContext> graphBuilderSuite = new PhaseSuite<>();
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess)));
         graphBuilderSuite.appendPhase(new GraphBuilderPhase(config));
-        HighTierContext context = new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.NONE);
+        HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE);
 
         Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus());
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java	Tue Mar 31 19:15:45 2015 -0700
@@ -45,7 +45,7 @@
 
     @Test
     public void test1() {
-        test("test1Snippet", REFERENCE_SNIPPET);
+        testConditionalElimination("test1Snippet", REFERENCE_SNIPPET);
     }
 
     @SuppressWarnings("all")
@@ -68,7 +68,7 @@
 
     @Test
     public void test2() {
-        test("test2Snippet", REFERENCE_SNIPPET);
+        testConditionalElimination("test2Snippet", REFERENCE_SNIPPET);
     }
 
     @SuppressWarnings("all")
@@ -88,7 +88,7 @@
 
     @Test
     public void test3() {
-        test("test3Snippet", REFERENCE_SNIPPET);
+        testConditionalElimination("test3Snippet", REFERENCE_SNIPPET);
     }
 
     @SuppressWarnings("all")
@@ -128,7 +128,7 @@
 
     @Test
     public void test4() {
-        test("test4Snippet", "test4Snippet");
+        testConditionalElimination("test4Snippet", "test4Snippet");
     }
 
     @SuppressWarnings("all")
@@ -151,6 +151,6 @@
 
     @Test
     public void test5() {
-        test("test5Snippet", "test5Snippet");
+        testConditionalElimination("test5Snippet", "test5Snippet");
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java	Tue Mar 31 19:15:45 2015 -0700
@@ -54,7 +54,7 @@
 
     @Test
     public void test1() {
-        test("test1Snippet", REFERENCE_SNIPPET);
+        testConditionalElimination("test1Snippet", REFERENCE_SNIPPET);
     }
 
     @SuppressWarnings("all")
@@ -81,7 +81,7 @@
 
     @Test
     public void test2() {
-        test("test2Snippet", REFERENCE_SNIPPET);
+        testConditionalElimination("test2Snippet", REFERENCE_SNIPPET);
     }
 
     @SuppressWarnings("all")
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java	Tue Mar 31 19:15:45 2015 -0700
@@ -51,7 +51,7 @@
 
     @Test
     public void test1() {
-        test("test1Snippet", "reference1Snippet");
+        testConditionalElimination("test1Snippet", "reference1Snippet");
     }
 
     @SuppressWarnings("all")
@@ -74,6 +74,6 @@
 
     @Test
     public void test2() {
-        test("test2Snippet", "reference2Snippet");
+        testConditionalElimination("test2Snippet", "reference2Snippet");
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java	Tue Mar 31 19:15:45 2015 -0700
@@ -63,7 +63,7 @@
 
     @Test
     public void test1() {
-        test("test1Snippet", "reference1Snippet");
+        testConditionalElimination("test1Snippet", "reference1Snippet");
     }
 
     public static int reference2Snippet(A a) {
@@ -85,7 +85,7 @@
 
     @Test
     public void test2() {
-        test("test2Snippet", "reference2Snippet");
+        testConditionalElimination("test2Snippet", "reference2Snippet");
     }
 
     @SuppressWarnings("unused")
@@ -115,6 +115,6 @@
 
     @Test
     public void test3() {
-        test("test3Snippet", "reference3Snippet", true);
+        testConditionalElimination("test3Snippet", "reference3Snippet", true);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java	Tue Mar 31 19:15:45 2015 -0700
@@ -62,7 +62,7 @@
 
     @Test
     public void test1() {
-        test("test1Snippet", "reference1Snippet");
+        testConditionalElimination("test1Snippet", "reference1Snippet");
     }
 
     @SuppressWarnings("all")
@@ -79,7 +79,7 @@
 
     @Test
     public void test2() {
-        test("test2Snippet", "reference1Snippet");
+        testConditionalElimination("test2Snippet", "reference1Snippet");
     }
 
     @SuppressWarnings("all")
@@ -96,6 +96,6 @@
 
     @Test
     public void test3() {
-        test("test3Snippet", "reference1Snippet");
+        testConditionalElimination("test3Snippet", "reference1Snippet");
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java	Tue Mar 31 19:15:45 2015 -0700
@@ -45,7 +45,7 @@
 
     @Test
     public void test1() {
-        test("test1Snippet", REFERENCE_SNIPPET);
+        testConditionalElimination("test1Snippet", REFERENCE_SNIPPET);
     }
 
     @SuppressWarnings("all")
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java	Tue Mar 31 19:15:45 2015 -0700
@@ -39,11 +39,11 @@
  */
 public class ConditionalEliminationTestBase extends GraalCompilerTest {
 
-    protected void test(String snippet, String referenceSnippet) {
-        test(snippet, referenceSnippet, false);
+    protected void testConditionalElimination(String snippet, String referenceSnippet) {
+        testConditionalElimination(snippet, referenceSnippet, false);
     }
 
-    protected void test(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference) {
+    protected void testConditionalElimination(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference) {
         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
         Debug.dump(graph, "Graph");
         PhaseContext context = new PhaseContext(getProviders());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -28,7 +28,6 @@
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -82,7 +81,7 @@
     private void test(final String snippet) {
         try (Scope s = Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet))) {
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-            HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            HighTierContext context = getDefaultHighTierContext();
             new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
             new CanonicalizerPhase().apply(graph, context);
             Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -69,7 +69,7 @@
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins());
         new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL, null).apply(graph);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, context);
         return graph;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -376,6 +376,10 @@
         return providers;
     }
 
+    protected HighTierContext getDefaultHighTierContext() {
+        return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+    }
+
     protected SnippetReflectionProvider getSnippetReflection() {
         return Graal.getRequiredCapability(SnippetReflectionProvider.class);
     }
@@ -718,7 +722,7 @@
         StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner) : graph;
         lastCompiledGraph = graphToCompile;
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false);
-        Request<CompilationResult> request = new Request<>(graphToCompile, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
+        Request<CompilationResult> request = new Request<>(graphToCompile, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), getDefaultGraphBuilderSuite(),
                         OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), getLIRSuites(), new CompilationResult(),
                         CompilationResultBuilderFactory.Default);
         return GraalCompiler.compile(request);
@@ -822,7 +826,7 @@
         assert javaMethod.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + javaMethod;
         try (Scope ds = Debug.scope("Parsing", javaMethod)) {
             StructuredGraph graph = new StructuredGraph(javaMethod, allowAssumptions);
-            graphBuilderSuite.apply(graph, new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.ALL));
+            graphBuilderSuite.apply(graph, getDefaultHighTierContext());
             return graph;
         } catch (Throwable e) {
             throw Debug.handle(e);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -31,7 +31,6 @@
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
@@ -75,7 +74,7 @@
 
     @Test
     public void testFloatingGuards() {
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES);
         new ConvertDeoptimizeToGuardPhase().apply(graph, context);
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -62,8 +62,8 @@
         final ResolvedJavaMethod method = getResolvedJavaMethod("testMethod");
         final StructuredGraph graph = parseEager(method, AllowAssumptions.YES);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-        final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
-                        OptimisticOptimizations.ALL, getProfilingInfo(graph), null, getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default);
+        final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL,
+                        getProfilingInfo(graph), null, getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default);
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
             if (sp instanceof Call) {
@@ -85,7 +85,7 @@
         assertTrue(graphLineSPs > 0);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         PhaseSuite<HighTierContext> graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins()));
-        final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL,
+        final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), graphBuilderSuite, OptimisticOptimizations.ALL,
                         getProfilingInfo(graph), getSpeculationLog(), getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default);
         int lineSPs = 0;
         for (Infopoint sp : cr.getInfopoints()) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -66,7 +65,7 @@
         for (Invoke invoke : graph.getInvokes()) {
             hints.put(invoke, 1000d);
         }
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -77,7 +76,7 @@
             hints.put(invoke, 1000d);
         }
 
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -29,7 +29,6 @@
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -89,7 +88,7 @@
     private StructuredGraph getGraph(String snippet) {
         ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
         StructuredGraph graph = parseEager(method, AllowAssumptions.YES);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new CanonicalizerPhase().apply(graph, context);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -29,7 +29,6 @@
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.debug.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy;
@@ -48,7 +47,7 @@
     }
 
     private void longAddChain(boolean reverse) {
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         StructuredGraph graph = new StructuredGraph(AllowAssumptions.NO);
         ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1));
         ValueNode value = null;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -688,7 +688,7 @@
         final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
         try (Scope d = Debug.scope("FloatingReadTest", graph)) {
             try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) {
-                HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+                HighTierContext context = getDefaultHighTierContext();
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
                 canonicalizer.apply(graph, context);
                 if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -33,7 +33,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -96,7 +95,7 @@
         for (Invoke invoke : graph.getInvokes()) {
             hints.put(invoke, 1000d);
         }
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -48,8 +48,8 @@
     protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph) {
         SchedulePhase schedule = null;
         try (Scope s = Debug.scope("FrontEnd")) {
-            schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE,
-                            graph.method().getProfilingInfo(), null, getSuites());
+            schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, graph.method().getProfilingInfo(),
+                            null, getSuites());
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Tue Mar 31 19:15:45 2015 -0700
@@ -34,7 +34,6 @@
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -150,7 +149,7 @@
         ResolvedJavaMethod method = getResolvedJavaMethod(snippet);
         try (Scope s = Debug.scope(getClass(), method, getCodeCache())) {
             graph = parseEager(method, AllowAssumptions.YES);
-            context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            context = getDefaultHighTierContext();
             new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
             new DeadCodeEliminationPhase().apply(graph);
             new CanonicalizerPhase().apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -25,7 +25,6 @@
 import org.junit.*;
 
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -41,7 +40,7 @@
     @Override
     protected void processMethod(final String snippet) {
         graph = parseEager(getResolvedJavaMethod(snippet), AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new EarlyReadEliminationPhase(new CanonicalizerPhase()).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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 java.util.concurrent.*;
-
-import org.junit.*;
-
-import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.compiler.test.ea.EATestBase.TestClassInt;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-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 IterativeInliningTest extends GraalCompilerTest {
-
-    private StructuredGraph graph;
-
-    public static class TestObject {
-
-        public Callable<Integer> callable;
-
-        public TestObject(Callable<Integer> callable) {
-            this.callable = callable;
-        }
-    }
-
-    public static class TestInt extends TestClassInt implements Callable<Integer> {
-
-        public TestInt(int x, int y) {
-            super(x, y);
-        }
-
-        @Override
-        public Integer call() throws Exception {
-            return new Integer(x);
-        }
-    }
-
-    @SuppressWarnings("all")
-    public static int testSimpleSnippet(int b) throws Exception {
-        TestObject a = new TestObject(null);
-        a.callable = new TestInt(b, 9);
-        return a.callable.call();
-    }
-
-    @Test
-    public void testSimple() {
-        ValueNode result = getReturn("testSimpleSnippet").result();
-        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
-        assertDeepEquals(graph.getParameter(0), result);
-    }
-
-    final ReturnNode getReturn(String snippet) {
-        processMethod(snippet);
-        assertDeepEquals(1, graph.getNodes(ReturnNode.TYPE).count());
-        return graph.getNodes(ReturnNode.TYPE).first();
-    }
-
-    private void processMethod(final String snippet) {
-        graph = parseEager(snippet, AllowAssumptions.YES);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
-        new IterativeInliningPhase(new CanonicalizerPhase()).apply(graph, context);
-    }
-}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -30,7 +30,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -243,7 +242,7 @@
 
     protected void processMethod(final String snippet) {
         graph = parseEager(snippet, AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new PartialEscapePhase(false, true, new CanonicalizerPhase(), null).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -23,17 +23,15 @@
 package com.oracle.graal.compiler.test.ea;
 
 import java.lang.ref.*;
-import java.util.function.*;
-
 import org.junit.*;
 
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.graph.*;
 
 /**
  * The PartialEscapeAnalysisPhase is expected to remove all allocations and return the correct
@@ -186,11 +184,11 @@
             Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", graph.getNodes().filter(NewInstanceNode.class).isEmpty());
             Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty());
 
-            ToDoubleFunction<FixedNode> nodeProbabilities = new FixedNodeProbabilityCache();
+            ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false);
             double probabilitySum = 0;
             int materializeCount = 0;
             for (CommitAllocationNode materialize : graph.getNodes().filter(CommitAllocationNode.class)) {
-                probabilitySum += nodeProbabilities.applyAsDouble(materialize) * materialize.getVirtualObjects().size();
+                probabilitySum += cfg.blockFor(materialize).probability() * materialize.getVirtualObjects().size();
                 materializeCount += materialize.getVirtualObjects().size();
             }
             Assert.assertEquals("unexpected number of MaterializeObjectNodes", expectedCount, materializeCount);
@@ -205,5 +203,4 @@
             throw e;
         }
     }
-
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -32,7 +32,6 @@
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -60,7 +59,7 @@
     private void test(final String snippet) {
         try (Scope s = Debug.scope("PoorMansEATest", new DebugDumpScope(snippet))) {
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
-            HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            HighTierContext highTierContext = getDefaultHighTierContext();
             new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext);
             PhaseContext context = new PhaseContext(getProviders());
             new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -233,7 +233,7 @@
             StructuredGraph graph = eagerInfopointMode ? parseDebug(method, AllowAssumptions.YES) : parseEager(method, AllowAssumptions.YES);
             PhaseSuite<HighTierContext> graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins()))
                             : getDefaultGraphBuilderSuite();
-            HighTierContext context = new HighTierContext(getProviders(), null, graphBuilderSuite, OptimisticOptimizations.ALL);
+            HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL);
             Debug.dump(graph, "Graph");
             new CanonicalizerPhase().apply(graph, context);
             new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java	Tue Mar 31 19:15:45 2015 -0700
@@ -23,7 +23,6 @@
 package com.oracle.graal.compiler.test.tutorial;
 
 import java.lang.reflect.*;
-import java.util.*;
 import java.util.concurrent.atomic.*;
 
 import com.oracle.graal.api.code.*;
@@ -122,11 +121,10 @@
             CompilationResultBuilderFactory factory = CompilationResultBuilderFactory.Default;
 
             /* Advanced configuration objects that are not mandatory. */
-            Map<ResolvedJavaMethod, StructuredGraph> cache = null;
             SpeculationLog speculationLog = null;
 
             /* Invoke the whole Graal compilation pipeline. */
-            GraalCompiler.compileGraph(graph, callingConvention, method, providers, backend, target, cache, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites,
+            GraalCompiler.compileGraph(graph, callingConvention, method, providers, backend, target, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites,
                             compilationResult, factory);
 
             /*
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Tue Mar 31 19:15:45 2015 -0700
@@ -141,7 +141,6 @@
         public final Providers providers;
         public final Backend backend;
         public final TargetDescription target;
-        public final Map<ResolvedJavaMethod, StructuredGraph> cache;
         public final PhaseSuite<HighTierContext> graphBuilderSuite;
         public final OptimisticOptimizations optimisticOpts;
         public final ProfilingInfo profilingInfo;
@@ -159,7 +158,6 @@
          * @param providers
          * @param backend
          * @param target
-         * @param cache
          * @param graphBuilderSuite
          * @param optimisticOpts
          * @param profilingInfo
@@ -170,15 +168,14 @@
          * @param factory
          */
         public Request(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend, TargetDescription target,
-                        Map<ResolvedJavaMethod, StructuredGraph> cache, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo,
-                        SpeculationLog speculationLog, Suites suites, LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) {
+                        PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites,
+                        LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) {
             this.graph = graph;
             this.cc = cc;
             this.installedCodeOwner = installedCodeOwner;
             this.providers = providers;
             this.backend = backend;
             this.target = target;
-            this.cache = cache;
             this.graphBuilderSuite = graphBuilderSuite;
             this.optimisticOpts = optimisticOpts;
             this.profilingInfo = profilingInfo;
@@ -209,10 +206,10 @@
      * @return the result of the compilation
      */
     public static <T extends CompilationResult> T compileGraph(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
-                    TargetDescription target, Map<ResolvedJavaMethod, StructuredGraph> cache, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts,
-                    ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites, LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) {
-        return compile(new Request<>(graph, cc, installedCodeOwner, providers, backend, target, cache, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites,
-                        compilationResult, factory));
+                    TargetDescription target, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog,
+                    Suites suites, LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) {
+        return compile(new Request<>(graph, cc, installedCodeOwner, providers, backend, target, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites, compilationResult,
+                        factory));
     }
 
     /**
@@ -223,7 +220,7 @@
     public static <T extends CompilationResult> T compile(Request<T> r) {
         assert !r.graph.isFrozen();
         try (Scope s0 = Debug.scope("GraalCompiler", r.graph, r.providers.getCodeCache())) {
-            SchedulePhase schedule = emitFrontEnd(r.providers, r.target, r.graph, r.cache, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.speculationLog, r.suites);
+            SchedulePhase schedule = emitFrontEnd(r.providers, r.target, r.graph, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.speculationLog, r.suites);
             emitBackEnd(r.graph, null, r.cc, r.installedCodeOwner, r.backend, r.target, r.compilationResult, r.factory, schedule, null, r.lirSuites);
         } catch (Throwable e) {
             throw Debug.handle(e);
@@ -242,14 +239,14 @@
     /**
      * Builds the graph, optimizes it.
      */
-    public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, Map<ResolvedJavaMethod, StructuredGraph> cache,
-                    PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) {
+    public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, PhaseSuite<HighTierContext> graphBuilderSuite,
+                    OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) {
         try (Scope s = Debug.scope("FrontEnd"); DebugCloseable a = FrontEnd.start()) {
             if (speculationLog != null) {
                 speculationLog.collectFailedSpeculations();
             }
 
-            HighTierContext highTierContext = new HighTierContext(providers, cache, graphBuilderSuite, optimisticOpts);
+            HighTierContext highTierContext = new HighTierContext(providers, graphBuilderSuite, optimisticOpts);
             if (graph.start().next() == null) {
                 graphBuilderSuite.apply(graph, highTierContext);
                 new DeadCodeEliminationPhase(Optional).apply(graph);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java	Tue Mar 31 19:15:45 2015 -0700
@@ -36,6 +36,11 @@
         if (ImmutableCode.getValue()) {
             canonicalizer.disableReadCanonicalization();
         }
+
+        if (OptCanonicalizer.getValue()) {
+            appendPhase(canonicalizer);
+        }
+
         appendPhase(new CleanTypeProfileProxyPhase(canonicalizer));
         appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER));
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Tue Mar 31 19:15:45 2015 -0700
@@ -56,16 +56,12 @@
         }
 
         if (Inline.getValue()) {
-            if (IterativeInlining.getValue()) {
-                appendPhase(new IterativeInliningPhase(canonicalizer));
-            } else {
-                appendPhase(new InliningPhase(canonicalizer));
-                appendPhase(new DeadCodeEliminationPhase(Optional));
+            appendPhase(new InliningPhase(canonicalizer));
+            appendPhase(new DeadCodeEliminationPhase(Optional));
 
-                if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
-                    appendPhase(canonicalizer);
-                    appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false));
-                }
+            if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
+                appendPhase(canonicalizer);
+                appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false));
             }
         }
 
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Tue Mar 31 19:15:45 2015 -0700
@@ -213,7 +213,6 @@
 
     protected final MetaAccessProvider metaAccess;
     private final List<MethodInfo> registrations;
-    private final Thread registrationThread;
 
     /**
      * The minimum {@linkplain InvocationPluginIdHolder#getInvocationPluginId() id} for a method
@@ -234,7 +233,6 @@
     private InvocationPlugins parent;
 
     private InvocationPlugins(InvocationPlugins parent, MetaAccessProvider metaAccess) {
-        this.registrationThread = Thread.currentThread();
         this.metaAccess = metaAccess;
         this.registrations = new ArrayList<>(INITIAL_PLUGIN_CAPACITY);
         InvocationPlugins p = parent;
@@ -263,7 +261,6 @@
      * registered for {@code method}.
      */
     public void register(InvocationPlugin plugin, Class<?> declaringClass, String name, Class<?>... argumentTypes) {
-        assert Thread.currentThread() == registrationThread : "invocation plugin registration must be single threaded";
         MethodInfo methodInfo = new MethodInfo(plugin, declaringClass, name, argumentTypes);
         assert Checker.check(this, methodInfo, plugin);
         assert plugins == null : "invocation plugin registration is closed";
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Tue Mar 31 19:15:45 2015 -0700
@@ -31,7 +31,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*;
+import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.word.*;
@@ -171,7 +171,7 @@
                 wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind);
             }
             try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
-                plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+                plugins = createGraphBuilderPlugins(runtime, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, stampProvider);
                 replacements.setGraphBuilderPlugins(plugins);
             }
             try (InitTimer rt = timer("create Suites provider")) {
@@ -184,6 +184,12 @@
         }
     }
 
+    protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider runtime, TargetDescription target, HotSpotConstantReflectionProvider constantReflection,
+                    HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements,
+                    HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
+        return HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+    }
+
     protected AMD64HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) {
         return new AMD64HotSpotBackend(runtime, providers);
     }
@@ -260,15 +266,15 @@
         } else {
             /*
              * System V Application Binary Interface, AMD64 Architecture Processor Supplement
-             * 
+             *
              * Draft Version 0.96
-             * 
+             *
              * http://www.uclibc.org/docs/psABI-x86_64.pdf
-             * 
+             *
              * 3.2.1
-             * 
+             *
              * ...
-             * 
+             *
              * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12
              * through %r15 "belong" to the calling function and the called function is required to
              * preserve their values. In other words, a called function must preserve these
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java	Tue Mar 31 19:15:45 2015 -0700
@@ -24,10 +24,6 @@
 
 import static com.oracle.graal.amd64.AMD64.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.asm.NumUtil.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*;
-import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
 import static com.oracle.graal.compiler.common.GraalInternalError.*;
 
 import com.oracle.graal.api.code.*;
@@ -107,11 +103,7 @@
         // increment counter (in memory)
         if (isConstant(incrementValue)) {
             int increment = asInt(asConstant(incrementValue));
-            if (increment == 1) {
-                INC.emit(masm, QWORD, counterAddr);
-            } else {
-                ADD.getMIOpcode(QWORD, isByte(increment)).emit(masm, QWORD, counterAddr, increment);
-            }
+            masm.incrementq(counterAddr, increment);
         } else {
             masm.addq(counterAddr, asRegister(incrementValue));
         }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Mar 31 19:15:45 2015 -0700
@@ -122,6 +122,11 @@
 
     SaveRbp saveRbp;
 
+    /**
+     * Helper instruction to reserve a stack slot for the whole method. Note that the actual users
+     * of the stack slot might be inserted after stack slot allocation. This dummy instruction
+     * ensures that the stack slot is alive and gets a real stack slot assigned.
+     */
     private static final class RescueSlotDummyOp extends LIRInstruction {
         public static final LIRInstructionClass<RescueSlotDummyOp> TYPE = LIRInstructionClass.create(RescueSlotDummyOp.class);
 
@@ -144,17 +149,16 @@
     private RescueSlotDummyOp rescueSlotOp;
 
     private StackSlotValue getOrInitRescueSlot() {
+        RescueSlotDummyOp op = getOrInitRescueSlotOp();
+        return op.getSlot();
+    }
+
+    private RescueSlotDummyOp getOrInitRescueSlotOp() {
         if (rescueSlotOp == null) {
             // create dummy instruction to keep the rescue slot alive
             rescueSlotOp = new RescueSlotDummyOp(getResult().getFrameMapBuilder(), getLIRKindTool().getWordKind());
-            // insert dummy instruction into the start block
-            LIR lir = getResult().getLIR();
-            List<LIRInstruction> instructions = lir.getLIRforBlock(lir.getControlFlowGraph().getStartBlock());
-            // Note: we do not insert at position 1 to avoid interference with the save rpb op
-            instructions.add(instructions.size() - 1, rescueSlotOp);
-            Debug.dump(lir, "created rescue dummy op");
         }
-        return rescueSlotOp.getSlot();
+        return rescueSlotOp;
     }
 
     /**
@@ -481,7 +485,12 @@
         }
         if (BenchmarkCounters.enabled) {
             // ensure that the rescue slot is available
-            getOrInitRescueSlot();
+            LIRInstruction op = getOrInitRescueSlotOp();
+            // insert dummy instruction into the start block
+            LIR lir = getResult().getLIR();
+            List<LIRInstruction> instructions = lir.getLIRforBlock(lir.getControlFlowGraph().getStartBlock());
+            instructions.add(1, op);
+            Debug.dump(lir, "created rescue dummy op");
         }
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Tue Mar 31 19:15:45 2015 -0700
@@ -27,7 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*;
+import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.word.*;
@@ -68,7 +68,7 @@
         HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target);
         HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime);
         HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind);
-        Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+        Plugins plugins = createGraphBuilderPlugins(runtime, target, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes);
         replacements.setGraphBuilderPlugins(plugins);
         HotSpotSuitesProvider suites = createSuites(runtime, plugins);
         HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection,
@@ -77,6 +77,12 @@
         return createBackend(runtime, providers);
     }
 
+    protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider runtime, TargetDescription target, HotSpotMetaAccessProvider metaAccess,
+                    HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotStampProvider stampProvider,
+                    HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
+        return HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+    }
+
     protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) {
         return new HotSpotSuitesProvider(runtime, plugins);
     }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -205,20 +205,18 @@
     }
 
     private StructuredGraph compile(String test, boolean compileAOT) {
-        StructuredGraph graph = parseEager(test, AllowAssumptions.YES);
-        ResolvedJavaMethod method = graph.method();
-
         try (OverrideScope s = OptionValue.override(ImmutableCode, compileAOT)) {
+            StructuredGraph graph = parseEager(test, AllowAssumptions.YES);
+            ResolvedJavaMethod method = graph.method();
             CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
             // create suites everytime, as we modify options for the compiler
             SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites();
             final Suites suitesLocal = suitesProvider.createSuites();
             final LIRSuites lirSuitesLocal = suitesProvider.createLIRSuites();
-            final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(),
-                            OptimisticOptimizations.ALL, getProfilingInfo(graph), getSpeculationLog(), suitesLocal, lirSuitesLocal, new CompilationResult(), CompilationResultBuilderFactory.Default);
+            final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL,
+                            getProfilingInfo(graph), getSpeculationLog(), suitesLocal, lirSuitesLocal, new CompilationResult(), CompilationResultBuilderFactory.Default);
             addMethod(method, compResult);
+            return graph;
         }
-
-        return graph;
     }
 }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -249,7 +249,7 @@
         ResolvedJavaMethod snippet = getResolvedJavaMethod(snippetName);
         try (Scope s = Debug.scope("WriteBarrierAdditionTest", snippet)) {
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
-            HighTierContext highContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            HighTierContext highContext = getDefaultHighTierContext();
             MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
             new NodeIntrinsificationPhase(getMetaAccess(), getConstantReflection(), getSnippetReflection(), getProviders().getForeignCalls(), getProviders().getStampProvider()).apply(graph);
             new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -627,7 +627,7 @@
     private void testPredicate(final String snippet, final GraphPredicate expectedBarriers, final int... removedBarrierIndices) {
         try (Scope d = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) {
             final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-            HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            HighTierContext highTierContext = getDefaultHighTierContext();
             new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext);
 
             MidTierContext midTierContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Tue Mar 31 19:15:45 2015 -0700
@@ -35,14 +35,12 @@
 import static com.oracle.graal.phases.common.inlining.InliningUtil.*;
 
 import java.lang.management.*;
-import java.util.*;
 import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
@@ -195,11 +193,6 @@
                 // Begin the compilation event.
                 compilationEvent.begin();
 
-                Map<ResolvedJavaMethod, StructuredGraph> graphCache = null;
-                if (GraalOptions.CacheGraphs.getValue()) {
-                    graphCache = new HashMap<>();
-                }
-
                 boolean recordEvolMethodDeps = graalEnv == 0 || unsafe.getByte(graalEnv + config.graalEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0;
 
                 HotSpotProviders providers = backend.getProviders();
@@ -225,8 +218,8 @@
                     // all code after the OSR loop is never executed.
                     optimisticOpts.remove(Optimization.RemoveNeverExecutedCode);
                 }
-                result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, getGraphBuilderSuite(providers), optimisticOpts, profilingInfo,
-                                method.getSpeculationLog(), suites, lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default);
+                result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), getGraphBuilderSuite(providers), optimisticOpts, profilingInfo, method.getSpeculationLog(), suites,
+                                lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default);
                 result.setId(getId());
                 result.setEntryBCI(entryBCI);
             } catch (Throwable e) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Tue Mar 31 19:15:45 2015 -0700
@@ -47,6 +47,7 @@
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
@@ -124,7 +125,7 @@
             r.register1(query.name(), Receiver.class, new InvocationPlugin() {
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                     ValueNode javaClass = receiver.get();
-                    ValueNode folded = ClassQueryNode.tryFold(javaClass, query, b.getMetaAccess(), b.getConstantReflection());
+                    ValueNode folded = ClassQueryNode.tryFold(GraphUtil.originalValue(javaClass), query, b.getMetaAccess(), b.getConstantReflection());
                     if (folded != null) {
                         b.addPush(query.returnKind, folded);
                     } else {
@@ -137,7 +138,7 @@
         r.register2("cast", Receiver.class, Object.class, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
                 ValueNode javaClass = receiver.get();
-                ValueNode folded = ClassCastNode.tryFold(javaClass, object, b.getConstantReflection(), b.getAssumptions());
+                ValueNode folded = ClassCastNode.tryFold(GraphUtil.originalValue(javaClass), object, b.getConstantReflection(), b.getAssumptions());
                 if (folded != null) {
                     b.addPush(Kind.Object, folded);
                 } else {
@@ -151,7 +152,7 @@
     private static void registerCallSitePlugins(InvocationPlugins plugins) {
         InvocationPlugin plugin = new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
-                ValueNode callSite = receiver.get();
+                ValueNode callSite = GraphUtil.originalValue(receiver.get());
                 ValueNode folded = CallSiteTargetNode.tryFold(callSite, b.getMetaAccess(), b.getAssumptions());
                 if (folded != null) {
                     b.addPush(Kind.Object, folded);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java	Tue Mar 31 19:15:45 2015 -0700
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot.meta;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.java.AbstractBytecodeParser.Options.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
@@ -42,7 +41,7 @@
     static final ThreadLocal<Boolean> FieldReadEnabledInImmutableCode = new ThreadLocal<>();
 
     public boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) {
-        if ((InlineDuringParsing.getValue() && !ImmutableCode.getValue()) || b.parsingReplacement()) {
+        if (!ImmutableCode.getValue() || b.parsingReplacement()) {
             if (receiver.isConstant()) {
                 JavaConstant asJavaConstant = receiver.asJavaConstant();
                 return tryReadField(b, field, asJavaConstant);
@@ -65,7 +64,7 @@
     }
 
     public boolean apply(GraphBuilderContext b, ResolvedJavaField staticField) {
-        if ((InlineDuringParsing.getValue() && !ImmutableCode.getValue()) || b.parsingReplacement()) {
+        if (!ImmutableCode.getValue() || b.parsingReplacement()) {
             // Javac does not allow use of "$assertionsDisabled" for a field name but
             // Eclipse does in which case a suffix is added to the generated field.
             if (b.parsingReplacement() && staticField.isSynthetic() && staticField.getName().startsWith("$assertionsDisabled")) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaFieldImpl.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaFieldImpl.java	Tue Mar 31 19:15:45 2015 -0700
@@ -51,7 +51,7 @@
     private final LocationIdentity locationIdentity = new FieldLocationIdentity(this);
 
     public static class FieldLocationIdentity extends LocationIdentity {
-        HotSpotResolvedJavaFieldImpl inner;
+        HotSpotResolvedJavaField inner;
 
         public FieldLocationIdentity(HotSpotResolvedJavaFieldImpl inner) {
             super(false);
@@ -78,7 +78,7 @@
 
         @Override
         public String toString() {
-            return inner.name;
+            return inner.getName();
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Tue Mar 31 19:15:45 2015 -0700
@@ -164,7 +164,7 @@
         LIRSuites lirSuites = providers.getSuites().createLIRSuites();
         PhaseSuite<HighTierContext> phaseSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, g.method(), false);
-        CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), null, phaseSuite, OptimisticOptimizations.ALL,
+        CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), phaseSuite, OptimisticOptimizations.ALL,
                         DefaultProfilingInfo.get(TriState.UNKNOWN), null, suites, lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default);
         InstalledCode installedCode;
         try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -29,7 +29,6 @@
 import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -67,9 +66,8 @@
     }
 
     public static ValueNode tryFold(ValueNode javaClass, ValueNode object, ConstantReflectionProvider constantReflection, Assumptions assumptions) {
-        ValueNode value = GraphUtil.originalValue(javaClass);
-        if (value.isConstant()) {
-            ResolvedJavaType type = constantReflection.asJavaType(value.asConstant());
+        if (javaClass != null && javaClass.isConstant()) {
+            ResolvedJavaType type = constantReflection.asJavaType(javaClass.asConstant());
             if (type != null && !type.isPrimitive()) {
                 return CheckCastNode.create(type, object, null, false, assumptions);
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassQueryNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassQueryNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -30,7 +30,6 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -79,13 +78,12 @@
     }
 
     public static ValueNode tryFold(ValueNode javaClass, Query query, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
-        ValueNode value = GraphUtil.originalValue(javaClass);
-        if (value != null && value.isConstant()) {
+        if (javaClass != null && javaClass.isConstant()) {
             if (query.returnKind == Kind.Object) {
                 if (GraalOptions.ImmutableCode.getValue()) {
                     return null;
                 }
-                HotSpotObjectConstant c = (HotSpotObjectConstant) value.asConstant();
+                HotSpotObjectConstant c = (HotSpotObjectConstant) javaClass.asConstant();
                 JavaConstant answer;
                 switch (query) {
                     case getClassLoader0:
@@ -105,7 +103,7 @@
                     return ConstantNode.forConstant(answer, metaAccess);
                 }
             } else {
-                ResolvedJavaType type = constantReflection.asJavaType(value.asConstant());
+                ResolvedJavaType type = constantReflection.asJavaType(javaClass.asConstant());
                 if (type != null) {
                     switch (query) {
                         case isArray:
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import static sun.misc.Version.*;
+
 import java.lang.invoke.*;
 
 import com.oracle.graal.api.meta.*;
@@ -35,24 +37,39 @@
 
 /**
  * A call target that replaces itself in the graph when being lowered by restoring the original
- * {@link MethodHandle} invocation target. This is required for when a {@link MethodHandle} call was
- * resolved to a constant target but the target was not inlined. In that case, the original
- * invocation must be restored with all of its original arguments. Why? HotSpot linkage for
- * {@link MethodHandle} intrinsics (see {@code MethodHandles::generate_method_handle_dispatch})
- * expects certain implicit arguments to be on the stack such as the MemberName suffix argument for
- * a call to one of the MethodHandle.linkTo* methods. An
- * {@linkplain MethodHandleNode#tryResolveTargetInvoke resolved} {@link MethodHandle} invocation
- * drops these arguments which means the interpreter won't find them.
+ * {@link MethodHandle} invocation target. Prior to
+ * https://bugs.openjdk.java.net/browse/JDK-8072008, this is required for when a
+ * {@link MethodHandle} call is resolved to a constant target but the target was not inlined. In
+ * that case, the original invocation must be restored with all of its original arguments. Why?
+ * HotSpot linkage for {@link MethodHandle} intrinsics (see
+ * {@code MethodHandles::generate_method_handle_dispatch}) expects certain implicit arguments to be
+ * on the stack such as the MemberName suffix argument for a call to one of the MethodHandle.linkTo*
+ * methods. An {@linkplain MethodHandleNode#tryResolveTargetInvoke resolved} {@link MethodHandle}
+ * invocation drops these arguments which means the interpreter won't find them.
  */
 @NodeInfo
 public final class ResolvedMethodHandleCallTargetNode extends MethodCallTargetNode implements Lowerable {
 
     public static final NodeClass<ResolvedMethodHandleCallTargetNode> TYPE = NodeClass.create(ResolvedMethodHandleCallTargetNode.class);
+
+    /**
+     * Creates a call target for an invocation on a direct target derived by resolving a constant
+     * {@link MethodHandle}.
+     */
+    public static MethodCallTargetNode create(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod,
+                    ValueNode[] originalArguments, JavaType originalReturnType) {
+        if (jdkMajorVersion() >= 1 && jdkMinorVersion() >= 8 && jdkMicroVersion() >= 0 && jdkUpdateVersion() >= 60) {
+            // https://bugs.openjdk.java.net/browse/JDK-8072008 is targeted for 8u60
+            return new MethodCallTargetNode(invokeKind, targetMethod, arguments, returnType);
+        }
+        return new ResolvedMethodHandleCallTargetNode(invokeKind, targetMethod, arguments, returnType, originalTargetMethod, originalArguments, originalReturnType);
+    }
+
     protected final ResolvedJavaMethod originalTargetMethod;
     protected final JavaType originalReturnType;
     @Input NodeInputList<ValueNode> originalArguments;
 
-    public ResolvedMethodHandleCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod,
+    protected ResolvedMethodHandleCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod,
                     ValueNode[] originalArguments, JavaType originalReturnType) {
         super(TYPE, invokeKind, targetMethod, arguments, returnType);
         this.originalTargetMethod = originalTargetMethod;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -30,7 +30,6 @@
 import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.replacements.nodes.*;
 
 @NodeInfo
@@ -46,9 +45,8 @@
         return arguments.get(0);
     }
 
-    public static ConstantNode tryFold(ValueNode initialCallSite, MetaAccessProvider metaAccess, Assumptions assumptions) {
-        ValueNode callSite = GraphUtil.originalValue(initialCallSite);
-        if (callSite.isConstant() && !callSite.isNullConstant()) {
+    public static ConstantNode tryFold(ValueNode callSite, MetaAccessProvider metaAccess, Assumptions assumptions) {
+        if (callSite != null && callSite.isConstant() && !callSite.isNullConstant()) {
             HotSpotObjectConstant c = (HotSpotObjectConstant) callSite.asConstant();
             JavaConstant target = c.getCallSiteTarget(assumptions);
             if (target != null) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -256,7 +256,7 @@
                 throw GraalInternalError.shouldNotReachHere();
         }
 
-        MethodCallTargetNode callTarget = new ResolvedMethodHandleCallTargetNode(targetInvokeKind, target, targetArguments, targetReturnType, original, arguments, returnType);
+        MethodCallTargetNode callTarget = ResolvedMethodHandleCallTargetNode.create(targetInvokeKind, target, targetArguments, targetReturnType, original, arguments, returnType);
 
         // The call target can have a different return type than the invoker,
         // e.g. the target returns an Object but the invoker void. In this case
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Tue Mar 31 19:15:45 2015 -0700
@@ -180,8 +180,8 @@
                 try (Scope s0 = Debug.scope("StubCompilation", graph, providers.getCodeCache())) {
                     Suites defaultSuites = providers.getSuites().getDefaultSuites();
                     Suites suites = new Suites(new PhaseSuite<>(), defaultSuites.getMidTier(), defaultSuites.getLowTier());
-                    SchedulePhase schedule = emitFrontEnd(providers, target, graph, null, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph),
-                                    null, suites);
+                    SchedulePhase schedule = emitFrontEnd(providers, target, graph, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
+                                    suites);
                     LIRSuites lirSuites = createLIRSuites();
                     emitBackEnd(graph, Stub.this, incomingCc, getInstalledCodeOwner(), backend, target, compResult, CompilationResultBuilderFactory.Default, schedule, getRegisterConfig(), lirSuites);
                 } catch (Throwable e) {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java	Tue Mar 31 19:15:45 2015 -0700
@@ -58,6 +58,9 @@
         @Option(help = "Inlines trivial methods during bytecode parsing.", type = OptionType.Expert)
         public static final StableOptionValue<Boolean> InlineDuringParsing = new StableOptionValue<>(false);
 
+        @Option(help = "Inlines intrinsic methods during bytecode parsing.", type = OptionType.Expert)
+        public static final StableOptionValue<Boolean> InlineIntrinsicsDuringParsing = new StableOptionValue<>(true);
+
         @Option(help = "Traces inlining performed during bytecode parsing.", type = OptionType.Debug)
         public static final StableOptionValue<Boolean> TraceInlineDuringParsing = new StableOptionValue<>(false);
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Tue Mar 31 19:15:45 2015 -0700
@@ -206,7 +206,9 @@
         }
 
         public void replace(LIR lir, LIRInstruction replacement) {
-            lir.getLIRforBlock(block).set(index, replacement);
+            List<LIRInstruction> instructions = lir.getLIRforBlock(block);
+            assert instructions.get(index).equals(this) : String.format("Replacing the wrong instruction: %s instead of %s", instructions.get(index), this);
+            instructions.set(index, replacement);
         }
 
         @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Interval.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Interval.java	Tue Mar 31 19:15:45 2015 -0700
@@ -414,7 +414,7 @@
         }
 
         public void setRegisterPriority(int index, RegisterPriority registerPriority) {
-            list.set(index * 2, registerPriority.ordinal());
+            list.set((index << 1) + 1, registerPriority.ordinal());
         }
 
         @Override
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Tue Mar 31 19:15:45 2015 -0700
@@ -259,7 +259,7 @@
         Collection<AbstractBeginNode> blocks = new LinkedList<>();
         Collection<LoopExitNode> exits = new LinkedList<>();
         Queue<Block> work = new LinkedList<>();
-        ControlFlowGraph cfg = loopsData().controlFlowGraph();
+        ControlFlowGraph cfg = loopsData().getCFG();
         work.add(cfg.blockFor(branch));
         while (!work.isEmpty()) {
             Block b = work.remove();
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Tue Mar 31 19:15:45 2015 -0700
@@ -25,7 +25,6 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 
 import java.util.*;
-import java.util.function.*;
 
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
@@ -49,12 +48,12 @@
     }
 
     // TODO (gd) change when inversion is available
-    public static boolean shouldPeel(LoopEx loop, ToDoubleFunction<FixedNode> probabilities) {
+    public static boolean shouldPeel(LoopEx loop, ControlFlowGraph cfg) {
         if (loop.detectCounted()) {
             return false;
         }
         LoopBeginNode loopBegin = loop.loopBegin();
-        double entryProbability = probabilities.applyAsDouble(loopBegin.forwardEnd());
+        double entryProbability = cfg.blockFor(loopBegin.forwardEnd()).probability();
         if (entryProbability > MinimumPeelProbability.getValue() && loop.size() + loopBegin.graph().getNodeCount() < MaximumDesiredSize.getValue()) {
             // check whether we're allowed to peel this loop
             for (Node node : loop.inside().nodes()) {
@@ -120,7 +119,7 @@
                 // this may count twice because of fall-through in switches
                 inBranchTotal += loop.nodesInLoopBranch(branch).count();
             }
-            Block postDomBlock = loop.loopsData().controlFlowGraph().blockFor(controlSplit).getPostdominator();
+            Block postDomBlock = loop.loopsData().getCFG().blockFor(controlSplit).getPostdominator();
             if (postDomBlock != null) {
                 IsolatedInitialization.UNSWITCH_SPLIT_WITH_PHIS.increment();
                 phis += ((MergeNode) postDomBlock.getBeginNode()).phis().count();
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Tue Mar 31 19:15:45 2015 -0700
@@ -104,7 +104,7 @@
         }
     }
 
-    public ControlFlowGraph controlFlowGraph() {
+    public ControlFlowGraph getCFG() {
         return cfg;
     }
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopPeelingPhase.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopPeelingPhase.java	Tue Mar 31 19:15:45 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,23 +22,19 @@
  */
 package com.oracle.graal.loop.phases;
 
-import java.util.function.*;
-
 import com.oracle.graal.debug.*;
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.graph.*;
 
 public class LoopPeelingPhase extends Phase {
 
     @Override
     protected void run(StructuredGraph graph) {
         if (graph.hasLoops()) {
-            ToDoubleFunction<FixedNode> probabilities = new FixedNodeProbabilityCache();
             LoopsData data = new LoopsData(graph);
             for (LoopEx loop : data.outerFirst()) {
-                if (LoopPolicies.shouldPeel(loop, probabilities)) {
+                if (LoopPolicies.shouldPeel(loop, data.getCFG())) {
                     Debug.log("Peeling %s", loop);
                     LoopTransformations.peel(loop);
                     Debug.dump(graph, "After peeling %s", loop);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java	Tue Mar 31 19:15:45 2015 -0700
@@ -53,7 +53,7 @@
         }
         for (LoopEx loop : loops.countedLoops()) {
             for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) {
-                Block b = loops.controlFlowGraph().blockFor(loopEnd);
+                Block b = loops.getCFG().blockFor(loopEnd);
                 blocks: while (b != loop.loop().getHeader()) {
                     assert b != null;
                     for (FixedNode node : b.getNodes()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -304,7 +304,7 @@
                          */
                         JavaConstant positive = lessThan2.getX().asJavaConstant();
                         if (positive != null && positive.asLong() > 0 && positive.asLong() < positive.getKind().getMaxValue()) {
-                            ConstantNode newLimit = ConstantNode.forIntegerKind(positive.getKind(), positive.asLong() + 1, graph());
+                            ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(), positive.asLong() + 1, graph());
                             below = graph().unique(new IntegerBelowNode(lessThan.getX(), newLimit));
                         }
                     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -115,15 +115,12 @@
                     }
                 } else {
                     // x < y
-                    if (yStamp.isPositive()) {
+                    if (yStamp.isStrictlyPositive()) {
                         // x >= 0 && x < y
                         long xUpperBound = xStamp.upperBound();
                         long yUpperBound = yStamp.upperBound();
                         if (yUpperBound <= xUpperBound || !xStamp.isPositive()) {
-                            if (yUpperBound != 0) {
-                                yUpperBound--;
-                            }
-                            return new IntegerStamp(bits, Math.max(0, xStamp.lowerBound()), Math.min(xUpperBound, yUpperBound), xStamp.downMask(), xStamp.upMask());
+                            return new IntegerStamp(bits, Math.max(0, xStamp.lowerBound()), Math.min(xUpperBound, yUpperBound - 1), xStamp.downMask(), xStamp.upMask());
                         }
                     }
                 }
@@ -156,11 +153,11 @@
                     if (xStamp.isPositive() && yStamp.isPositive()) {
                         long xLowerBound = xStamp.lowerBound();
                         long yLowerBound = yStamp.lowerBound();
-                        if (xLowerBound >= yLowerBound) {
-                            if (xLowerBound != CodeUtil.maxValue(bits)) {
-                                xLowerBound++;
-                            }
-                            return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask());
+                        if (xLowerBound == CodeUtil.maxValue(bits)) {
+                            return null;
+                        } else if (xLowerBound >= yLowerBound) {
+                            assert xLowerBound != CodeUtil.maxValue(bits);
+                            return new IntegerStamp(bits, xLowerBound + 1, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask());
                         }
                     }
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -137,11 +137,11 @@
                     // x < y
                     long xUpperBound = xStamp.upperBound();
                     long yUpperBound = yStamp.upperBound();
-                    if (yUpperBound <= xUpperBound) {
-                        if (yUpperBound != CodeUtil.minValue(bits)) {
-                            yUpperBound--;
-                        }
-                        return new IntegerStamp(bits, xStamp.lowerBound(), yUpperBound, xStamp.downMask(), xStamp.upMask());
+                    if (yUpperBound == CodeUtil.minValue(bits)) {
+                        return null;
+                    } else if (yUpperBound <= xUpperBound) {
+                        assert yUpperBound != CodeUtil.minValue(bits);
+                        return new IntegerStamp(bits, xStamp.lowerBound(), yUpperBound - 1, xStamp.downMask(), xStamp.upMask());
                     }
                 }
             }
@@ -170,11 +170,11 @@
                     // y > x
                     long xLowerBound = xStamp.lowerBound();
                     long yLowerBound = yStamp.lowerBound();
-                    if (xLowerBound >= yLowerBound) {
-                        if (xLowerBound != CodeUtil.maxValue(bits)) {
-                            xLowerBound++;
-                        }
-                        return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask());
+                    if (xLowerBound == CodeUtil.maxValue(bits)) {
+                        return null;
+                    } else if (xLowerBound >= yLowerBound) {
+                        assert xLowerBound != CodeUtil.maxValue(bits);
+                        return new IntegerStamp(bits, xLowerBound + 1, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask());
                     }
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Tue Mar 31 19:15:45 2015 -0700
@@ -118,6 +118,10 @@
         return nodeToBlock.get(node);
     }
 
+    public double frequencyFor(FixedNode node) {
+        return blockFor(node).probability();
+    }
+
     public List<Loop<Block>> getLoops() {
         return loops;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -85,8 +85,7 @@
     @Override
     public boolean verify() {
         MemoryNode lla = getLastLocationAccess();
-        assert lla == null || lla instanceof MemoryCheckpoint || lla instanceof MemoryProxy || lla instanceof MemoryPhiNode : "lastLocationAccess of " + this +
-                        " should be a MemoryCheckpoint, but is " + lla;
+        assert lla != null || getLocationIdentity().isImmutable() : "lastLocationAccess of " + this + " shouldn't be null for mutable location identity " + getLocationIdentity();
         return super.verify();
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -29,6 +29,7 @@
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
 
 @NodeInfo
 public final class UnboxNode extends FixedWithNextNode implements Virtualizable, Lowerable, Canonicalizable.Unary<ValueNode> {
@@ -78,6 +79,9 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+        if (hasNoUsages() && StampTool.isPointerNonNull(forValue)) {
+            return null;
+        }
         ValueNode synonym = findSynonym(tool.getMetaAccess(), tool.getConstantReflection(), forValue, boxingKind);
         if (synonym != null) {
             return synonym;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Mar 31 19:15:45 2015 -0700
@@ -122,7 +122,7 @@
 
     /**
      * Checks whether this {@link Stamp} represents a {@linkplain Stamp#isLegal() legal} pointer
-     * stamp whose values known to be always null.
+     * stamp whose values are known to never be null.
      *
      * @param stamp the stamp to check
      * @return true if this stamp represents a legal object stamp whose values are known to be
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Tue Mar 31 19:15:45 2015 -0700
@@ -289,9 +289,8 @@
                     MemoryAccess access = (MemoryAccess) node;
                     if (access.getLastLocationAccess() == anchor) {
                         MemoryNode lastLocationAccess = state.getLastLocationAccess(access.getLocationIdentity());
-                        if (lastLocationAccess != null) {
-                            access.setLastLocationAccess(lastLocationAccess);
-                        }
+                        assert lastLocationAccess != null;
+                        access.setLastLocationAccess(lastLocationAccess);
                     }
                 }
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java	Tue Mar 31 19:15:45 2015 -0700
@@ -23,7 +23,6 @@
 package com.oracle.graal.phases.common;
 
 import java.util.*;
-import java.util.function.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.graph.*;
@@ -36,7 +35,6 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.schedule.*;
 
 /**
@@ -63,15 +61,14 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        ToDoubleFunction<FixedNode> probabilities = new FixedNodeProbabilityCache();
         SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph, false);
 
         ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
         for (Loop<Block> loop : cfg.getLoops()) {
-            double loopProbability = probabilities.applyAsDouble(loop.getHeader().getBeginNode());
+            double loopProbability = cfg.blockFor(loop.getHeader().getBeginNode()).probability();
             if (loopProbability > (1D / Integer.MAX_VALUE)) {
-                addSectionCounters(loop.getHeader().getBeginNode(), loop.getBlocks(), loop.getChildren(), schedule, probabilities);
+                addSectionCounters(loop.getHeader().getBeginNode(), loop.getBlocks(), loop.getChildren(), schedule, cfg);
             }
         }
         // don't put the counter increase directly after the start (problems with OSR)
@@ -79,7 +76,7 @@
         while (current.next() instanceof FixedWithNextNode) {
             current = (FixedWithNextNode) current.next();
         }
-        addSectionCounters(current, cfg.getBlocks(), cfg.getLoops(), schedule, probabilities);
+        addSectionCounters(current, cfg.getBlocks(), cfg.getLoops(), schedule, cfg);
 
         if (WITH_INVOKES) {
             for (Node node : graph.getNodes()) {
@@ -92,13 +89,12 @@
         }
     }
 
-    private static void addSectionCounters(FixedWithNextNode start, Collection<Block> sectionBlocks, Collection<Loop<Block>> childLoops, SchedulePhase schedule,
-                    ToDoubleFunction<FixedNode> probabilities) {
+    private static void addSectionCounters(FixedWithNextNode start, Collection<Block> sectionBlocks, Collection<Loop<Block>> childLoops, SchedulePhase schedule, ControlFlowGraph cfg) {
         HashSet<Block> blocks = new HashSet<>(sectionBlocks);
         for (Loop<?> loop : childLoops) {
             blocks.removeAll(loop.getBlocks());
         }
-        double weight = getSectionWeight(schedule, probabilities, blocks) / probabilities.applyAsDouble(start);
+        double weight = getSectionWeight(schedule, blocks) / cfg.blockFor(start).probability();
         DynamicCounterNode.addCounterBefore(GROUP_NAME, sectionHead(start), (long) weight, true, start.next());
         if (WITH_INVOKE_FREE_SECTIONS && !hasInvoke(blocks)) {
             DynamicCounterNode.addCounterBefore(GROUP_NAME_WITHOUT, sectionHead(start), (long) weight, true, start.next());
@@ -113,10 +109,10 @@
         }
     }
 
-    private static double getSectionWeight(SchedulePhase schedule, ToDoubleFunction<FixedNode> probabilities, Collection<Block> blocks) {
+    private static double getSectionWeight(SchedulePhase schedule, Collection<Block> blocks) {
         double count = 0;
         for (Block block : blocks) {
-            double blockProbability = probabilities.applyAsDouble(block.getBeginNode());
+            double blockProbability = block.probability();
             for (Node node : schedule.getBlockToNodesMap().get(block)) {
                 count += blockProbability * getNodeWeight(node);
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Tue Mar 31 19:15:45 2015 -0700
@@ -75,10 +75,6 @@
         if (result != null) {
             return result;
         }
-        result = getCachedGraph(method, context);
-        if (result != null) {
-            return result;
-        }
         return parseBytecodes(method, context, canonicalizer, caller);
     }
 
@@ -181,18 +177,6 @@
         return result;
     }
 
-    private static StructuredGraph getCachedGraph(ResolvedJavaMethod method, HighTierContext context) {
-        if (context.getGraphCache() != null) {
-            StructuredGraph cachedGraph = context.getGraphCache().get(method);
-            if (cachedGraph != null) {
-                // TODO: check that cachedGraph.getAssumptions() are still valid
-                // instead of waiting for code installation to do it.
-                return cachedGraph;
-            }
-        }
-        return null;
-    }
-
     /**
      * This method builds the IR nodes for the given <code>method</code> and canonicalizes them.
      * Provided profiling info is mature, the resulting graph is cached. The caller is responsible
@@ -219,9 +203,6 @@
                 canonicalizer.apply(newGraph, context);
             }
 
-            if (context.getGraphCache() != null) {
-                context.getGraphCache().put(newGraph.method(), newGraph);
-            }
             return newGraph;
         } catch (Throwable e) {
             throw Debug.handle(e);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java	Tue Mar 31 19:15:45 2015 -0700
@@ -73,6 +73,53 @@
         assert node != null;
         metricComputeNodeProbability.increment();
 
+        FixedNode current = findBegin(node);
+        if (current == null) {
+            // this should only appear for dead code
+            return 1D;
+        }
+
+        assert current instanceof AbstractBeginNode;
+        Double cachedValue = cache.get(current);
+        if (cachedValue != null) {
+            return cachedValue;
+        }
+
+        double probability = 0.0;
+        if (current.predecessor() == null) {
+            if (current instanceof AbstractMergeNode) {
+                probability = handleMerge(current, probability);
+            } else {
+                assert current instanceof StartNode;
+                probability = 1D;
+            }
+        } else {
+            ControlSplitNode split = (ControlSplitNode) current.predecessor();
+            probability = split.probability((AbstractBeginNode) current) * applyAsDouble(split);
+        }
+        assert !Double.isNaN(probability) && !Double.isInfinite(probability) : current + " " + probability;
+        cache.put(current, probability);
+        return probability;
+    }
+
+    private double handleMerge(FixedNode current, double probability) {
+        double result = probability;
+        AbstractMergeNode currentMerge = (AbstractMergeNode) current;
+        NodeInputList<EndNode> currentForwardEnds = currentMerge.forwardEnds();
+        /*
+         * Use simple iteration instead of streams, since the stream infrastructure adds many frames
+         * which causes the recursion to overflow the stack earlier than it would otherwise.
+         */
+        for (AbstractEndNode endNode : currentForwardEnds) {
+            result += applyAsDouble(endNode);
+        }
+        if (current instanceof LoopBeginNode) {
+            result *= ((LoopBeginNode) current).loopFrequency();
+        }
+        return result;
+    }
+
+    private static FixedNode findBegin(FixedNode node) {
         FixedNode current = node;
         while (true) {
             assert current != null;
@@ -85,44 +132,11 @@
                     break;
                 }
             } else if (predecessor == null) {
-                // this should only appear for dead code
-                return 1D;
+                current = null;
+                break;
             }
             current = (FixedNode) predecessor;
         }
-
-        assert current instanceof AbstractBeginNode;
-        Double cachedValue = cache.get(current);
-        if (cachedValue != null) {
-            return cachedValue;
-        }
-
-        double probability = 0.0;
-        if (current.predecessor() == null) {
-            if (current instanceof AbstractMergeNode) {
-                AbstractMergeNode currentMerge = (AbstractMergeNode) current;
-                NodeInputList<EndNode> currentForwardEnds = currentMerge.forwardEnds();
-                /*
-                 * Use simple iteration instead of streams, since the stream infrastructure adds
-                 * many frames which causes the recursion to overflow the stack earlier than it
-                 * would otherwise.
-                 */
-                for (AbstractEndNode endNode : currentForwardEnds) {
-                    probability += applyAsDouble(endNode);
-                }
-                if (current instanceof LoopBeginNode) {
-                    probability *= ((LoopBeginNode) current).loopFrequency();
-                }
-            } else {
-                assert current instanceof StartNode;
-                probability = 1D;
-            }
-        } else {
-            ControlSplitNode split = (ControlSplitNode) current.predecessor();
-            probability = split.probability((AbstractBeginNode) current) * applyAsDouble(split);
-        }
-        assert !Double.isNaN(probability) && !Double.isInfinite(probability) : current + " " + probability;
-        cache.put(current, probability);
-        return probability;
+        return current;
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/MemoryScheduleVerification.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/MemoryScheduleVerification.java	Tue Mar 31 19:15:45 2015 -0700
@@ -31,7 +31,6 @@
 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.phases.graph.*;
 import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
 
@@ -78,7 +77,7 @@
                 }
 
                 addFloatingReadUsages(currentState, n);
-            } else if (n instanceof MemoryProxy) {
+            } else if (n instanceof MemoryNode) {
                 addFloatingReadUsages(currentState, n);
             } else if (n instanceof FloatingReadNode) {
                 FloatingReadNode floatingReadNode = (FloatingReadNode) n;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Tue Mar 31 19:15:45 2015 -0700
@@ -22,10 +22,6 @@
  */
 package com.oracle.graal.phases.tiers;
 
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
 
@@ -33,12 +29,10 @@
 
     private final PhaseSuite<HighTierContext> graphBuilderSuite;
 
-    private final Map<ResolvedJavaMethod, StructuredGraph> cache;
     private final OptimisticOptimizations optimisticOpts;
 
-    public HighTierContext(Providers providers, Map<ResolvedJavaMethod, StructuredGraph> cache, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts) {
+    public HighTierContext(Providers providers, PhaseSuite<HighTierContext> graphBuilderSuite, OptimisticOptimizations optimisticOpts) {
         super(providers);
-        this.cache = cache;
         this.graphBuilderSuite = graphBuilderSuite;
         this.optimisticOpts = optimisticOpts;
     }
@@ -47,10 +41,6 @@
         return graphBuilderSuite;
     }
 
-    public Map<ResolvedJavaMethod, StructuredGraph> getGraphCache() {
-        return cache;
-    }
-
     public OptimisticOptimizations getOptimisticOptimizations() {
         return optimisticOpts;
     }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Tue Mar 31 19:15:45 2015 -0700
@@ -30,15 +30,12 @@
 import java.nio.channels.*;
 import java.util.*;
 import java.util.Map.Entry;
-import java.util.function.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.cfg.*;
 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.schedule.*;
 
 public class BinaryGraphPrinter implements GraphPrinter {
@@ -143,7 +140,7 @@
         BlockMap<List<Node>> blockToNodes = schedule == null ? null : schedule.getBlockToNodesMap();
         NodeMap<Block> nodeToBlocks = schedule == null ? null : schedule.getNodeToBlockMap();
         List<Block> blocks = cfg == null ? null : cfg.getBlocks();
-        writeNodes(graph, nodeToBlocks);
+        writeNodes(graph, nodeToBlocks, cfg);
         writeBlocks(blocks, blockToNodes);
     }
 
@@ -400,14 +397,7 @@
         return node.getId();
     }
 
-    private void writeNodes(Graph graph, NodeMap<Block> nodeToBlocks) throws IOException {
-        ToDoubleFunction<FixedNode> probabilities = null;
-        if (PrintGraphProbabilities.getValue()) {
-            try {
-                probabilities = new FixedNodeProbabilityCache();
-            } catch (Throwable t) {
-            }
-        }
+    private void writeNodes(Graph graph, NodeMap<Block> nodeToBlocks, ControlFlowGraph cfg) throws IOException {
         Map<Object, Object> props = new HashMap<>();
 
         writeInt(graph.getNodeCount());
@@ -415,9 +405,9 @@
         for (Node node : graph.getNodes()) {
             NodeClass<?> nodeClass = node.getNodeClass();
             node.getDebugProperties(props);
-            if (probabilities != null && node instanceof FixedNode) {
+            if (cfg != null && PrintGraphProbabilities.getValue() && node instanceof FixedNode) {
                 try {
-                    props.put("probability", probabilities.applyAsDouble((FixedNode) node));
+                    props.put("probability", cfg.blockFor(node).probability());
                 } catch (Throwable t) {
                     props.put("probability", t);
                 }
@@ -432,6 +422,29 @@
                     }
                 }
             }
+
+            if (node instanceof ControlSinkNode) {
+                props.put("category", "controlSink");
+            } else if (node instanceof ControlSplitNode) {
+                props.put("category", "controlSplit");
+            } else if (node instanceof AbstractMergeNode) {
+                props.put("category", "merge");
+            } else if (node instanceof AbstractBeginNode) {
+                props.put("category", "begin");
+            } else if (node instanceof AbstractEndNode) {
+                props.put("category", "end");
+            } else if (node instanceof FixedNode) {
+                props.put("category", "fixed");
+            } else if (node instanceof VirtualState) {
+                props.put("category", "state");
+            } else if (node instanceof PhiNode) {
+                props.put("category", "phi");
+            } else if (node instanceof ProxyNode) {
+                props.put("category", "proxy");
+            } else {
+                props.put("category", "floating");
+            }
+
             writeInt(getNodeId(node));
             writePoolObject(nodeClass);
             writeByte(node.predecessor() == null ? 0 : 1);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -331,7 +331,7 @@
     @Test
     public void testCanonicalLength() {
         StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
 
@@ -347,7 +347,7 @@
     @Test
     public void testCanonicalEqual() {
         StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
 
@@ -361,7 +361,7 @@
     @Test
     public void testVirtualEqual() {
         StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
         new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context);
@@ -379,7 +379,7 @@
     @Test
     public void testVirtualNotEqual() {
         StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
         new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -29,7 +29,6 @@
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -248,7 +247,7 @@
      */
     private ValueNode parseAndInline(String name, Class<? extends ValueNode> expectedClass) {
         StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE);
+        HighTierContext context = getDefaultHighTierContext();
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
         canonicalizer.apply(graph, context);
         new InliningPhase(canonicalizer).apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -34,7 +34,6 @@
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.common.inlining.policy.*;
@@ -115,7 +114,7 @@
 
         ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         StructuredGraph g = parseProfiled(javaMethod, AllowAssumptions.NO);
-        HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+        HighTierContext context = getDefaultHighTierContext();
         new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase()).apply(g, context);
         new CanonicalizerPhase().apply(g, context);
         Assert.assertTrue(g.getNodes().filter(CheckCastNode.class).isEmpty());
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -33,7 +33,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -48,7 +47,7 @@
     protected StructuredGraph testGraph(final String snippet) {
         try (Scope s = Debug.scope("MethodSubstitutionTest", getResolvedJavaMethod(snippet))) {
             StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
-            HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL);
+            HighTierContext context = getDefaultHighTierContext();
             Debug.dump(graph, "Graph");
             new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
             Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Tue Mar 31 19:15:45 2015 -0700
@@ -397,7 +397,7 @@
     }
 
     private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
-        HighTierContext context = new HighTierContext(getProviders(), null, null, OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL);
 
         StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES);
         new CanonicalizerPhase().apply(graph, context);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Tue Mar 31 19:15:45 2015 -0700
@@ -208,7 +208,7 @@
         }
 
         @Override
-        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) {
+        public void replace(ValueNode oldNode, ValueNode newNode) {
             assert newNode instanceof PhiNode;
             assert oldNode == instanceOf;
             newNode.inferStamp();
@@ -239,7 +239,7 @@
         }
 
         @Override
-        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) {
+        public void replace(ValueNode oldNode, ValueNode newNode) {
             assert newNode instanceof PhiNode;
             assert oldNode == instanceOf;
             newNode.inferStamp();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Mar 31 19:15:45 2015 -0700
@@ -97,7 +97,7 @@
     public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) {
         ResolvedJavaMethod subst = getMethodSubstitutionMethod(method);
         if (subst != null) {
-            if (b.parsingReplacement() || InlineDuringParsing.getValue()) {
+            if (b.parsingReplacement() || InlineDuringParsing.getValue() || InlineIntrinsicsDuringParsing.getValue()) {
                 // Forced inlining of intrinsics
                 return new InlineInfo(subst, true, true);
             }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Tue Mar 31 19:15:45 2015 -0700
@@ -722,18 +722,20 @@
 
         new FloatingReadPhase(false, true).apply(snippetCopy);
 
-        MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode());
-        snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor);
+        MemoryAnchorNode anchor = snippetCopy.add(new MemoryAnchorNode());
+        snippetCopy.start().replaceAtUsages(InputType.Memory, anchor);
 
         this.snippet = snippetCopy;
 
         Debug.dump(snippet, "SnippetTemplate after fixing memory anchoring");
 
         StartNode entryPointNode = snippet.start();
-        if (memoryAnchor.hasNoUsages()) {
-            memoryAnchor.safeDelete();
+        if (anchor.hasNoUsages()) {
+            anchor.safeDelete();
+            this.memoryAnchor = null;
         } else {
-            snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor);
+            snippetCopy.addAfterFixed(snippetCopy.start(), anchor);
+            this.memoryAnchor = anchor;
         }
         List<ReturnNode> returnNodes = snippet.getNodes(ReturnNode.TYPE).snapshot();
         if (returnNodes.isEmpty()) {
@@ -832,6 +834,11 @@
     private final ReturnNode returnNode;
 
     /**
+     * The memory anchor (if any) of the snippet.
+     */
+    private final MemoryAnchorNode memoryAnchor;
+
+    /**
      * Nodes that inherit the {@link StateSplit#stateAfter()} from the replacee during
      * instantiation.
      */
@@ -948,7 +955,7 @@
         /**
          * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}.
          */
-        void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap);
+        void replace(ValueNode oldNode, ValueNode newNode);
     }
 
     /**
@@ -957,48 +964,8 @@
      */
     public static final UsageReplacer DEFAULT_REPLACER = new UsageReplacer() {
 
-        private LocationIdentity getLocationIdentity(Node node) {
-            if (node instanceof MemoryAccess) {
-                return ((MemoryAccess) node).getLocationIdentity();
-            } else if (node instanceof MemoryProxy) {
-                return ((MemoryProxy) node).getLocationIdentity();
-            } else if (node instanceof MemoryPhiNode) {
-                return ((MemoryPhiNode) node).getLocationIdentity();
-            } else {
-                return null;
-            }
-        }
-
         @Override
-        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) {
-            if (mmap != null) {
-                for (Node usage : oldNode.usages().snapshot()) {
-                    LocationIdentity identity = getLocationIdentity(usage);
-                    boolean usageReplaced = false;
-                    if (identity != null && !identity.isImmutable()) {
-                        // lastLocationAccess points into the snippet graph. find a proper
-                        // MemoryCheckPoint inside the snippet graph
-                        MemoryNode lastAccess = mmap.getLastLocationAccess(identity);
-
-                        assert lastAccess != null : "no mapping found for lowerable node " + oldNode + ". (No node in the snippet kills the same location as the lowerable node?)";
-                        if (usage instanceof MemoryAccess) {
-                            MemoryAccess access = (MemoryAccess) usage;
-                            if (access.getLastLocationAccess() == oldNode) {
-                                assert oldNode.graph().isAfterFloatingReadPhase();
-                                access.setLastLocationAccess(lastAccess);
-                                usageReplaced = true;
-                            }
-                        } else {
-                            assert usage instanceof MemoryProxy || usage instanceof MemoryPhiNode;
-                            usage.replaceFirstInput(oldNode, lastAccess.asNode());
-                            usageReplaced = true;
-                        }
-                    }
-                    if (!usageReplaced) {
-                        assert newNode != null : "this branch is only valid if we have a newNode for replacement";
-                    }
-                }
-            }
+        public void replace(ValueNode oldNode, ValueNode newNode) {
             if (newNode == null) {
                 assert oldNode.hasNoUsages();
             } else {
@@ -1066,14 +1033,48 @@
         return true;
     }
 
-    private class DuplicateMapper implements MemoryMap {
+    private static class MemoryInputMap implements MemoryMap {
+
+        private final LocationIdentity locationIdentity;
+        private final MemoryNode lastLocationAccess;
+
+        public MemoryInputMap(ValueNode replacee) {
+            if (replacee instanceof MemoryAccess) {
+                MemoryAccess access = (MemoryAccess) replacee;
+                locationIdentity = access.getLocationIdentity();
+                lastLocationAccess = access.getLastLocationAccess();
+            } else {
+                locationIdentity = null;
+                lastLocationAccess = null;
+            }
+        }
+
+        @Override
+        public MemoryNode getLastLocationAccess(LocationIdentity location) {
+            if (locationIdentity != null && locationIdentity.equals(location)) {
+                return lastLocationAccess;
+            } else {
+                return null;
+            }
+        }
+
+        @Override
+        public Collection<LocationIdentity> getLocations() {
+            if (locationIdentity == null) {
+                return Collections.emptySet();
+            } else {
+                return Collections.singleton(locationIdentity);
+            }
+        }
+    }
+
+    private class MemoryOutputMap extends MemoryInputMap {
 
         private final Map<Node, Node> duplicates;
-        private StartNode replaceeStart;
 
-        public DuplicateMapper(Map<Node, Node> duplicates, StartNode replaceeStart) {
+        public MemoryOutputMap(ValueNode replacee, Map<Node, Node> duplicates) {
+            super(replacee);
             this.duplicates = duplicates;
-            this.replaceeStart = replaceeStart;
         }
 
         @Override
@@ -1081,9 +1082,9 @@
             MemoryMapNode memoryMap = returnNode.getMemoryMap();
             assert memoryMap != null : "no memory map stored for this snippet graph (snippet doesn't have a ReturnNode?)";
             MemoryNode lastLocationAccess = memoryMap.getLastLocationAccess(locationIdentity);
-            assert lastLocationAccess != null;
-            if (lastLocationAccess instanceof StartNode) {
-                return replaceeStart;
+            assert lastLocationAccess != null : locationIdentity;
+            if (lastLocationAccess == memoryAnchor) {
+                return super.getLastLocationAccess(locationIdentity);
             } else {
                 return (MemoryNode) duplicates.get(ValueNodeUtil.asNode(lastLocationAccess));
             }
@@ -1095,6 +1096,60 @@
         }
     }
 
+    private void rewireMemoryGraph(ValueNode replacee, Map<Node, Node> duplicates) {
+        // rewire outgoing memory edges
+        replaceMemoryUsages(replacee, new MemoryOutputMap(replacee, duplicates));
+
+        ReturnNode ret = (ReturnNode) duplicates.get(returnNode);
+        MemoryMapNode memoryMap = ret.getMemoryMap();
+        ret.setMemoryMap(null);
+        memoryMap.safeDelete();
+
+        if (memoryAnchor != null) {
+            // rewire incoming memory edges
+            MemoryAnchorNode memoryDuplicate = (MemoryAnchorNode) duplicates.get(memoryAnchor);
+            replaceMemoryUsages(memoryDuplicate, new MemoryInputMap(replacee));
+
+            if (memoryDuplicate.hasNoUsages()) {
+                memoryDuplicate.graph().removeFixed(memoryDuplicate);
+            }
+        }
+    }
+
+    private static LocationIdentity getLocationIdentity(Node node) {
+        if (node instanceof MemoryAccess) {
+            return ((MemoryAccess) node).getLocationIdentity();
+        } else if (node instanceof MemoryProxy) {
+            return ((MemoryProxy) node).getLocationIdentity();
+        } else if (node instanceof MemoryPhiNode) {
+            return ((MemoryPhiNode) node).getLocationIdentity();
+        } else {
+            return null;
+        }
+    }
+
+    private static void replaceMemoryUsages(ValueNode node, MemoryMap map) {
+        for (Node usage : node.usages().snapshot()) {
+            if (usage instanceof MemoryMapNode) {
+                continue;
+            }
+
+            LocationIdentity location = getLocationIdentity(usage);
+            if (location != null) {
+                NodePosIterator iter = usage.inputs().iterator();
+                while (iter.hasNext()) {
+                    Position pos = iter.nextPosition();
+                    if (pos.getInputType() == InputType.Memory && pos.get(usage) == node) {
+                        MemoryNode replacement = map.getLastLocationAccess(location);
+                        if (replacement != null) {
+                            pos.set(usage, replacement.asNode());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Replaces a given fixed node with this specialized snippet.
      *
@@ -1181,17 +1236,18 @@
 
             updateStamps(replacee, duplicates);
 
+            rewireMemoryGraph(replacee, duplicates);
+
             // Replace all usages of the replacee with the value returned by the snippet
             ValueNode returnValue = null;
             if (returnNode != null && !(replacee instanceof ControlSinkNode)) {
                 ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode);
                 returnValue = returnDuplicate.result();
-                MemoryMap mmap = new DuplicateMapper(duplicates, replaceeGraph.start());
                 if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) {
-                    replacer.replace(replacee, null, mmap);
+                    replacer.replace(replacee, null);
                 } else {
                     assert returnValue != null || replacee.hasNoUsages();
-                    replacer.replace(replacee, returnValue, mmap);
+                    replacer.replace(replacee, returnValue);
                 }
                 if (returnDuplicate.isAlive()) {
                     FixedNode next = null;
@@ -1284,11 +1340,13 @@
             }
             updateStamps(replacee, duplicates);
 
+            rewireMemoryGraph(replacee, duplicates);
+
             // Replace all usages of the replacee with the value returned by the snippet
             ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode);
             ValueNode returnValue = returnDuplicate.result();
             assert returnValue != null || replacee.hasNoUsages();
-            replacer.replace(replacee, returnValue, new DuplicateMapper(duplicates, replaceeGraph.start()));
+            replacer.replace(replacee, returnValue);
 
             if (returnDuplicate.isAlive()) {
                 returnDuplicate.replaceAndDelete(next);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -80,7 +80,7 @@
                 if (state1.getVirtualObject() == state2.getVirtualObject()) {
                     // the same virtual objects will always have the same contents
                     tool.replaceWithValue(ConstantNode.forBoolean(true, graph()));
-                } else if (state1.getVirtualObject().entryCount() == state2.getVirtualObject().entryCount()) {
+                } else if (state1.getVirtualObject().entryCount() == state2.getVirtualObject().entryCount() && state1.getState() == EscapeState.Virtual && state2.getState() == EscapeState.Virtual) {
                     int entryCount = state1.getVirtualObject().entryCount();
                     boolean allEqual = true;
                     for (int i = 0; i < entryCount; i++) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -79,8 +79,10 @@
 
     public void generate(NodeLIRBuilderTool generator) {
         assert compileTimeAssertion;
-        if (value.isConstant() && value.asJavaConstant().asInt() == 0) {
-            throw new GraalInternalError("%s: failed compile-time assertion: %s", this, message);
+        if (value.isConstant()) {
+            if (value.asJavaConstant().asInt() == 0) {
+                throw new GraalInternalError("%s: failed compile-time assertion: %s", this, message);
+            }
         } else {
             throw new GraalInternalError("%s: failed compile-time assertion (value %s): %s", this, value, message);
         }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +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.truffle.hotspot;
-
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.runtime.*;
-import com.oracle.graal.truffle.*;
-
-public final class HotSpotTruffleReplacements extends TruffleReplacements {
-
-    private HotSpotTruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) {
-        super(providers, snippetReflection);
-    }
-
-    public static Replacements makeInstance() {
-        Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders();
-        SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class);
-        return new HotSpotTruffleReplacements(providers, snippetReflection);
-    }
-}
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Tue Mar 31 19:15:45 2015 -0700
@@ -50,7 +50,6 @@
 import com.oracle.graal.lir.phases.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.tiers.*;
@@ -74,7 +73,6 @@
     }
 
     private TruffleCompilerImpl truffleCompiler;
-    private Replacements truffleReplacements;
     private Map<OptimizedCallTarget, Future<?>> compilations = newIdentityMap();
     private final ThreadPoolExecutor compileQueue;
 
@@ -83,7 +81,6 @@
 
     private HotSpotTruffleRuntime() {
         installOptimizedCallTargetCallMethod();
-        installOptimizedCallTargetCallDirect();
         lookupCallMethods(getGraalProviders().getMetaAccess());
 
         installDefaultListeners();
@@ -115,12 +112,6 @@
 
     }
 
-    private static void installOptimizedCallTargetCallDirect() {
-        if (TruffleCompilerOptions.TruffleFunctionInlining.getValue() && !TruffleCompilerOptions.FastPE.getValue()) {
-            ((HotSpotResolvedJavaMethod) getGraalProviders().getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod())).setNotInlineable();
-        }
-    }
-
     @Override
     public String getName() {
         return "Graal Truffle Runtime";
@@ -150,14 +141,6 @@
         return createCallTargetImpl(source, root);
     }
 
-    @Override
-    public Replacements getReplacements() {
-        if (truffleReplacements == null) {
-            truffleReplacements = HotSpotTruffleReplacements.makeInstance();
-        }
-        return truffleReplacements;
-    }
-
     public static void installOptimizedCallTargetCallMethod() {
         Providers providers = getGraalProviders();
         MetaAccessProvider metaAccess = providers.getMetaAccess();
@@ -203,8 +186,8 @@
         CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
         Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
         CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod);
-        return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null,
-                        suites, lirSuites, new CompilationResult(), factory);
+        return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null, suites,
+                        lirSuites, new CompilationResult(), factory);
     }
 
     private static HotSpotProviders getGraalProviders() {
@@ -232,11 +215,15 @@
         Runnable r = new Runnable() {
             @Override
             public void run() {
+                boolean success = true;
                 try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(optimizedCallTarget))) {
                     truffleCompiler.compileMethod(optimizedCallTarget);
-                    optimizedCallTarget.notifyCompilationFinished();
                 } catch (Throwable e) {
                     optimizedCallTarget.notifyCompilationFailed(e);
+                    success = false;
+                } finally {
+                    optimizedCallTarget.notifyCompilationFinished(success);
+
                 }
             }
         };
@@ -265,7 +252,10 @@
         if (codeTask != null && isCompiling(optimizedCallTarget)) {
             this.compilations.remove(optimizedCallTarget);
             boolean result = codeTask.cancel(true);
-            getCompilationNotify().notifyCompilationDequeued(optimizedCallTarget, source, reason);
+            if (result) {
+                optimizedCallTarget.notifyCompilationFinished(false);
+                getCompilationNotify().notifyCompilationDequeued(optimizedCallTarget, source, reason);
+            }
             return result;
         }
         return false;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.test/sl/TestOSR.sl	Tue Mar 31 19:15:45 2015 -0700
@@ -0,0 +1,13 @@
+function test() {
+  i = 0;
+  sum = 0;  
+  while (i < 300000) { 
+    sum = sum +  i;
+    i = i + 1;  
+  }
+  return sum;
+}
+
+function main() {  
+  test();
+}  
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java	Tue Mar 31 19:15:45 2015 -0700
@@ -29,7 +29,7 @@
 public class DefaultLoopNodeFactory implements LoopNodeFactory {
 
     public LoopNode create(RepeatingNode repeatingNode) {
-        return new OptimizedLoopNode(repeatingNode);
+        return OptimizedOSRLoopNode.create(repeatingNode);
     }
 
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Tue Mar 31 19:15:45 2015 -0700
@@ -32,7 +32,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.truffle.debug.*;
 import com.oracle.graal.truffle.unsafe.*;
 import com.oracle.truffle.api.*;
@@ -270,8 +269,6 @@
 
     public abstract Collection<OptimizedCallTarget> getQueuedCallTargets();
 
-    public abstract Replacements getReplacements();
-
     public abstract void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous);
 
     public abstract boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget, Object source, CharSequence reason);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Tue Mar 31 19:15:45 2015 -0700
@@ -27,7 +27,6 @@
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
-import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 import java.util.stream.*;
 
@@ -72,6 +71,7 @@
 
     private TruffleInlining inlining;
     private int cachedNonTrivialNodeCount = -1;
+    private boolean compiling;
 
     /**
      * When this call target is inlined, the inlining {@link InstalledCode} registers this
@@ -102,6 +102,10 @@
         this.nodeRewritingAssumption = new CyclicAssumption("nodeRewritingAssumption of " + rootNode.toString());
     }
 
+    public final boolean isCompiling() {
+        return compiling;
+    }
+
     private static RootNode cloneRootNode(RootNode root) {
         if (root == null || !root.isCloningAllowed()) {
             return null;
@@ -174,7 +178,7 @@
     }
 
     @ExplodeLoop
-    private void profileArguments(Object[] args) {
+    void profileArguments(Object[] args) {
         if (profiledArgumentTypesAssumption == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
             initializeProfiledArgumentTypes(args);
@@ -272,7 +276,12 @@
         VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args);
         Object result = callProxy(frame);
 
-        // Profile call return type
+        profileReturnType(result);
+
+        return result;
+    }
+
+    void profileReturnType(Object result) {
         if (profiledReturnTypeAssumption == null) {
             if (TruffleReturnTypeSpeculation.getValue()) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -286,8 +295,6 @@
                 profiledReturnTypeAssumption.invalidate();
             }
         }
-
-        return result;
     }
 
     @Override
@@ -321,25 +328,16 @@
             this.runtime.reinstallStubs();
         } else {
             compilationProfile.reportInterpreterCall();
-            if (compilationPolicy.shouldCompile(compilationProfile, getCompilerOptions())) {
+            if (!isCompiling() && compilationPolicy.shouldCompile(compilationProfile, getCompilerOptions())) {
                 compile();
             }
         }
     }
 
     public void compile() {
-        compile(TruffleBackgroundCompilation.getValue() && !TruffleCompilationExceptionsAreThrown.getValue());
-    }
-
-    public void compile(boolean mayBeAsynchronous) {
-        if (!runtime.isCompiling(this)) {
-            runtime.compile(this, mayBeAsynchronous);
-        } else if (!mayBeAsynchronous && runtime.isCompiling(this)) {
-            try {
-                runtime.waitForCompilation(this, 20000);
-            } catch (ExecutionException | TimeoutException e) {
-                Debug.log(3, e.getMessage());
-            }
+        if (!isCompiling()) {
+            compiling = true;
+            runtime.compile(this, TruffleBackgroundCompilation.getValue() && !TruffleCompilationExceptionsAreThrown.getValue());
         }
     }
 
@@ -363,11 +361,11 @@
         }
     }
 
-    public void notifyCompilationFinished() {
-        // Compilation was successful.
-        if (inlining != null) {
+    public void notifyCompilationFinished(boolean successful) {
+        if (successful && inlining != null) {
             dequeueInlinedCallSites(inlining);
         }
+        compiling = false;
     }
 
     private void dequeueInlinedCallSites(TruffleInlining parentDecision) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedOSRLoopNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+
+public final class OptimizedOSRLoopNode extends LoopNode implements ReplaceObserver {
+
+    private static final int OSR_THRESHOLD = TruffleCompilerOptions.TruffleOSRCompilationThreshold.getValue();
+
+    private int interpreterLoopCount;
+    private OptimizedCallTarget compiledTarget;
+
+    @Child private RepeatingNode repeatableNode;
+
+    private OptimizedOSRLoopNode(RepeatingNode repeatableNode) {
+        this.repeatableNode = repeatableNode;
+    }
+
+    @Override
+    public Node copy() {
+        OptimizedOSRLoopNode copy = (OptimizedOSRLoopNode) super.copy();
+        copy.compiledTarget = null;
+        copy.interpreterLoopCount = 0;
+        return copy;
+    }
+
+    @Override
+    public RepeatingNode getRepeatingNode() {
+        return repeatableNode;
+    }
+
+    @Override
+    public void executeLoop(VirtualFrame frame) {
+        if (CompilerDirectives.inInterpreter()) {
+            boolean done = false;
+            while (!done) {
+                if (compiledTarget == null) {
+                    done = profilingLoop(frame);
+                } else {
+                    done = compilingLoop(frame);
+                }
+            }
+        } else {
+            while (repeatableNode.executeRepeating(frame)) {
+                if (CompilerDirectives.inInterpreter()) {
+                    // compiled method got invalidated. We might need OSR again.
+                    executeLoop(frame);
+                    return;
+                }
+            }
+        }
+    }
+
+    private boolean profilingLoop(VirtualFrame frame) {
+        int overflowLoopCount = Integer.MAX_VALUE - OSR_THRESHOLD + interpreterLoopCount;
+        try {
+            while (repeatableNode.executeRepeating(frame)) {
+                try {
+                    overflowLoopCount = Math.incrementExact(overflowLoopCount);
+                } catch (ArithmeticException e) {
+                    compileLoop(frame);
+                    return false;
+                }
+            }
+        } finally {
+            reportLoopCount(overflowLoopCount - Integer.MAX_VALUE + OSR_THRESHOLD - interpreterLoopCount);
+        }
+        return true;
+    }
+
+    private boolean compilingLoop(VirtualFrame frame) {
+        int iterations = 0;
+        try {
+            do {
+                OptimizedCallTarget target = compiledTarget;
+                if (target == null) {
+                    return false;
+                } else if (target.isValid()) {
+                    Object result = target.callDirect(new Object[]{frame});
+                    if (result == Boolean.TRUE) {
+                        // loop is done. No further repetitions necessary.
+                        return true;
+                    } else {
+                        invalidate(this, "OSR compilation got invalidated");
+                        return false;
+                    }
+                } else if (!target.isCompiling()) {
+                    invalidate(this, "OSR compilation failed or cancelled");
+                    return false;
+                }
+                iterations++;
+            } while (repeatableNode.executeRepeating(frame));
+        } finally {
+            reportLoopCount(iterations);
+        }
+        return true;
+    }
+
+    private void compileLoop(VirtualFrame frame) {
+        atomic(new Runnable() {
+            public void run() {
+                /*
+                 * Compilations need to run atomically as they may be scheduled by multiple threads
+                 * at the same time. This strategy lets the first thread win. Later threads will not
+                 * issue compiles.
+                 */
+                if (compiledTarget == null) {
+                    compiledTarget = compileImpl(frame);
+                    if (compiledTarget == null) {
+                        interpreterLoopCount = 0;
+                    }
+                }
+            }
+        });
+    }
+
+    private OptimizedCallTarget compileImpl(VirtualFrame frame) {
+        Node parent = getParent();
+        OptimizedCallTarget target = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(new OSRRootNode(this));
+        // to avoid a deopt on first call we provide some profiling information
+        target.profileReturnType(Boolean.TRUE);
+        target.profileReturnType(Boolean.FALSE);
+        target.profileArguments(new Object[]{frame});
+        // let the old parent re-adopt the children
+        parent.adoptChildren();
+        target.compile();
+        return target;
+    }
+
+    private void reportLoopCount(int reportIterations) {
+        if (reportIterations != 0) {
+            interpreterLoopCount += reportIterations;
+            getRootNode().reportLoopCount(reportIterations);
+        }
+    }
+
+    public void nodeReplaced(Node oldNode, Node newNode, CharSequence reason) {
+        invalidate(newNode, reason);
+    }
+
+    private void invalidate(Object source, CharSequence reason) {
+        OptimizedCallTarget target = this.compiledTarget;
+        if (target != null) {
+            target.invalidate(source, reason);
+            compiledTarget = null;
+            interpreterLoopCount = 0;
+        }
+    }
+
+    public static LoopNode create(RepeatingNode repeat) {
+        if (TruffleCompilerOptions.TruffleOSR.getValue()) {
+            return new OptimizedOSRLoopNode(repeat);
+        } else {
+            return new OptimizedLoopNode(repeat);
+        }
+    }
+
+    private static class OSRRootNode extends RootNode {
+
+        @Child private OptimizedOSRLoopNode loopNode;
+
+        public OSRRootNode(OptimizedOSRLoopNode loop) {
+            super(loop.getSourceSection(), loop.getRootNode().getFrameDescriptor());
+            this.loopNode = loop;
+        }
+
+        @Override
+        public Object execute(VirtualFrame frame) {
+            VirtualFrame parentFrame = (VirtualFrame) frame.getArguments()[0];
+            while (loopNode.getRepeatingNode().executeRepeating(parentFrame)) {
+                if (CompilerDirectives.inInterpreter()) {
+                    return Boolean.FALSE;
+                }
+            }
+            return Boolean.TRUE;
+        }
+
+        @Override
+        public boolean isCloningAllowed() {
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return loopNode.getRepeatingNode().toString() + "<OSR>";
+        }
+
+    }
+
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Tue Mar 31 19:15:45 2015 -0700
@@ -22,41 +22,28 @@
  */
 package com.oracle.graal.truffle;
 
-import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.MethodHandleAccessProvider.IntrinsicMethod;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.debug.internal.*;
-import com.oracle.graal.graph.Graph.Mark;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.java.*;
-import com.oracle.graal.loop.*;
-import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-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.common.inlining.*;
-import com.oracle.graal.phases.common.inlining.info.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.truffle.debug.*;
@@ -77,20 +64,17 @@
 
     private final Providers providers;
     private final CanonicalizerPhase canonicalizer;
-    private Set<JavaConstant> constantReceivers;
-    private final TruffleCache truffleCache;
     private final SnippetReflectionProvider snippetReflection;
     private final ResolvedJavaMethod callDirectMethod;
     private final ResolvedJavaMethod callInlinedMethod;
     private final ResolvedJavaMethod callSiteProxyMethod;
-    protected final ResolvedJavaMethod callRootMethod;
+    private final ResolvedJavaMethod callRootMethod;
     private final GraphBuilderConfiguration configForRoot;
 
-    public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) {
+    public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, SnippetReflectionProvider snippetReflection) {
         this.providers = providers;
         this.canonicalizer = new CanonicalizerPhase();
         this.snippetReflection = snippetReflection;
-        this.truffleCache = truffleCache;
         this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod());
         this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod());
         this.callSiteProxyMethod = providers.getMetaAccess().lookupJavaMethod(GraalFrameInstance.CallNodeFrame.METHOD);
@@ -104,10 +88,6 @@
     }
 
     public StructuredGraph createGraph(final OptimizedCallTarget callTarget, AllowAssumptions allowAssumptions) {
-        if (TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) {
-            constantReceivers = new HashSet<>();
-        }
-
         try (Scope c = Debug.scope("TruffleTree")) {
             Debug.dump(callTarget, "truffle tree");
         } catch (Throwable e) {
@@ -119,28 +99,16 @@
 
         try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph)) {
 
-            Map<ResolvedJavaMethod, StructuredGraph> graphCache = null;
-            if (CacheGraphs.getValue()) {
-                graphCache = new HashMap<>();
-            }
             PhaseContext baseContext = new PhaseContext(providers);
-            HighTierContext tierContext = new HighTierContext(providers, graphCache, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE);
+            HighTierContext tierContext = new HighTierContext(providers, new PhaseSuite<HighTierContext>(), OptimisticOptimizations.NONE);
 
-            if (TruffleCompilerOptions.FastPE.getValue()) {
-                fastPartialEvaluation(callTarget, graph, baseContext, tierContext);
-            } else {
-                createRootGraph(graph);
-                partialEvaluation(callTarget, graph, baseContext, tierContext);
-            }
+            fastPartialEvaluation(callTarget, graph, baseContext, tierContext);
 
             if (Thread.currentThread().isInterrupted()) {
                 return null;
             }
 
             new VerifyFrameDoesNotEscapePhase().apply(graph, false);
-            if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) {
-                createHistogram();
-            }
             postPartialEvaluation(graph);
 
         } catch (Throwable e) {
@@ -202,13 +170,6 @@
             if (original.getAnnotation(TruffleBoundary.class) != null) {
                 return null;
             }
-            IntrinsicMethod intrinsicMethod = builder.getConstantReflection().getMethodHandleAccess().lookupMethodHandleIntrinsic(original);
-            if (intrinsicMethod != null) {
-                InlineInfo inlineInfo = getMethodHandleIntrinsicInlineInfo(builder, arguments, intrinsicMethod);
-                if (inlineInfo != null) {
-                    return inlineInfo;
-                }
-            }
             if (replacements != null && replacements.getMethodSubstitutionMethod(original) != null) {
                 return null;
             }
@@ -243,59 +204,6 @@
                 inlining.pop();
             }
         }
-
-        private InlineInfo getMethodHandleIntrinsicInlineInfo(GraphBuilderContext builder, ValueNode[] arguments, IntrinsicMethod intrinsicMethod) {
-            ResolvedJavaMethod targetMethod = null;
-            switch (intrinsicMethod) {
-                case INVOKE_BASIC:
-                    ValueNode methodHandleNode = arguments[0];
-                    if (methodHandleNode.isConstant()) {
-                        targetMethod = builder.getConstantReflection().getMethodHandleAccess().resolveInvokeBasicTarget(methodHandleNode.asJavaConstant(), true);
-                    }
-                    break;
-                case LINK_TO_STATIC:
-                case LINK_TO_SPECIAL:
-                case LINK_TO_VIRTUAL:
-                case LINK_TO_INTERFACE:
-                    ValueNode memberNameNode = arguments[arguments.length - 1];
-                    if (memberNameNode.isConstant()) {
-                        targetMethod = builder.getConstantReflection().getMethodHandleAccess().resolveLinkToTarget(memberNameNode.asJavaConstant());
-                    }
-                    break;
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
-            if (targetMethod != null) {
-                // TODO maybe cast arguments
-
-                if (!targetMethod.canBeInlined()) {
-                    return null;
-                }
-                if (targetMethod.canBeStaticallyBound()) {
-                    return new InlineInfo(targetMethod, false, false);
-                }
-
-                // Try to get the most accurate receiver type
-                if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
-                    ResolvedJavaType receiverType = StampTool.typeOrNull(arguments[0].stamp());
-                    if (receiverType != null) {
-                        AssumptionResult<ResolvedJavaMethod> concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod);
-                        if (concreteMethod != null) {
-                            builder.getAssumptions().record(concreteMethod);
-                            return new InlineInfo(concreteMethod.getResult(), false, false);
-                        }
-                    }
-                } else {
-                    AssumptionResult<ResolvedJavaMethod> concreteMethod = targetMethod.getDeclaringClass().findUniqueConcreteMethod(targetMethod);
-                    if (concreteMethod != null) {
-                        builder.getAssumptions().record(concreteMethod);
-                        return new InlineInfo(concreteMethod.getResult(), false, false);
-                    }
-                }
-            }
-
-            return null;
-        }
     }
 
     private class PELoopExplosionPlugin implements LoopExplosionPlugin {
@@ -362,48 +270,6 @@
         ComputeLoopFrequenciesClosure.compute(graph);
     }
 
-    private void partialEvaluation(final OptimizedCallTarget callTarget, final StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) {
-        injectConstantCallTarget(graph, callTarget, baseContext);
-
-        Debug.dump(graph, "Before expansion");
-
-        TruffleExpansionLogger expansionLogger = null;
-        if (TraceTruffleExpansion.getValue()) {
-            expansionLogger = new TruffleExpansionLogger(providers, graph);
-        }
-
-        expandTree(graph, expansionLogger);
-
-        TruffleInliningCache inliningCache = null;
-        if (TruffleFunctionInlining.getValue()) {
-            callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy()));
-            if (TruffleFunctionInliningCache.getValue()) {
-                inliningCache = new TruffleInliningCache();
-            }
-        }
-
-        expandDirectCalls(graph, expansionLogger, callTarget.getInlining(), inliningCache);
-
-        if (Thread.currentThread().isInterrupted()) {
-            return;
-        }
-
-        canonicalizer.apply(graph, baseContext);
-        // EA frame and clean up.
-        do {
-            try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) {
-                new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext);
-                new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext);
-            } catch (Throwable t) {
-                Debug.handle(t);
-            }
-        } while (expandTree(graph, expansionLogger));
-
-        if (expansionLogger != null) {
-            expansionLogger.print(callTarget);
-        }
-    }
-
     public StructuredGraph createRootGraph(StructuredGraph graph) {
         new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations, null).apply(graph);
         return graph;
@@ -442,223 +308,6 @@
         }
     }
 
-    private void injectConstantCallTarget(final StructuredGraph graph, final OptimizedCallTarget constantCallTarget, PhaseContext baseContext) {
-        ParameterNode thisNode = graph.getParameter(0);
-
-        /*
-         * Converting the call target to a Constant using the SnippetReflectionProvider is a
-         * workaround, we should think about a better solution. Since object constants are
-         * VM-specific, only the hosting VM knows how to do the conversion.
-         */
-        thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(constantCallTarget), providers.getMetaAccess(), graph));
-
-        canonicalizer.apply(graph, baseContext);
-
-        new IncrementalCanonicalizerPhase<>(canonicalizer, new ReplaceIntrinsicsPhase(providers.getReplacements())).apply(graph, baseContext);
-    }
-
-    private void createHistogram() {
-        DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes");
-        for (JavaConstant c : constantReceivers) {
-            String javaName = providers.getMetaAccess().lookupJavaType(c).toJavaName(false);
-
-            // The DSL uses nested classes with redundant names - only show the inner class
-            int index = javaName.indexOf('$');
-            if (index != -1) {
-                javaName = javaName.substring(index + 1);
-            }
-
-            histogram.add(javaName);
-
-        }
-        new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram);
-    }
-
-    private boolean expandTree(StructuredGraph graph, TruffleExpansionLogger expansionLogger) {
-        PhaseContext phaseContext = new PhaseContext(providers);
-        boolean changed = false;
-        boolean changedInIteration;
-        ArrayDeque<MethodCallTargetNode> queue = new ArrayDeque<>();
-        MetaAccessProvider metaAccess = providers.getMetaAccess();
-        ResolvedJavaType profileClass = metaAccess.lookupJavaType(NodeCloneable.class);
-        do {
-            changedInIteration = false;
-
-            Mark mark = null;
-            while (true) {
-
-                for (MethodCallTargetNode methodCallTargetNode : graph.getNewNodes(mark).filter(MethodCallTargetNode.class)) {
-                    if (methodCallTargetNode.invokeKind().isDirect()) {
-                        ValueNode receiver = methodCallTargetNode.receiver();
-                        if (receiver != null && receiver.isConstant() && profileClass.isAssignableFrom(receiver.stamp().javaType(metaAccess))) {
-                            queue.addFirst(methodCallTargetNode);
-                        } else {
-                            queue.addLast(methodCallTargetNode);
-                        }
-                    }
-                }
-                mark = graph.getMark();
-
-                if (queue.isEmpty()) {
-                    break;
-                }
-                MethodCallTargetNode methodCallTargetNode = queue.removeFirst();
-                if (!methodCallTargetNode.isAlive()) {
-                    continue;
-                }
-                InvokeKind kind = methodCallTargetNode.invokeKind();
-                try (Indent id1 = Debug.logAndIndent("try inlining %s, kind = %s", methodCallTargetNode.targetMethod(), kind)) {
-                    if (kind.isDirect()) {
-                        if ((TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) && kind == InvokeKind.Special && methodCallTargetNode.receiver().isConstant()) {
-                            constantReceivers.add(methodCallTargetNode.receiver().asJavaConstant());
-                        }
-
-                        Replacements replacements = providers.getReplacements();
-                        StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
-
-                        ResolvedJavaMethod targetMethod = methodCallTargetNode.targetMethod();
-                        if (inlineGraph == null && targetMethod.hasBytecodes() && targetMethod.canBeInlined()) {
-                            inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), phaseContext);
-                        }
-
-                        if (inlineGraph != null) {
-                            expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph);
-                            changed = changedInIteration = true;
-                        }
-                    }
-                }
-
-                if (graph.getNodeCount() > TruffleCompilerOptions.TruffleGraphMaxNodes.getValue()) {
-                    throw new BailoutException("Truffle compilation is exceeding maximum node count: %d", graph.getNodeCount());
-                }
-            }
-
-        } while (changedInIteration);
-
-        return changed;
-    }
-
-    private void expandTreeInline(StructuredGraph graph, PhaseContext phaseContext, TruffleExpansionLogger expansionLogger, MethodCallTargetNode methodCallTargetNode, StructuredGraph inlineGraph) {
-        try (Indent indent = Debug.logAndIndent("expand graph %s", methodCallTargetNode.targetMethod())) {
-            int nodeCountBefore = graph.getNodeCount();
-            if (expansionLogger != null) {
-                expansionLogger.preExpand(methodCallTargetNode, inlineGraph);
-            }
-            List<Node> canonicalizedNodes = methodCallTargetNode.invoke().asNode().usages().snapshot();
-
-            Map<Node, Node> inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false, canonicalizedNodes);
-            if (expansionLogger != null) {
-                expansionLogger.postExpand(inlined);
-            }
-            if (Debug.isDumpEnabled()) {
-                int nodeCountAfter = graph.getNodeCount();
-                Debug.dump(graph, "After expand %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter);
-            }
-            AbstractInlineInfo.getInlinedParameterUsages(canonicalizedNodes, inlineGraph, inlined);
-            canonicalizer.applyIncremental(graph, phaseContext, canonicalizedNodes);
-        }
-    }
-
-    private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final PhaseContext phaseContext) {
-        StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, canonicalizer);
-
-        if (graph != null && targetMethod.getAnnotation(ExplodeLoop.class) != null) {
-            assert graph.hasLoops() : graph + " does not contain a loop";
-            final StructuredGraph graphCopy = graph.copy();
-            final List<Node> modifiedNodes = new ArrayList<>();
-            for (ParameterNode param : graphCopy.getNodes(ParameterNode.TYPE).snapshot()) {
-                ValueNode arg = arguments.get(param.index());
-                if (arg.isConstant()) {
-                    Constant constant = arg.asConstant();
-                    param.usages().snapshotTo(modifiedNodes);
-                    param.replaceAndDelete(ConstantNode.forConstant(arg.stamp(), constant, phaseContext.getMetaAccess(), graphCopy));
-                } else {
-                    ValueNode length = GraphUtil.arrayLength(arg);
-                    if (length != null && length.isConstant()) {
-                        param.usages().snapshotTo(modifiedNodes);
-                        ParameterNode newParam = graphCopy.addWithoutUnique(new ParameterNode(param.index(), param.stamp()));
-                        param.replaceAndDelete(graphCopy.addWithoutUnique(new PiArrayNode(newParam, ConstantNode.forInt(length.asJavaConstant().asInt(), graphCopy), param.stamp())));
-                    }
-                }
-            }
-            try (Scope s = Debug.scope("TruffleUnrollLoop", targetMethod)) {
-
-                canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes);
-                boolean unrolled;
-                do {
-                    unrolled = false;
-                    LoopsData loopsData = new LoopsData(graphCopy);
-                    loopsData.detectedCountedLoops();
-                    for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) {
-                        if (ex.counted().isConstantMaxTripCount()) {
-                            long constant = ex.counted().constantMaxTripCount();
-                            LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer);
-                            Debug.dump(graphCopy, "After loop unrolling %d times", constant);
-                            unrolled = true;
-                            break;
-                        }
-                    }
-                    loopsData.deleteUnusedNodes();
-                } while (unrolled);
-            } catch (Throwable e) {
-                throw Debug.handle(e);
-            }
-
-            return graphCopy;
-        } else {
-            return graph;
-        }
-    }
-
-    private void expandDirectCalls(StructuredGraph graph, TruffleExpansionLogger expansionLogger, TruffleInlining inlining, TruffleInliningCache inliningCache) {
-        PhaseContext phaseContext = new PhaseContext(providers);
-
-        for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE).snapshot()) {
-            StructuredGraph inlineGraph = parseDirectCallGraph(phaseContext, graph, inlining, inliningCache, methodCallTargetNode);
-
-            if (inlineGraph != null) {
-                expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph);
-            }
-        }
-        // non inlined direct calls need to be expanded until TruffleCallBoundary.
-        expandTree(graph, expansionLogger);
-        assert noDirectCallsLeft(graph);
-    }
-
-    private boolean noDirectCallsLeft(StructuredGraph graph) {
-        for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE).snapshot()) {
-            if (methodCallTargetNode.targetMethod().equals(callDirectMethod)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private StructuredGraph parseDirectCallGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInlining inlining, TruffleInliningCache inliningCache,
-                    MethodCallTargetNode methodCallTargetNode) {
-        OptimizedDirectCallNode callNode = resolveConstantCallNode(methodCallTargetNode);
-        if (callNode == null) {
-            return null;
-        }
-
-        TruffleInliningDecision decision = getDecision(inlining, callNode);
-
-        StructuredGraph graph;
-        if (decision != null && decision.isInline()) {
-            if (inliningCache == null) {
-                graph = createInlineGraph(phaseContext, caller, null, decision);
-            } else {
-                graph = inliningCache.getCachedGraph(phaseContext, caller, decision);
-            }
-            caller.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption()));
-        } else {
-            // we continue expansion of callDirect until we reach the callBoundary.
-            graph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), phaseContext);
-        }
-
-        return graph;
-    }
-
     private static TruffleInliningDecision getDecision(TruffleInlining inlining, OptimizedDirectCallNode callNode) {
         TruffleInliningDecision decision = inlining.findByCall(callNode);
         if (decision == null) {
@@ -680,125 +329,4 @@
         }
         return decision;
     }
-
-    private OptimizedDirectCallNode resolveConstantCallNode(MethodCallTargetNode methodCallTargetNode) {
-        if (!methodCallTargetNode.targetMethod().equals(callDirectMethod)) {
-            return null;
-        }
-
-        Invoke invoke = methodCallTargetNode.invoke();
-        if (invoke == null) {
-            return null;
-        }
-
-        FrameState directCallState = invoke.stateAfter();
-        while (directCallState != null && !directCallState.method().equals(callSiteProxyMethod)) {
-            directCallState = directCallState.outerFrameState();
-        }
-
-        if (directCallState == null) {
-            // not a direct call. May be indirect call.
-            return null;
-        }
-
-        if (directCallState.values().isEmpty()) {
-            throw new AssertionError(String.format("Frame state of method '%s' is invalid.", callDirectMethod.toString()));
-        }
-
-        ValueNode node = directCallState.values().get(0);
-        if (!node.isConstant()) {
-            throw new AssertionError(String.format("Method argument for method '%s' is not constant.", callDirectMethod.toString()));
-        }
-
-        JavaConstant constantCallNode = node.asJavaConstant();
-        Object value = snippetReflection.asObject(Object.class, constantCallNode);
-
-        if (!(value instanceof OptimizedDirectCallNode)) {
-            // might be an indirect call.
-            return null;
-        }
-
-        return (OptimizedDirectCallNode) value;
-    }
-
-    private StructuredGraph createInlineGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningCache cache, TruffleInliningDecision decision) {
-        try (Scope s = Debug.scope("GuestLanguageInlinedGraph", new DebugDumpScope(decision.getTarget().toString()))) {
-            OptimizedCallTarget target = decision.getTarget();
-            StructuredGraph inlineGraph = createInlineGraph(target.toString(), caller);
-            injectConstantCallTarget(inlineGraph, decision.getTarget(), phaseContext);
-            TruffleExpansionLogger expansionLogger = null;
-            if (TraceTruffleExpansion.getValue()) {
-                expansionLogger = new TruffleExpansionLogger(providers, inlineGraph);
-            }
-            expandTree(inlineGraph, expansionLogger);
-            expandDirectCalls(inlineGraph, expansionLogger, decision, cache);
-
-            if (expansionLogger != null) {
-                expansionLogger.print(target);
-            }
-            return inlineGraph;
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
-    }
-
-    private static List<LoopEx> innerLoopsFirst(Collection<LoopEx> loops) {
-        ArrayList<LoopEx> sortedLoops = new ArrayList<>(loops);
-        Collections.sort(sortedLoops, new Comparator<LoopEx>() {
-
-            @Override
-            public int compare(LoopEx o1, LoopEx o2) {
-                return o2.loop().getDepth() - o1.loop().getDepth();
-            }
-        });
-        return sortedLoops;
-    }
-
-    private final class TruffleInliningCache {
-
-        private final Map<CacheKey, StructuredGraph> cache;
-
-        public TruffleInliningCache() {
-            this.cache = new HashMap<>();
-        }
-
-        public StructuredGraph getCachedGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningDecision decision) {
-            CacheKey cacheKey = new CacheKey(decision);
-            StructuredGraph inlineGraph = cache.get(cacheKey);
-            if (inlineGraph == null) {
-                inlineGraph = createInlineGraph(phaseContext, caller, this, decision);
-                cache.put(cacheKey, inlineGraph);
-            }
-            return inlineGraph;
-        }
-
-        private final class CacheKey {
-
-            public final TruffleInliningDecision decision;
-
-            public CacheKey(TruffleInliningDecision decision) {
-                this.decision = decision;
-                /*
-                 * If decision.isInline() is not true CacheKey#hashCode does not match
-                 * CacheKey#equals
-                 */
-                assert decision.isInline();
-            }
-
-            @Override
-            public int hashCode() {
-                return decision.getTarget().hashCode();
-            }
-
-            @Override
-            public boolean equals(Object obj) {
-                if (!(obj instanceof CacheKey)) {
-                    return false;
-                }
-                CacheKey other = (CacheKey) obj;
-                return decision.isSameAs(other.decision);
-            }
-        }
-    }
-
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +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.truffle;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.common.*;
-
-public interface TruffleCache {
-
-    /**
-     * Returns a cached graph for a method with given arguments.
-     */
-    StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList<ValueNode> arguments, final CanonicalizerPhase finalCanonicalizer);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.truffle;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.graph.Graph.Mark;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Node;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.graphbuilderconf.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.common.inlining.*;
-import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.truffle.debug.*;
-import com.oracle.graal.truffle.phases.*;
-import com.oracle.graal.virtual.phases.ea.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.*;
-
-/**
- * Implementation of a cache for Truffle graphs for improving partial evaluation time.
- */
-public class TruffleCacheImpl implements TruffleCache {
-
-    private final Providers providers;
-    private final GraphBuilderConfiguration config;
-    private final OptimisticOptimizations optimisticOptimizations;
-
-    private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>();
-    private final HashMap<List<Object>, Long> lastUsed = new HashMap<>();
-    private final StructuredGraph markerGraph = new StructuredGraph(AllowAssumptions.NO);
-
-    private final ResolvedJavaType stringBuilderClass;
-    private final ResolvedJavaType runtimeExceptionClass;
-    private final ResolvedJavaType errorClass;
-    private final ResolvedJavaType controlFlowExceptionClass;
-
-    private long counter;
-
-    public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) {
-        this.providers = providers;
-        this.config = config;
-        this.optimisticOptimizations = optimisticOptimizations;
-
-        this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class);
-        this.runtimeExceptionClass = providers.getMetaAccess().lookupJavaType(RuntimeException.class);
-        this.errorClass = providers.getMetaAccess().lookupJavaType(Error.class);
-        this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class);
-    }
-
-    private static List<Object> computeCacheKey(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments) {
-        List<Object> key = new ArrayList<>(arguments.size() + 1);
-        key.add(method);
-        for (ValueNode v : arguments) {
-            if (v.getKind() == Kind.Object) {
-                key.add(v.stamp());
-            }
-        }
-        return key;
-    }
-
-    public StructuredGraph lookup(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments, CanonicalizerPhase canonicalizer) {
-        List<Object> key = computeCacheKey(method, arguments);
-        StructuredGraph resultGraph = cache.get(key);
-        if (resultGraph == markerGraph) {
-            // compilation failed previously, don't try again
-            return null;
-        }
-        StructuredGraph graph = cacheLookup(method, arguments, canonicalizer);
-        assert graph != markerGraph : "markerGraph should not leak out";
-        return graph;
-    }
-
-    private StructuredGraph cacheLookup(ResolvedJavaMethod method, NodeInputList<ValueNode> arguments, CanonicalizerPhase canonicalizer) {
-        if (method.getAnnotation(CompilerDirectives.TruffleBoundary.class) != null) {
-            return null;
-        }
-
-        List<Object> key = computeCacheKey(method, arguments);
-        StructuredGraph resultGraph = cache.get(key);
-        if (resultGraph != null) {
-            lastUsed.put(key, counter++);
-            return resultGraph;
-        }
-
-        if (lastUsed.values().size() >= TruffleCompilerOptions.TruffleMaxCompilationCacheSize.getValue()) {
-            lookupExceedsMaxSize();
-        }
-
-        StructuredGraph graph = new StructuredGraph(method, AllowAssumptions.NO);
-        PhaseContext phaseContext = new PhaseContext(providers);
-        try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method)) {
-
-            graph = parseGraph(graph, phaseContext);
-            if (graph == null) {
-                return null;
-            }
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
-
-        try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method, graph)) {
-
-            lastUsed.put(key, counter++);
-            cache.put(key, markerGraph);
-
-            for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
-                if (param.getKind() == Kind.Object) {
-                    ValueNode actualArgument = arguments.get(param.index());
-                    param.setStamp(param.stamp().join(actualArgument.stamp()));
-                }
-            }
-
-            // Intrinsify methods.
-            new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
-
-            // Convert deopt to guards.
-            new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext);
-
-            PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizer);
-
-            Mark mark = null;
-            while (true) {
-
-                partialEscapePhase.apply(graph, phaseContext);
-
-                // Conditional elimination.
-                ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase();
-                conditionalEliminationPhase.apply(graph);
-
-                // Canonicalize / constant propagate.
-                canonicalizer.apply(graph, phaseContext);
-
-                boolean inliningProgress = false;
-                for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.TYPE)) {
-                    if (!graph.getMark().equals(mark)) {
-                        mark = lookupProcessMacroSubstitutions(graph, mark);
-                    }
-                    if (methodCallTarget.isAlive() && methodCallTarget.invoke() != null && shouldInline(methodCallTarget)) {
-                        inliningProgress = true;
-                        lookupDoInline(graph, phaseContext, canonicalizer, methodCallTarget);
-                    }
-                }
-
-                // Convert deopt to guards.
-                new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext);
-
-                new EarlyReadEliminationPhase(canonicalizer).apply(graph, phaseContext);
-
-                if (!inliningProgress) {
-                    break;
-                }
-            }
-
-            if (TruffleCompilerOptions.TraceTrufflePerformanceWarnings.getValue()) {
-                int warnNodeCount = TruffleCompilerOptions.TrufflePerformanceWarningGraalNodeCount.getValue();
-                if (graph.getNodeCount() > warnNodeCount) {
-                    Map<String, Object> map = new LinkedHashMap<>();
-                    map.put("nodeCount", graph.getNodeCount());
-                    map.put("method", method.toString());
-                    TracePerformanceWarningsListener.logPerformanceWarning(String.format("Method on fast path contains more than %d graal nodes.", warnNodeCount), map);
-
-                    try (Scope s2 = Debug.scope("TrufflePerformanceWarnings")) {
-                        Debug.dump(graph, "performance warning");
-                    }
-                }
-            }
-
-            cache.put(key, graph);
-            if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) {
-                TTY.println(String.format("[truffle] added to graph cache method %s with %d nodes.", method, graph.getNodeCount()));
-            }
-            return graph;
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
-    }
-
-    private void lookupExceedsMaxSize() {
-        List<Long> lastUsedList = new ArrayList<>();
-        for (long l : lastUsed.values()) {
-            lastUsedList.add(l);
-        }
-        Collections.sort(lastUsedList);
-        long mid = lastUsedList.get(lastUsedList.size() / 2);
-
-        List<List<Object>> toRemoveList = new ArrayList<>();
-        for (Entry<List<Object>, Long> entry : lastUsed.entrySet()) {
-            if (entry.getValue() < mid) {
-                toRemoveList.add(entry.getKey());
-            }
-        }
-
-        for (List<Object> entry : toRemoveList) {
-            cache.remove(entry);
-            lastUsed.remove(entry);
-        }
-    }
-
-    private Mark lookupProcessMacroSubstitutions(StructuredGraph graph, Mark mark) {
-        // Make sure macro substitutions such as
-        // CompilerDirectives.transferToInterpreter get processed first.
-        for (Node newNode : graph.getNewNodes(mark)) {
-            if (newNode instanceof MethodCallTargetNode) {
-                MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode;
-                tryCutOffRuntimeExceptionsAndErrors(methodCallTargetNode);
-            }
-        }
-        return graph.getMark();
-    }
-
-    private void lookupDoInline(StructuredGraph graph, PhaseContext phaseContext, CanonicalizerPhase canonicalizer, MethodCallTargetNode methodCallTarget) {
-        List<Node> canonicalizerUsages = new ArrayList<>();
-        for (Node n : methodCallTarget.invoke().asNode().usages()) {
-            if (n instanceof Canonicalizable) {
-                canonicalizerUsages.add(n);
-            }
-        }
-        List<ValueNode> argumentSnapshot = methodCallTarget.arguments().snapshot();
-        Mark beforeInvokeMark = graph.getMark();
-        expandInvoke(methodCallTarget, canonicalizer);
-        for (Node arg : argumentSnapshot) {
-            if (arg != null) {
-                for (Node argUsage : arg.usages()) {
-                    if (graph.isNew(beforeInvokeMark, argUsage) && argUsage instanceof Canonicalizable) {
-                        canonicalizerUsages.add(argUsage);
-                    }
-                }
-            }
-        }
-        canonicalizer.applyIncremental(graph, phaseContext, canonicalizerUsages);
-    }
-
-    protected StructuredGraph parseGraph(StructuredGraph graph, final PhaseContext phaseContext) {
-        new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), null, config, optimisticOptimizations, null).apply(graph);
-        return graph;
-    }
-
-    private void expandInvoke(MethodCallTargetNode methodCallTargetNode, CanonicalizerPhase canonicalizer) {
-        StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod());
-        if (inlineGraph == null) {
-            inlineGraph = cacheLookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), canonicalizer);
-        }
-        if (inlineGraph == null) {
-            return;
-        }
-        if (inlineGraph == this.markerGraph) {
-            // Can happen for recursive calls.
-            throw GraphUtil.approxSourceException(methodCallTargetNode, new IllegalStateException("Found illegal recursive call to " + methodCallTargetNode.targetMethod() +
-                            ", must annotate such calls with @TruffleBoundary!"));
-        }
-        Invoke invoke = methodCallTargetNode.invoke();
-        InliningUtil.inline(invoke, inlineGraph, true, null);
-    }
-
-    private boolean tryCutOffRuntimeExceptionsAndErrors(MethodCallTargetNode methodCallTargetNode) {
-        if (methodCallTargetNode.targetMethod().isConstructor()) {
-            ResolvedJavaType declaringClass = methodCallTargetNode.targetMethod().getDeclaringClass();
-            ResolvedJavaType exceptionType = Objects.requireNonNull(StampTool.typeOrNull(methodCallTargetNode.receiver().stamp()));
-
-            boolean removeAllocation = runtimeExceptionClass.isAssignableFrom(declaringClass) || errorClass.isAssignableFrom(declaringClass);
-            boolean isControlFlowException = controlFlowExceptionClass.isAssignableFrom(exceptionType);
-            if (removeAllocation && !isControlFlowException) {
-                DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode));
-                FixedNode invokeNode = methodCallTargetNode.invoke().asNode();
-                invokeNode.replaceAtPredecessor(deoptNode);
-                GraphUtil.killCFG(invokeNode);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    protected boolean shouldInline(MethodCallTargetNode methodCallTargetNode) {
-        boolean result = methodCallTargetNode.invokeKind().isDirect() && methodCallTargetNode.targetMethod().hasBytecodes() && methodCallTargetNode.targetMethod().canBeInlined() &&
-                        methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) == null &&
-                        methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.TruffleBoundary.class) == null &&
-                        !methodCallTargetNode.targetMethod().getDeclaringClass().equals(stringBuilderClass);
-        return result;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Tue Mar 31 19:15:45 2015 -0700
@@ -43,7 +43,6 @@
 import com.oracle.graal.lir.phases.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
@@ -66,7 +65,6 @@
     private final Backend backend;
     private final GraphBuilderConfiguration config;
     private final RuntimeProvider runtime;
-    private final TruffleCache truffleCache;
     private final GraalTruffleCompilationListener compilationNotify;
 
     // @formatter:off
@@ -89,34 +87,22 @@
         this.runtime = Graal.getRequiredCapability(RuntimeProvider.class);
         this.compilationNotify = graalTruffleRuntime.getCompilationNotify();
         this.backend = runtime.getHostBackend();
-        Replacements truffleReplacements = graalTruffleRuntime.getReplacements();
         Providers backendProviders = backend.getProviders();
         ConstantReflectionProvider constantReflection = new TruffleConstantReflectionProvider(backendProviders.getConstantReflection(), backendProviders.getMetaAccess());
-        if (!TruffleCompilerOptions.FastPE.getValue()) {
-            backendProviders = backendProviders.copyWith(truffleReplacements);
-        }
         this.providers = backendProviders.copyWith(constantReflection);
         this.suites = backend.getSuites().getDefaultSuites();
         this.lirSuites = backend.getSuites().getDefaultLIRSuites();
 
         ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
 
-        Plugins plugins;
-        if (TruffleCompilerOptions.FastPE.getValue()) {
-            GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous();
-            InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins());
-            plugins = new Plugins(invocationPlugins);
-            TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins);
-        } else {
-            plugins = new Plugins(new InvocationPlugins(backendProviders.getMetaAccess()));
-        }
+        GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous();
+        InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins());
+        Plugins plugins = new Plugins(invocationPlugins);
+        TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins);
 
         this.config = GraphBuilderConfiguration.getDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes);
 
-        GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes);
-        this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations);
-
-        this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class));
+        this.partialEvaluator = new PartialEvaluator(providers, config, Graal.getRequiredCapability(SnippetReflectionProvider.class));
 
         if (Debug.isEnabled()) {
             DebugEnvironment.initialize(System.out);
@@ -177,7 +163,7 @@
             CodeCacheProvider codeCache = providers.getCodeCache();
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(name);
-            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, graphBuilderSuite, Optimizations, getProfilingInfo(graph), speculationLog, suites,
+            result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), graphBuilderSuite, Optimizations, getProfilingInfo(graph), speculationLog, suites,
                             lirSuites, compilationResult, CompilationResultBuilderFactory.Default);
         } catch (Throwable e) {
             throw Debug.handle(e);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Tue Mar 31 19:15:45 2015 -0700
@@ -98,6 +98,12 @@
     @Option(help = "Experimental. New splitting only: Split everything aggressively. ", type = OptionType.Debug)
     public static final OptionValue<Boolean> TruffleSplittingAggressive = new OptionValue<>(false);
 
+    @Option(help = "Enable on stack replacement for Truffle loops.", type = OptionType.Debug)
+    public static final OptionValue<Boolean> TruffleOSR = new OptionValue<>(true);
+
+    @Option(help = "Number of loop iterations until on-stack-replacement compilation is triggered.", type = OptionType.Debug)
+    public static final OptionValue<Integer> TruffleOSRCompilationThreshold = new OptionValue<>(10000);
+
     @Option(help = "Disable call target splitting if tree size exceeds this limit", type = OptionType.Debug)
     public static final OptionValue<Integer> TruffleSplittingMaxCalleeSize = new OptionValue<>(100);
 
@@ -138,9 +144,6 @@
     @Option(help = "Print information for compilation queuing", type = OptionType.Debug)
     public static final OptionValue<Boolean> TraceTruffleCompilationDetails = new OptionValue<>(false);
 
-    @Option(help = "Print a node count histogram after each compilation", type = OptionType.Debug)
-    public static final OptionValue<Boolean> TraceTruffleCompilationHistogram = new OptionValue<>(false);
-
     @Option(help = "Print all polymorphic and generic nodes after each compilation", type = OptionType.Debug)
     public static final OptionValue<Boolean> TraceTruffleCompilationPolymorphism = new OptionValue<>(false);
 
@@ -191,8 +194,5 @@
 
     @Option(help = "Print additional more verbose Truffle compilation statistics at the end of a run.", type = OptionType.Debug)
     public static final OptionValue<Boolean> TruffleCompilationStatisticDetails = new OptionValue<>(false);
-
-    @Option(help = "Experimental new version of the partial evaluator.", type = OptionType.Debug)
-    public static final OptionValue<Boolean> FastPE = new OptionValue<>(true);
     // @formatter:on
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.truffle;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.replacements.*;
-
-/**
- * Custom {@link Replacements} for Truffle compilation.
- */
-public abstract class TruffleReplacements extends ReplacementsImpl {
-
-    private final Replacements graalReplacements;
-
-    protected TruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) {
-        super(providers, snippetReflection, providers.getCodeCache().getTarget());
-        this.graalReplacements = providers.getReplacements();
-    }
-
-    @Override
-    public StructuredGraph getSnippet(ResolvedJavaMethod method, Object[] args) {
-        return graalReplacements.getSnippet(method, null, args);
-    }
-
-    @Override
-    public StructuredGraph getMethodSubstitution(ResolvedJavaMethod method) {
-        StructuredGraph graph = graalReplacements.getMethodSubstitution(method);
-        if (graph == null) {
-            return super.getMethodSubstitution(method);
-        }
-        return graph;
-    }
-
-    @Override
-    public Collection<ResolvedJavaMethod> getAllReplacements() {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    @Override
-    public boolean isForcedSubstitution(ResolvedJavaMethod method) {
-        return graalReplacements.isForcedSubstitution(method) || super.isForcedSubstitution(method);
-    }
-
-    @Override
-    public void registerSnippetTemplateCache(SnippetTemplateCache templates) {
-        throw GraalInternalError.shouldNotReachHere();
-    }
-
-    @Override
-    public <T extends SnippetTemplateCache> T getSnippetTemplateCache(Class<T> templatesClass) {
-        return graalReplacements.getSnippetTemplateCache(templatesClass);
-    }
-}
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +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.compiler.common.GraalOptions.*;
-import static com.oracle.graal.debug.Debug.*;
-import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
-
-import java.util.*;
-
-import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.common.*;
-import com.oracle.graal.phases.common.inlining.*;
-import com.oracle.graal.phases.tiers.*;
-
-public class IterativeInliningPhase extends AbstractInliningPhase {
-
-    private final CanonicalizerPhase canonicalizer;
-
-    public IterativeInliningPhase(CanonicalizerPhase canonicalizer) {
-        this.canonicalizer = canonicalizer;
-    }
-
-    public static final void trace(String format, Object... obj) {
-        if (TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) {
-            Debug.logv(format, obj);
-        }
-    }
-
-    @Override
-    protected void run(final StructuredGraph graph, final HighTierContext context) {
-        runIterations(graph, true, context);
-        runIterations(graph, false, context);
-    }
-
-    private void runIterations(final StructuredGraph graph, final boolean simple, final HighTierContext context) {
-        for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue(); iteration++) {
-            try (Scope s = Debug.scope(isEnabled() ? "iteration " + iteration : null)) {
-                boolean progress = false;
-                PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer);
-                boolean eaResult = ea.runAnalysis(graph, context);
-                progress |= eaResult;
-
-                Map<Invoke, Double> hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null;
-
-                InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase());
-                inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE);
-                inlining.apply(graph, context);
-                progress |= inlining.getInliningCount() > 0;
-
-                new DeadCodeEliminationPhase(Optional).apply(graph);
-
-                if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
-                    canonicalizer.apply(graph, context);
-                    new IterativeConditionalEliminationPhase(canonicalizer, false).apply(graph, context);
-                }
-                if (!progress) {
-                    break;
-                }
-            } catch (Throwable e) {
-                throw Debug.handle(e);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java	Tue Mar 31 19:15:45 2015 -0700
@@ -33,20 +33,23 @@
 
     final HashMap<ReadCacheEntry, ValueNode> readCache;
 
-    static class ReadCacheEntry {
+    static final class ReadCacheEntry {
 
         public final LocationIdentity identity;
         public final ValueNode object;
+        public final int index;
 
-        public ReadCacheEntry(LocationIdentity identity, ValueNode object) {
+        public ReadCacheEntry(LocationIdentity identity, ValueNode object, int index) {
             this.identity = identity;
             this.object = object;
+            this.index = index;
         }
 
         @Override
         public int hashCode() {
             int result = 31 + ((identity == null) ? 0 : identity.hashCode());
-            return 31 * result + ((object == null) ? 0 : object.hashCode());
+            result = 31 * result + ((object == null) ? 0 : object.hashCode());
+            return result * 31 + index;
         }
 
         @Override
@@ -60,7 +63,7 @@
 
         @Override
         public String toString() {
-            return object + ":" + identity;
+            return index == -1 ? (object + ":" + identity) : (object + "[" + index + "]:" + identity);
         }
     }
 
@@ -83,7 +86,7 @@
         if (virtual instanceof VirtualInstanceNode) {
             VirtualInstanceNode instance = (VirtualInstanceNode) virtual;
             for (int i = 0; i < instance.entryCount(); i++) {
-                readCache.put(new ReadCacheEntry(instance.field(i).getLocationIdentity(), representation), values.get(i));
+                readCache.put(new ReadCacheEntry(instance.field(i).getLocationIdentity(), representation, -1), values.get(i));
             }
         }
     }
@@ -96,7 +99,7 @@
         return super.equivalentTo(other);
     }
 
-    public void addReadCache(ValueNode object, LocationIdentity identity, ValueNode value, PartialEscapeClosure<?> closure) {
+    public void addReadCache(ValueNode object, LocationIdentity identity, int index, ValueNode value, PartialEscapeClosure<?> closure) {
         ValueNode cacheObject;
         ObjectState obj = closure.getObjectState(this, object);
         if (obj != null) {
@@ -105,10 +108,10 @@
         } else {
             cacheObject = object;
         }
-        readCache.put(new ReadCacheEntry(identity, cacheObject), value);
+        readCache.put(new ReadCacheEntry(identity, cacheObject, index), value);
     }
 
-    public ValueNode getReadCache(ValueNode object, LocationIdentity identity, PartialEscapeClosure<?> closure) {
+    public ValueNode getReadCache(ValueNode object, LocationIdentity identity, int index, PartialEscapeClosure<?> closure) {
         ValueNode cacheObject;
         ObjectState obj = closure.getObjectState(this, object);
         if (obj != null) {
@@ -117,7 +120,7 @@
         } else {
             cacheObject = object;
         }
-        ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject));
+        ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject, index));
         obj = closure.getObjectState(this, cacheValue);
         if (obj != null) {
             assert !obj.isVirtual();
@@ -133,11 +136,11 @@
         readCache.clear();
     }
 
-    public void killReadCache(LocationIdentity identity) {
+    public void killReadCache(LocationIdentity identity, int index) {
         Iterator<Map.Entry<ReadCacheEntry, ValueNode>> iter = readCache.entrySet().iterator();
         while (iter.hasNext()) {
-            Map.Entry<ReadCacheEntry, ValueNode> entry = iter.next();
-            if (entry.getKey().identity.equals(identity)) {
+            ReadCacheEntry entry = iter.next().getKey();
+            if (entry.identity.equals(identity) && (index == -1 || entry.index == -1 || index == entry.index)) {
                 iter.remove();
             }
         }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Tue Mar 31 19:15:45 2015 -0700
@@ -38,6 +38,14 @@
 
 public class PEReadEliminationClosure extends PartialEscapeClosure<PEReadEliminationBlockState> {
 
+    private static final EnumMap<Kind, LocationIdentity> UNBOX_LOCATIONS;
+    static {
+        UNBOX_LOCATIONS = new EnumMap<>(Kind.class);
+        for (Kind kind : Kind.values()) {
+            UNBOX_LOCATIONS.put(kind, NamedLocationIdentity.immutable("PEA unbox " + kind.getJavaName()));
+        }
+    }
+
     public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
         super(schedule, metaAccess, constantReflection);
     }
@@ -57,8 +65,14 @@
             return processLoadField((LoadFieldNode) node, state, effects);
         } else if (node instanceof StoreFieldNode) {
             return processStoreField((StoreFieldNode) node, state, effects);
+        } else if (node instanceof LoadIndexedNode) {
+            return processLoadIndexed((LoadIndexedNode) node, state, effects);
+        } else if (node instanceof StoreIndexedNode) {
+            return processStoreIndexed((StoreIndexedNode) node, state, effects);
         } else if (node instanceof ArrayLengthNode) {
             return processArrayLength((ArrayLengthNode) node, state, effects);
+        } else if (node instanceof UnboxNode) {
+            return processUnbox((UnboxNode) node, state, effects);
         } else if (node instanceof MemoryCheckpoint.Single) {
             METRIC_MEMORYCHECKPOINT.increment();
             LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
@@ -75,13 +89,13 @@
 
     private boolean processArrayLength(ArrayLengthNode length, PEReadEliminationBlockState state, GraphEffectList effects) {
         ValueNode array = GraphUtil.unproxify(length.array());
-        ValueNode cachedValue = state.getReadCache(array, ARRAY_LENGTH_LOCATION, this);
+        ValueNode cachedValue = state.getReadCache(array, ARRAY_LENGTH_LOCATION, -1, this);
         if (cachedValue != null) {
             effects.replaceAtUsages(length, cachedValue);
             addScalarAlias(length, cachedValue);
             return true;
         } else {
-            state.addReadCache(array, ARRAY_LENGTH_LOCATION, length, this);
+            state.addReadCache(array, ARRAY_LENGTH_LOCATION, -1, length, this);
         }
         return false;
     }
@@ -89,7 +103,7 @@
     private boolean processStoreField(StoreFieldNode store, PEReadEliminationBlockState state, GraphEffectList effects) {
         if (!store.isVolatile()) {
             ValueNode object = GraphUtil.unproxify(store.object());
-            ValueNode cachedValue = state.getReadCache(object, store.field().getLocationIdentity(), this);
+            ValueNode cachedValue = state.getReadCache(object, store.field().getLocationIdentity(), -1, this);
 
             ValueNode value = getScalarAlias(store.value());
             boolean result = false;
@@ -97,8 +111,8 @@
                 effects.deleteNode(store);
                 result = true;
             }
-            state.killReadCache(store.field().getLocationIdentity());
-            state.addReadCache(object, store.field().getLocationIdentity(), value, this);
+            state.killReadCache(store.field().getLocationIdentity(), -1);
+            state.addReadCache(object, store.field().getLocationIdentity(), -1, value, this);
             return result;
         } else {
             processIdentity(state, any());
@@ -111,14 +125,67 @@
             processIdentity(state, any());
         } else {
             ValueNode object = GraphUtil.unproxify(load.object());
-            ValueNode cachedValue = state.getReadCache(object, load.field().getLocationIdentity(), this);
+            ValueNode cachedValue = state.getReadCache(object, load.field().getLocationIdentity(), -1, this);
             if (cachedValue != null) {
                 effects.replaceAtUsages(load, cachedValue);
                 addScalarAlias(load, cachedValue);
                 return true;
             } else {
-                state.addReadCache(object, load.field().getLocationIdentity(), load, this);
+                state.addReadCache(object, load.field().getLocationIdentity(), -1, load, this);
+            }
+        }
+        return false;
+    }
+
+    private boolean processStoreIndexed(StoreIndexedNode store, PEReadEliminationBlockState state, GraphEffectList effects) {
+        LocationIdentity arrayLocation = NamedLocationIdentity.getArrayLocation(store.elementKind());
+        if (store.index().isConstant()) {
+            int index = ((JavaConstant) store.index().asConstant()).asInt();
+            ValueNode object = GraphUtil.unproxify(store.array());
+            ValueNode cachedValue = state.getReadCache(object, arrayLocation, index, this);
+
+            ValueNode value = getScalarAlias(store.value());
+            boolean result = false;
+            if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
+                effects.deleteNode(store);
+                result = true;
             }
+            state.killReadCache(arrayLocation, index);
+            state.addReadCache(object, arrayLocation, index, value, this);
+            return result;
+        } else {
+            state.killReadCache(arrayLocation, -1);
+        }
+        return false;
+    }
+
+    private boolean processLoadIndexed(LoadIndexedNode load, PEReadEliminationBlockState state, GraphEffectList effects) {
+        if (load.index().isConstant()) {
+            int index = ((JavaConstant) load.index().asConstant()).asInt();
+            LocationIdentity arrayLocation = NamedLocationIdentity.getArrayLocation(load.elementKind());
+            ValueNode object = GraphUtil.unproxify(load.array());
+            ValueNode cachedValue = state.getReadCache(object, arrayLocation, index, this);
+            if (cachedValue != null) {
+                effects.replaceAtUsages(load, cachedValue);
+                addScalarAlias(load, cachedValue);
+                return true;
+            } else {
+                state.addReadCache(object, arrayLocation, index, load, this);
+            }
+        }
+        return false;
+    }
+
+    private boolean processUnbox(UnboxNode unbox, PEReadEliminationBlockState state, GraphEffectList effects) {
+        ValueNode object = GraphUtil.unproxify(unbox.getValue());
+        LocationIdentity identity = UNBOX_LOCATIONS.get(unbox.getBoxingKind());
+        ValueNode cachedValue = state.getReadCache(object, identity, -1, this);
+        if (cachedValue != null) {
+            effects.replaceAtUsages(unbox, cachedValue);
+            addScalarAlias(unbox, cachedValue);
+            return true;
+        } else {
+            state.addReadCache(object, identity, -1, unbox, this);
         }
         return false;
     }
@@ -127,7 +194,7 @@
         if (identity.isAny()) {
             state.killReadCache();
         } else {
-            state.killReadCache(identity);
+            state.killReadCache(identity, -1);
         }
     }
 
@@ -138,7 +205,7 @@
         if (exitNode.graph().hasValueProxies()) {
             for (Map.Entry<ReadCacheEntry, ValueNode> entry : exitState.getReadCache().entrySet()) {
                 if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) {
-                    ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this);
+                    ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, entry.getKey().index, this);
                     if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) {
                         ProxyNode proxy = new ValueProxyNode(value, exitNode);
                         effects.addFloatingNode(proxy, "readCacheProxy");
@@ -192,7 +259,7 @@
                     PhiNode phiNode = getPhi(entry, value.stamp().unrestricted());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
-                        afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this));
+                        afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, key.index, PEReadEliminationClosure.this));
                     }
                     newState.readCache.put(key, phiNode);
                 } else if (value != null) {
@@ -203,7 +270,7 @@
                 if (phi.getKind() == 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);
+                            mergeReadCachePhi(phi, entry.getKey().identity, entry.getKey().index, states);
                         }
                     }
 
@@ -211,22 +278,22 @@
             }
         }
 
-        private void mergeReadCachePhi(PhiNode phi, LocationIdentity identity, List<PEReadEliminationBlockState> states) {
+        private void mergeReadCachePhi(PhiNode phi, LocationIdentity identity, int index, List<PEReadEliminationBlockState> 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, PEReadEliminationClosure.this);
+                ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity, index, PEReadEliminationClosure.this);
                 if (value == null) {
                     return;
                 }
                 values[i] = value;
             }
 
-            PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi), values[0].stamp().unrestricted());
+            PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index), values[0].stamp().unrestricted());
             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);
+            newState.readCache.put(new ReadCacheEntry(identity, phi, index), phiNode);
         }
     }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Tue Mar 31 19:15:45 2015 -0700
@@ -26,19 +26,14 @@
 import static com.oracle.graal.virtual.phases.ea.PartialEscapePhase.Options.*;
 
 import java.util.*;
-import java.util.function.*;
 
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
-import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.options.*;
 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.*;
 
@@ -94,44 +89,4 @@
             return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getConstantReflection());
         }
     }
-
-    public static Map<Invoke, Double> getHints(StructuredGraph graph) {
-        ToDoubleFunction<FixedNode> probabilities = new FixedNodeProbabilityCache();
-        Map<Invoke, Double> hints = null;
-        for (CommitAllocationNode commit : graph.getNodes().filter(CommitAllocationNode.class)) {
-            double sum = 0;
-            double invokeSum = 0;
-            for (Node commitUsage : commit.usages()) {
-                for (Node usage : commitUsage.usages()) {
-                    if (usage instanceof FixedNode) {
-                        sum += probabilities.applyAsDouble((FixedNode) usage);
-                    } else {
-                        if (usage instanceof MethodCallTargetNode) {
-                            invokeSum += probabilities.applyAsDouble(((MethodCallTargetNode) usage).invoke().asNode());
-                        }
-                        for (Node secondLevelUage : usage.usages()) {
-                            if (secondLevelUage instanceof FixedNode) {
-                                sum += probabilities.applyAsDouble(((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 = CollectionsFactory.newMap();
-                            }
-                            Invoke invoke = ((MethodCallTargetNode) usage).invoke();
-                            hints.put(invoke, sum / invokeSum);
-                        }
-                    }
-                }
-            }
-        }
-        return hints;
-    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java	Tue Mar 31 19:15:45 2015 -0700
@@ -40,14 +40,16 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T profile(T value) {
-        if (cachedClass != null && cachedClass.isInstance(value)) {
-            return (T) cachedClass.cast(value);
-        } else {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            if (cachedClass == null && value != null) {
-                cachedClass = value.getClass();
+        if (cachedClass != Object.class) {
+            if (cachedClass != null && cachedClass.isInstance(value)) {
+                return (T) cachedClass.cast(value);
             } else {
-                cachedClass = Object.class;
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                if (cachedClass == null && value != null) {
+                    cachedClass = value.getClass();
+                } else {
+                    cachedClass = Object.class;
+                }
             }
         }
         return value;
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java	Tue Mar 31 19:15:45 2015 -0700
@@ -53,27 +53,42 @@
     public Object profile(Object value) {
         Object snapshot = this.cachedValue;
         if (snapshot != GENERIC) {
-            if (snapshot instanceof Byte && value instanceof Byte && (byte) snapshot == (byte) value) {
-                return snapshot;
-            } else if (snapshot instanceof Short && value instanceof Short && (short) snapshot == (short) value) {
-                return snapshot;
-            } else if (snapshot instanceof Integer && value instanceof Integer && (int) snapshot == (int) value) {
-                return snapshot;
-            } else if (snapshot instanceof Long && value instanceof Long && (long) snapshot == (long) value) {
-                return snapshot;
-            } else if (snapshot instanceof Float && value instanceof Float && exactCompare((float) snapshot, (float) value)) {
-                return snapshot;
-            } else if (snapshot instanceof Double && value instanceof Double && exactCompare((double) snapshot, (double) value)) {
-                return snapshot;
-            } else if (snapshot instanceof Boolean && value instanceof Boolean && (boolean) snapshot == (boolean) value) {
-                return snapshot;
-            } else if (snapshot instanceof Character && value instanceof Character && (char) snapshot == (char) value) {
-                return snapshot;
+            if (snapshot instanceof Byte) {
+                if (value instanceof Byte && (byte) snapshot == (byte) value) {
+                    return snapshot;
+                }
+            } else if (snapshot instanceof Short) {
+                if (value instanceof Short && (short) snapshot == (short) value) {
+                    return snapshot;
+                }
+            } else if (snapshot instanceof Integer) {
+                if (value instanceof Integer && (int) snapshot == (int) value) {
+                    return snapshot;
+                }
+            } else if (snapshot instanceof Long) {
+                if (value instanceof Long && (long) snapshot == (long) value) {
+                    return snapshot;
+                }
+            } else if (snapshot instanceof Float) {
+                if (value instanceof Float && exactCompare((float) snapshot, (float) value)) {
+                    return snapshot;
+                }
+            } else if (snapshot instanceof Double) {
+                if (value instanceof Double && exactCompare((double) snapshot, (double) value)) {
+                    return snapshot;
+                }
+            } else if (snapshot instanceof Boolean) {
+                if (value instanceof Boolean && (boolean) snapshot == (boolean) value) {
+                    return snapshot;
+                }
+            } else if (snapshot instanceof Character) {
+                if (value instanceof Character && (char) snapshot == (char) value) {
+                    return snapshot;
+                }
             } else if (snapshot == value) {
                 return snapshot;
-            } else {
-                cacheMiss(value);
             }
+            cacheMiss(value);
         }
         return value;
     }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -64,7 +64,7 @@
      * @param node the node to format.
      * @return a formatted source section string
      */
-    private static String formatSourceSection(Node node) {
+    public static String formatSourceSection(Node node) {
         if (node == null) {
             return "<unknown>";
         }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java	Tue Mar 31 19:15:45 2015 -0700
@@ -93,4 +93,9 @@
         }
     }
 
+    @Override
+    public String toString() {
+        return SLStatementNode.formatSourceSection(this);
+    }
+
 }
--- a/mx/mx_graal.py	Tue Mar 31 19:01:07 2015 -0700
+++ b/mx/mx_graal.py	Tue Mar 31 19:15:45 2015 -0700
@@ -83,6 +83,9 @@
 
 _minVersion = mx.VersionSpec('1.8')
 
+# max version (first _unsupported_ version)
+_untilVersion = mx.VersionSpec('1.8.0_40')
+
 class JDKDeployedDist:
     def __init__(self, name, isExtension):
         self.name = name
@@ -2527,7 +2530,9 @@
 def mx_post_parse_cmd_line(opts):  #
     # TODO _minVersion check could probably be part of a Suite in mx?
     if mx.java().version < _minVersion:
-        mx.abort('Requires Java version ' + str(_minVersion) + ' or greater, got version ' + str(mx.java().version))
+        mx.abort('Requires Java version ' + str(_minVersion) + ' or greater for JAVA_HOME, got version ' + str(mx.java().version))
+    if mx.java().version >= _untilVersion:
+        mx.abort('Requires Java version strictly before ' + str(_untilVersion) + ' for JAVA_HOME, got version ' + str(mx.java().version))
 
     if _vmSourcesAvailable:
         if hasattr(opts, 'vm') and opts.vm is not None:
--- a/mxtool/mx.py	Tue Mar 31 19:01:07 2015 -0700
+++ b/mxtool/mx.py	Tue Mar 31 19:15:45 2015 -0700
@@ -1660,6 +1660,8 @@
     elif get_os() == 'linux':
         base = '/usr/lib/jvm'
         candidateJdks = [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))]
+        base = '/usr/java'
+        candidateJdks += [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))]
     elif get_os() == 'solaris':
         base = '/usr/jdk/instances'
         candidateJdks = [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))]
@@ -5331,7 +5333,7 @@
     if opts.extra_java_homes:
         for java_home in opts.extra_java_homes.split(os.pathsep):
             extraJdk = JavaConfig(java_home, opts.java_dbg_port)
-            if extraJdk > defaultJdk:
+            if extraJdk.javaCompliance > defaultJdk.javaCompliance:
                 abort('Secondary JDK ' + extraJdk.jdk + ' has higher compliance level than default JDK ' + defaultJdk.jdk)
             _java_homes.append(extraJdk)
 
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/cfg.filter	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-var f = new com.sun.hotspot.igv.graal.filters.GraalCFGFilter();
-f.apply(graph);
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Tue Mar 31 19:01:07 2015 -0700
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Tue Mar 31 19:15:45 2015 -0700
@@ -1,11 +1,28 @@
-colorize("name", ".*", white);
-colorize("name", "Begin|KillingBegin|EndNode|LoopBegin|LoopEnd|LoopExit|Return", orange);
-colorize("class", "FrameState", new java.awt.Color(0.5, 0.8, 1.0));
-colorize("name", "If|Merge|(Integer|Type)Switch", pink);
-colorize("name", "\\+|-|\\*|/|&|\\||<<|>>|>>>", cyan);
-colorize("name", "Virtual.*", green);
-colorize("name", "(Φ|Proxy)\(.*\)", magenta);
-colorize("name", "(Φ|Proxy)\(.*\) Identity\(.*\)", green);
-colorize("name", "C\(.*\)", new java.awt.Color(0.7, 0.7, 0.7));
-colorize("name", "P\(.*\)", new java.awt.Color(0.85, 0.85, 0.85));
-colorize("name", "==|<|InstanceOf", yellow);
+var red =  new java.awt.Color(240, 59, 32);
+var orange = new java.awt.Color(254, 178, 76);
+var yellow = new java.awt.Color(255, 237, 160);
+var middleBlue = new java.awt.Color(100, 147, 224);
+var lightGreen = new java.awt.Color(173, 221, 142);
+var lightBlue = new java.awt.Color(200, 200, 250);
+var gray = new java.awt.Color(220, 220, 220);
+var violet = new java.awt.Color(201, 148, 199);
+colorize("category", "controlSink", red);
+colorize("category", "controlSplit", red);
+colorize("category", "merge", red);
+colorize("category", "begin", orange);
+colorize("category", "end", orange);
+colorize("category", "fixed", yellow);
+colorize("category", "state", lightGreen);
+colorize("category", "phi", middleBlue);
+colorize("category", "proxy", middleBlue);
+colorize("category", "floating", lightBlue);
+colorize("class", "ConstantLocationNode", gray);
+colorize("class", "ParameterNode", gray);
+colorize("class", "ConstantNode", gray);
+colorize("class", "GuardNode", violet);
+
+var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter();
+f.setUsageColor("Successor", red);
+f.setUsageColor("Value", blue);
+f.setUsageColor("Memory", new Color(0.0, 0.5, 0.0));
+f.apply(graph);
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/edgeColor.filter	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter();
-f.setUsageColor("Successor", red);
-f.setUsageColor("Value", blue);
-f.setUsageColor("Memory", new Color(0.0, 0.5, 0.0));
-f.apply(graph);
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/noframestate.filter	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-remove("class", "FrameState");
-remove("class", "Virtual.*");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeFloating.filter	Tue Mar 31 19:15:45 2015 -0700
@@ -0,0 +1,4 @@
+remove("category", "floating");
+remove("category", "state");
+remove("category", "phi");
+remove("category", "proxy");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeState.filter	Tue Mar 31 19:15:45 2015 -0700
@@ -0,0 +1,1 @@
+remove("category", "state");
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/slots.filter	Tue Mar 31 19:01:07 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-removeUnconnectedSlots(true, true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/stampColor.filter	Tue Mar 31 19:15:45 2015 -0700
@@ -0,0 +1,16 @@
+var red =  new java.awt.Color(240, 59, 32);
+var orange = new java.awt.Color(254, 178, 76);
+var yellow = new java.awt.Color(255, 237, 160);
+var middleBlue = new java.awt.Color(100, 147, 224);
+var lightGreen = new java.awt.Color(173, 221, 142);
+var lightBlue = new java.awt.Color(200, 200, 250);
+var gray = new java.awt.Color(220, 220, 220);
+var violet = new java.awt.Color(201, 148, 199);
+
+colorize("stamp", ".*", white);
+colorize("stamp", "void", gray);
+colorize("stamp", "a.*", yellow);
+colorize("stamp", "a#.*", orange);
+colorize("stamp", "a!.*", red);
+colorize("stamp", "i.*", middleBlue);
+colorize("stamp", "f.*", lightGreen);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Tue Mar 31 19:01:07 2015 -0700
+++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Tue Mar 31 19:15:45 2015 -0700
@@ -2,35 +2,32 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
     <folder name="Filters">
-        <file name="Graal Coloring" url="filters/color.filter">
-            <attr name="enabled" boolvalue="false"/>
+        <file name="Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="true"/>
         </file>
         
-        <file name="Graal Edge Coloring" url="filters/edgeColor.filter">
+        
+        <file name="Stamp Coloring" url="filters/stampColor.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
-        
-        <file name="Graal Remove Unconnected Slots" url="filters/slots.filter">
+      
+        <file name="Probability Coloring" url="filters/probability.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
         
-        <file name="Graal Probability" url="filters/probability.filter">
-            <attr name="enabled" boolvalue="false"/>
-        </file>
-        
-        <file name="Graal Reduce Edges" url="filters/reduceEdges.filter">
+        <file name="Call Graph Coloring" url="filters/callgraph.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
         
-        <file name="Graal Remove FrameState" url="filters/noframestate.filter">
+        <file name="Reduce Edges" url="filters/reduceEdges.filter">
+            <attr name="enabled" boolvalue="true"/>
+        </file>
+        
+        <file name="Remove State" url="filters/removeState.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
         
-        <file name="Graal Call Analysis" url="filters/callgraph.filter">
-            <attr name="enabled" boolvalue="false"/>
-        </file>
-        
-        <file name="Graal CFG-only" url="filters/cfg.filter">
+        <file name="Remove Floating" url="filters/removeFloating.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
     </folder>
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Tue Mar 31 19:01:07 2015 -0700
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Tue Mar 31 19:15:45 2015 -0700
@@ -538,15 +538,9 @@
                 if (n2.vertex == null) {
                     return 0;
                 }
-                if (n1.preds.size() == 1 && n1.preds.get(0).from.vertex != null) {
-                    return 1;
-                }
                 return -1;
             }
             if (n2.vertex == null) {
-                if (n2.preds.size() == 1 && n2.preds.get(0).from.vertex != null) {
-                    return -1;
-                }
                 return 1;
             }
             return n1.preds.size() - n2.preds.size();
@@ -568,24 +562,18 @@
                     n2VIP++;
                 }
             }
+            if (n1VIP != n2VIP) {
+                return n2VIP - n1VIP;
+            }
             if (n1.vertex == null) {
                 if (n2.vertex == null) {
                     return 0;
                 }
-                if (n1.succs.size() == 1 && n1.succs.get(0).to.vertex != null) {
-                    return 1;
-                }
                 return -1;
             }
             if (n2.vertex == null) {
-                if (n2.succs.size() == 1 && n2.succs.get(0).to.vertex != null) {
-                    return -1;
-                }
                 return 1;
             }
-            if (n1VIP != n2VIP) {
-                return n2VIP - n1VIP;
-            }
             return n1.succs.size() - n2.succs.size();
         }
     };
@@ -634,11 +622,13 @@
             for (int i = 0; i < SWEEP_ITERATIONS; i++) {
                 sweepDown();
                 adjustSpace();
-                sweepUp();
+                sweepUp(false);
                 adjustSpace();
             }
 
             sweepDown();
+            adjustSpace();
+            sweepUp(true);
         }
 
         private void adjustSpace() {
@@ -730,7 +720,7 @@
             }
         }
 
-        private void sweepUp() {
+        private void sweepUp(boolean onlyDummies) {
             for (int i = layers.length - 1; i >= 0; i--) {
                 NodeRow r = new NodeRow(space[i]);
                 for (LayoutNode n : upProcessingOrder[i]) {
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Tue Mar 31 19:01:07 2015 -0700
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Tue Mar 31 19:15:45 2015 -0700
@@ -2,6 +2,7 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
       <folder name="Filters">
+          <!--
         <file name="C2 Basic Coloring" url="filters/color.filter">
             <attr name="enabled" boolvalue="false"/>
         </file>
@@ -25,5 +26,6 @@
             <attr name="enabled" boolvalue="false"/>
             <attr name="after" stringvalue="C2 Remove Filter"/>
         </file>
+        -->
     </folder>	
 </filesystem>