changeset 19792:90f0e7566dc0

Merge.
author Doug Simon <doug.simon@oracle.com>
date Wed, 11 Mar 2015 20:43:52 +0100
parents 14e703edb2ab (current diff) 905afef74a2e (diff)
children 9cfcbadec537
files graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java
diffstat 47 files changed, 695 insertions(+), 212 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static org.junit.Assert.*;
-
 import org.junit.*;
 
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConcreteSubtypeTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConcreteSubtypeTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static org.junit.Assert.*;
-
 import org.junit.*;
 
 import com.oracle.graal.api.code.Assumptions.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerAssumptionsTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerAssumptionsTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static org.junit.Assert.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.Assumptions.Assumption;
 import com.oracle.graal.api.meta.*;
@@ -70,9 +68,9 @@
             try {
                 Class.forName(fullName);
             } catch (ClassNotFoundException e) {
-                assertFalse(String.format("Can't find class %s", fullName), true);
+                fail("Can't find class %s", fullName);
             }
-            assertTrue(!willInvalidate == installedCode.isValid());
+            assertTrue(!willInvalidate == installedCode.isValid(), "method should be %s", willInvalidate ? "invalid" : "valid");
         }
     }
 
@@ -83,7 +81,7 @@
                 found = true;
             }
         }
-        assertTrue(String.format("Can't find assumption %s", expectedAssumption), found);
+        assertTrue(found, "Can't find assumption %s", expectedAssumption);
     }
 
     /**
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -23,8 +23,6 @@
 package com.oracle.graal.compiler.test;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static org.junit.Assert.*;
-
 import java.util.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static org.junit.Assert.*;
-
 import java.util.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static org.junit.Assert.*;
-
 import java.util.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EAMergingTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
-import static org.junit.Assert.*;
-
 import org.junit.*;
 
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
-import static org.junit.Assert.*;
-
 import java.util.concurrent.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
-import static org.junit.Assert.*;
-
 import java.util.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.test.inlining;
 
-import static org.junit.Assert.*;
-
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyCompilerConfiguration.java	Wed Mar 11 20:43:52 2015 +0100
@@ -0,0 +1,60 @@
+/*
+ * 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.compiler.phases;
+
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.lir.phases.*;
+import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.*;
+import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*;
+import com.oracle.graal.lir.phases.AllocationPhase.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
+
+@ServiceProvider(CompilerConfiguration.class)
+public class EconomyCompilerConfiguration implements CompilerConfiguration {
+
+    public PhaseSuite<HighTierContext> createHighTier() {
+        return new EconomyHighTier();
+    }
+
+    public PhaseSuite<MidTierContext> createMidTier() {
+        return new EconomyMidTier();
+    }
+
+    public PhaseSuite<LowTierContext> createLowTier() {
+        return new EconomyLowTier();
+    }
+
+    public LIRPhaseSuite<PreAllocationOptimizationContext> createPreAllocationOptimizationStage() {
+        return new EconomyPreAllocationOptimizationStage();
+    }
+
+    public LIRPhaseSuite<AllocationContext> createAllocationStage() {
+        return new EconomyAllocationStage();
+    }
+
+    public LIRPhaseSuite<PostAllocationOptimizationContext> createPostAllocationOptimizationStage() {
+        return new EconomyPostAllocationOptimizationStage();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java	Wed Mar 11 20:43:52 2015 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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.compiler.phases;
+
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class EconomyHighTier extends PhaseSuite<HighTierContext> {
+
+    public EconomyHighTier() {
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+        if (ImmutableCode.getValue()) {
+            canonicalizer.disableReadCanonicalization();
+        }
+        appendPhase(new CleanTypeProfileProxyPhase(canonicalizer));
+        appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyLowTier.java	Wed Mar 11 20:43:52 2015 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.compiler.phases;
+
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class EconomyLowTier extends PhaseSuite<LowTierContext> {
+
+    public EconomyLowTier() {
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+        if (ImmutableCode.getValue()) {
+            canonicalizer.disableReadCanonicalization();
+        }
+
+        appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.LOW_TIER));
+
+        appendPhase(new ExpandLogicPhase());
+        appendPhase(new RemoveValueProxyPhase());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyMidTier.java	Wed Mar 11 20:43:52 2015 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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.compiler.phases;
+
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.tiers.*;
+
+public class EconomyMidTier extends PhaseSuite<MidTierContext> {
+
+    public EconomyMidTier() {
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
+        if (ImmutableCode.getValue()) {
+            canonicalizer.disableReadCanonicalization();
+        }
+
+        appendPhase(new LoopSafepointInsertionPhase());
+
+        appendPhase(new GuardLoweringPhase());
+
+        appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER));
+
+        appendPhase(new FrameStateAssignmentPhase());
+    }
+}
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ArrayCopyIntrinsificationTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ArrayCopyIntrinsificationTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.hotspot.test;
 
-import static org.junit.Assert.*;
-
 import java.lang.reflect.*;
 import java.util.*;
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ClassSubstitutionsTests.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ClassSubstitutionsTests.java	Wed Mar 11 20:43:52 2015 +0100
@@ -23,8 +23,6 @@
 
 package com.oracle.graal.hotspot.test;
 
-import static org.junit.Assert.*;
-
 import org.junit.*;
 
 import com.oracle.graal.compiler.test.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Wed Mar 11 20:43:52 2015 +0100
@@ -1503,6 +1503,7 @@
 
     @HotSpotVMConstant(name = "GraalEnv::ok") @Stable public int codeInstallResultOk;
     @HotSpotVMConstant(name = "GraalEnv::dependencies_failed") @Stable public int codeInstallResultDependenciesFailed;
+    @HotSpotVMConstant(name = "GraalEnv::dependencies_invalid") @Stable public int codeInstallResultDependenciesInvalid;
     @HotSpotVMConstant(name = "GraalEnv::cache_full") @Stable public int codeInstallResultCacheFull;
     @HotSpotVMConstant(name = "GraalEnv::code_too_large") @Stable public int codeInstallResultCodeTooLarge;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Mar 11 20:43:52 2015 +0100
@@ -176,6 +176,7 @@
     public enum CodeInstallResult {
         OK("ok"),
         DEPENDENCIES_FAILED("dependencies failed"),
+        DEPENDENCIES_INVALID("dependencies invalid"),
         CACHE_FULL("code cache is full"),
         CODE_TOO_LARGE("code is too large");
 
@@ -191,6 +192,9 @@
                 case "dependencies failed":
                     this.value = config.codeInstallResultDependenciesFailed;
                     break;
+                case "dependencies invalid":
+                    this.value = config.codeInstallResultDependenciesInvalid;
+                    break;
                 case "code cache is full":
                     this.value = config.codeInstallResultCacheFull;
                     break;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Wed Mar 11 20:43:52 2015 +0100
@@ -264,9 +264,14 @@
         if (result != CodeInstallResult.OK) {
             String msg = compiledCode.getInstallationFailureMessage();
             if (msg != null) {
-                throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s%n%s", result, msg);
+                msg = String.format("Code installation failed: %s%n%s", result, msg);
+            } else {
+                msg = String.format("Code installation failed: %s", result);
             }
-            throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s", result);
+            if (result == CodeInstallResult.DEPENDENCIES_INVALID) {
+                throw new AssertionError(result + " " + msg);
+            }
+            throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, msg);
         }
         return logOrDump(installedCode, compResult);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/EconomyAllocationStage.java	Wed Mar 11 20:43:52 2015 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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.lir.phases;
+
+import com.oracle.graal.lir.alloc.lsra.*;
+import com.oracle.graal.lir.phases.AllocationPhase.*;
+import com.oracle.graal.lir.stackslotalloc.*;
+
+public class EconomyAllocationStage extends LIRPhaseSuite<AllocationContext> {
+    public EconomyAllocationStage() {
+        appendPhase(new LinearScanPhase());
+
+        // build frame map
+        appendPhase(new SimpleStackSlotAllocator());
+
+        // currently we mark locations only if we do register allocation
+        appendPhase(new LocationMarker());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/EconomyPostAllocationOptimizationStage.java	Wed Mar 11 20:43:52 2015 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.lir.phases;
+
+import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.*;
+
+public class EconomyPostAllocationOptimizationStage extends LIRPhaseSuite<PostAllocationOptimizationContext> {
+    public EconomyPostAllocationOptimizationStage() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/EconomyPreAllocationOptimizationStage.java	Wed Mar 11 20:43:52 2015 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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.lir.phases;
+
+import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.*;
+
+public class EconomyPreAllocationOptimizationStage extends LIRPhaseSuite<PreAllocationOptimizationContext> {
+    public EconomyPreAllocationOptimizationStage() {
+    }
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Wed Mar 11 20:43:52 2015 +0100
@@ -94,21 +94,26 @@
     private static void optimizeAtControlSplit(ControlSplitNode controlSplit, LazyCFG cfg) {
         AbstractBeginNode successor = findMinimumUsagesSuccessor(controlSplit);
         int successorCount = controlSplit.successors().count();
-        List<GuardNode> otherGuards = new ArrayList<>(successorCount - 1);
         for (GuardNode guard : successor.guards().snapshot()) {
             if (guard.isDeleted() || guard.condition().getUsageCount() < successorCount) {
                 continue;
             }
+            List<GuardNode> otherGuards = new ArrayList<>(successorCount - 1);
+            HashSet<Node> successorsWithoutGuards = new HashSet<>(controlSplit.successors().count());
+            controlSplit.successors().snapshotTo(successorsWithoutGuards);
+            successorsWithoutGuards.remove(guard.getAnchor());
             for (GuardNode conditonGuard : guard.condition().usages().filter(GuardNode.class)) {
                 if (conditonGuard != guard) {
-                    AnchoringNode conditonGuardAnchor = conditonGuard.getAnchor();
-                    if (conditonGuardAnchor.asNode().predecessor() == controlSplit && compatibleGuards(guard, conditonGuard)) {
+                    AnchoringNode conditionGuardAnchor = conditonGuard.getAnchor();
+                    if (conditionGuardAnchor.asNode().predecessor() == controlSplit && compatibleGuards(guard, conditonGuard)) {
                         otherGuards.add(conditonGuard);
+                        successorsWithoutGuards.remove(conditionGuardAnchor);
                     }
                 }
             }
 
-            if (otherGuards.size() == successorCount - 1) {
+            if (successorsWithoutGuards.isEmpty()) {
+                assert otherGuards.size() >= successorCount - 1;
                 AbstractBeginNode anchor = computeOptimalAnchor(cfg.get(), AbstractBeginNode.prevBegin(controlSplit));
                 GuardNode newGuard = controlSplit.graph().unique(new GuardNode(guard.condition(), anchor, guard.reason(), guard.action(), guard.isNegated(), guard.getSpeculation()));
                 for (GuardNode otherGuard : otherGuards) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Wed Mar 11 20:43:52 2015 +0100
@@ -377,19 +377,34 @@
         processStack(blockToNodes, nodeToBlock, visited, stack);
 
         // Visit back input edges of loop phis.
-        for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.TYPE)) {
-            for (PhiNode phi : loopBegin.phis()) {
-                if (visited.isMarked(phi)) {
-                    for (int i = 0; i < loopBegin.getLoopEndCount(); ++i) {
-                        Node node = phi.valueAt(i + loopBegin.forwardEndCount());
-                        if (node != null && !visited.isMarked(node)) {
-                            stack.push(node);
-                            processStack(blockToNodes, nodeToBlock, visited, stack);
+
+        boolean changed;
+        boolean unmarkedPhi;
+        do {
+            changed = false;
+            unmarkedPhi = false;
+            for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.TYPE)) {
+                for (PhiNode phi : loopBegin.phis()) {
+                    if (visited.isMarked(phi)) {
+                        for (int i = 0; i < loopBegin.getLoopEndCount(); ++i) {
+                            Node node = phi.valueAt(i + loopBegin.forwardEndCount());
+                            if (node != null && !visited.isMarked(node)) {
+                                changed = true;
+                                stack.push(node);
+                                processStack(blockToNodes, nodeToBlock, visited, stack);
+                            }
                         }
+                    } else {
+                        unmarkedPhi = true;
                     }
                 }
             }
-        }
+
+            /*
+             * the processing of one loop phi could have marked a previously checked loop phi,
+             * therefore this needs to be iterative.
+             */
+        } while (unmarkedPhi && changed);
 
         // Check for dead nodes.
         if (visited.getCounter() < graph.getNodeCount()) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java	Wed Mar 11 20:43:52 2015 +0100
@@ -75,7 +75,9 @@
             name = name.toLowerCase();
 
             configurations.put(name, config);
-            if (name.equals("basic")) {
+            if (name.equals("economy")) {
+                // ignore economy configuration if not explicitely specified
+            } else if (name.equals("basic")) {
                 assert basic == null;
                 basic = config;
             } else {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.replacements.test;
 
-import static org.junit.Assert.*;
-
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.code.*;
--- a/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.test;
 
-import static org.junit.Assert.*;
-
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
@@ -253,4 +251,105 @@
             }
         }
     }
+
+    /*
+     * Overrides to the normal JUnit {@link Assert} routines that provide varargs style formatting
+     * and produce an exception stack trace with the assertion frames trimmed out.
+     */
+
+    /**
+     * Fails a test with the given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     *            okay)
+     * @see AssertionError
+     */
+    public static void fail(String message, Object... objects) {
+        AssertionError e;
+        if (message == null) {
+            e = new AssertionError();
+        } else {
+            e = new AssertionError(String.format(message, objects));
+        }
+        // Trim the assert frames from the stack trace
+        StackTraceElement[] trace = e.getStackTrace();
+        int start = 1; // Skip this frame
+        String thisClassName = GraalTest.class.getName();
+        while (start < trace.length && trace[start].getClassName().equals(thisClassName) && (trace[start].getMethodName().equals("assertTrue") || trace[start].getMethodName().equals("assertFalse"))) {
+            start++;
+        }
+        e.setStackTrace(Arrays.copyOfRange(trace, start, trace.length));
+        throw e;
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws an {@link AssertionError} with the
+     * given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     *            okay)
+     * @param condition condition to be checked
+     */
+    public static void assertTrue(String message, boolean condition) {
+        assertTrue(condition, message);
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws an {@link AssertionError} without a
+     * message.
+     *
+     * @param condition condition to be checked
+     */
+    public static void assertTrue(boolean condition) {
+        assertTrue(condition, null);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws an {@link AssertionError} with the
+     * given message.
+     *
+     * @param message the identifying message for the {@link AssertionError} (<code>null</code>
+     *            okay)
+     * @param condition condition to be checked
+     */
+    public static void assertFalse(String message, boolean condition) {
+        assertTrue(!condition, message);
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws an {@link AssertionError} without a
+     * message.
+     *
+     * @param condition condition to be checked
+     */
+    public static void assertFalse(boolean condition) {
+        assertTrue(!condition, null);
+    }
+
+    /**
+     * Asserts that a condition is true. If it isn't it throws an {@link AssertionError} with the
+     * given message.
+     *
+     * @param condition condition to be checked
+     * @param message the identifying message for the {@link AssertionError}
+     * @param objects arguments to the format string
+     */
+    public static void assertTrue(boolean condition, String message, Object... objects) {
+        if (!condition) {
+            fail(message, objects);
+        }
+    }
+
+    /**
+     * Asserts that a condition is false. If it isn't it throws an {@link AssertionError} with the
+     * given message produced by {@link String#format}.
+     *
+     * @param condition condition to be checked
+     * @param message the identifying message for the {@link AssertionError}
+     * @param objects arguments to the format string
+     */
+    public static void assertFalse(boolean condition, String message, Object... objects) {
+        assertTrue(!condition, message, objects);
+    }
+
 }
--- a/graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive1.sl	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive1.sl	Wed Mar 11 20:43:52 2015 +0100
@@ -20,6 +20,4 @@
 
 function main() {
     callUntilOptimized(test);
-    assertTrue(isInlined(test, test, fib), "fib is not inlined");
-    assertFalse(isInlined(test, fib, fib), "fib -> fib is not inlined");
 }  
--- a/graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive2.sl	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.truffle.test/sl/TestInliningRecursive2.sl	Wed Mar 11 20:43:52 2015 +0100
@@ -29,9 +29,4 @@
 function main() {
     callUntilOptimized(test);
     assertTrue(isInlined(test, test, fib), "not inlined: test -> fib");
-    
-    assertTrue(isInlined(test, fib, call), "not inlined: fib -> call");
-    assertFalse(isInlined(test, call, fib), "inlined: call -> fib"); 
-    assertTrue(isInlined(test, call, void), "inlined: call -> void");
-    
 }  
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultInliningPolicy.java	Wed Mar 11 20:43:52 2015 +0100
@@ -28,7 +28,7 @@
 
 public class DefaultInliningPolicy implements TruffleInliningPolicy {
 
-    private static final String REASON_RECURSION = "recursion";
+    private static final String REASON_RECURSION = "number of recursions > " + TruffleMaximumRecursiveInlining.getValue();
     private static final String REASON_MAXIMUM_NODE_COUNT = "deepNodeCount * callSites  > " + TruffleInliningMaxCallerSize.getValue();
     private static final String REASON_MAXIMUM_TOTAL_NODE_COUNT = "totalNodeCount > " + TruffleInliningMaxCallerSize.getValue();
 
@@ -39,7 +39,7 @@
 
     @Override
     public boolean isAllowed(TruffleInliningProfile profile, int currentNodeCount, CompilerOptions options) {
-        if (profile.isRecursiveCall()) {
+        if (profile.getRecursions() > TruffleMaximumRecursiveInlining.getValue()) {
             profile.setFailedReason(REASON_RECURSION);
             return false;
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Mar 11 20:43:52 2015 +0100
@@ -74,6 +74,9 @@
     @Option(help = "Stop inlining if caller's cumulative tree size would exceed this limit", type = OptionType.Expert)
     public static final OptionValue<Integer> TruffleInliningMaxCallerSize = new OptionValue<>(2250);
 
+    @Option(help = "Maximum level of recursive inlining", type = OptionType.Expert)
+    public static final OptionValue<Integer> TruffleMaximumRecursiveInlining = new OptionValue<>(4);
+
     @Option(help = "Defines the number of graal nodes that triggers a performance warning.", type = OptionType.Debug)
     public static final OptionValue<Integer> TrufflePerformanceWarningGraalNodeCount = new OptionValue<>(1000);
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java	Wed Mar 11 20:43:52 2015 +0100
@@ -68,15 +68,15 @@
         double frequency = calculateFrequency(parentTarget, callNode);
         int nodeCount = callNode.getCurrentCallTarget().countNonTrivialNodes();
 
-        boolean recursive = isRecursiveStack(callStack);
+        int recursions = countRecursions(callStack);
         int deepNodeCount = nodeCount;
-        if (!recursive && callStack.size() < 15) {
+        if (callStack.size() < 15 && recursions <= TruffleCompilerOptions.TruffleMaximumRecursiveInlining.getValue()) {
             /*
              * We make a preliminary optimistic inlining decision with best possible characteristics
              * to avoid the exploration of unnecessary paths in the inlining tree.
              */
             final CompilerOptions options = callNode.getRootNode().getCompilerOptions();
-            if (policy.isAllowed(new TruffleInliningProfile(callNode, nodeCount, nodeCount, frequency, recursive), callStackNodeCount, options)) {
+            if (policy.isAllowed(new TruffleInliningProfile(callNode, nodeCount, nodeCount, frequency, recursions), callStackNodeCount, options)) {
                 List<TruffleInliningDecision> exploredCallSites = exploreCallSites(callStack, callStackNodeCount + nodeCount, policy);
                 childCallSites = decideInlining(exploredCallSites, policy, nodeCount, options);
                 for (TruffleInliningDecision childCallSite : childCallSites) {
@@ -90,7 +90,7 @@
             }
         }
 
-        TruffleInliningProfile profile = new TruffleInliningProfile(callNode, nodeCount, deepNodeCount, frequency, recursive);
+        TruffleInliningProfile profile = new TruffleInliningProfile(callNode, nodeCount, deepNodeCount, frequency, recursions);
         profile.setScore(policy.calculateScore(profile));
         return new TruffleInliningDecision(currentTarget, profile, childCallSites);
     }
@@ -99,14 +99,16 @@
         return (double) Math.max(1, ocn.getCallCount()) / (double) Math.max(1, target.getCompilationProfile().getInterpreterCallCount());
     }
 
-    private static boolean isRecursiveStack(List<OptimizedCallTarget> stack) {
+    private static int countRecursions(List<OptimizedCallTarget> stack) {
+        int count = 0;
         OptimizedCallTarget top = stack.get(stack.size() - 1);
         for (int i = 0; i < stack.size() - 1; i++) {
             if (stack.get(i) == top) {
-                return true;
+                count++;
             }
         }
-        return false;
+
+        return count;
     }
 
     private static List<TruffleInliningDecision> decideInlining(List<TruffleInliningDecision> callSites, TruffleInliningPolicy policy, int nodeCount, CompilerOptions options) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningProfile.java	Wed Mar 11 20:43:52 2015 +0100
@@ -30,22 +30,22 @@
     private final int nodeCount;
     private final int deepNodeCount;
     private final double frequency;
-    private final boolean recursiveCall;
+    private final int recursions;
 
     private String failedReason;
     private int queryIndex = -1;
     private double score;
 
-    public TruffleInliningProfile(OptimizedDirectCallNode callNode, int nodeCount, int deepNodeCount, double frequency, boolean recursiveCall) {
+    public TruffleInliningProfile(OptimizedDirectCallNode callNode, int nodeCount, int deepNodeCount, double frequency, int recursions) {
         this.callNode = callNode;
         this.nodeCount = nodeCount;
         this.deepNodeCount = deepNodeCount;
         this.frequency = frequency;
-        this.recursiveCall = recursiveCall;
+        this.recursions = recursions;
     }
 
-    public boolean isRecursiveCall() {
-        return recursiveCall;
+    public int getRecursions() {
+        return recursions;
     }
 
     public OptimizedDirectCallNode getCallNode() {
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MergeSpecializationsTest.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/MergeSpecializationsTest.java	Wed Mar 11 20:43:52 2015 +0100
@@ -84,27 +84,37 @@
 
     @Test
     public void testMultithreadedMergeInOrder() {
-        multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3);
+        for (int i = 0; i < 100; i++) {
+            multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3);
+        }
     }
 
     @Test
     public void testMultithreadedMergeReverse() {
-        multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1.0, 1L << 32, 1), 3, 2, 1);
+        for (int i = 0; i < 100; i++) {
+            multithreadedMerge(TestNodeFactory.getInstance(), new Executions(1.0, 1L << 32, 1), 3, 2, 1);
+        }
     }
 
     @Test
     public void testMultithreadedMergeCachedInOrder() {
-        multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3);
+        for (int i = 0; i < 100; i++) {
+            multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 1L << 32, 1.0), 1, 2, 3);
+        }
     }
 
     @Test
     public void testMultithreadedMergeCachedTwoEntries() {
-        multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 1.0), 1, 1, 3);
+        for (int i = 0; i < 100; i++) {
+            multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 1.0), 1, 1, 3);
+        }
     }
 
     @Test
     public void testMultithreadedMergeCachedThreeEntries() {
-        multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 3), 1, 1, 1);
+        for (int i = 0; i < 100; i++) {
+            multithreadedMerge(TestCachedNodeFactory.getInstance(), new Executions(1, 2, 3), 1, 1, 1);
+        }
     }
 
     private static <T extends ValueNode> void multithreadedMerge(NodeFactory<T> factory, final Executions executions, int... order) {
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Cached.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Cached.java	Wed Mar 11 20:43:52 2015 +0100
@@ -86,7 +86,7 @@
  *
  * <pre>
  *  &#064;Specialization
- *  void doCached(int operand, @Local(&quot;operand&quot;) int cachedOperand) {
+ *  void doCached(int operand, @Cached(&quot;operand&quot;) int cachedOperand) {
  *      CompilerAsserts.compilationConstant(cachedOperand);
  *      ...
  *  }
@@ -111,7 +111,7 @@
  * specialization instantiation limit is <code>3</code>.
  *
  * <pre>
- * &#064;Specialization(guards = &quot;==(operand, cachedOperand)&quot;)
+ * &#064;Specialization(guards = &quot;operand == cachedOperand&quot;)
  * void doCached(int operand, @Cached(&quot;operand&quot;) int cachedOperand) {
  *    CompilerAsserts.compilationConstant(cachedOperand);
  *    ...
@@ -139,7 +139,7 @@
  * <code>doCached</code> instances remain but no new instances are created.
  *
  * <code>
- * &#064;Specialization(guards = &quot;==(operand, cachedOperand)&quot;)
+ * &#064;Specialization(guards = &quot;operand == cachedOperand&quot;)
  * void doCached(int operand, @Cached(&quot;operand&quot;) int cachedOperand) {
  *    CompilerAsserts.compilationConstant(cachedOperand);
  *    ...
@@ -209,7 +209,7 @@
  *
  * <pre>
  * &#064;Specialization
- * void s(int operand, @Local(&quot;create()&quot;) BranchProfile profile) {
+ * void s(int operand, @Cached(&quot;create()&quot;) BranchProfile profile) {
  * }
  * </pre>
  *
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/SpecializationNode.java	Wed Mar 11 20:43:52 2015 +0100
@@ -266,11 +266,18 @@
     }
 
     protected final SpecializationNode removeSame(final CharSequence reason) {
-        return atomic(new Callable<SpecializationNode>() {
-            public SpecializationNode call() throws Exception {
-                return removeSameImpl(SpecializationNode.this, reason);
+        SpecializationNode start = SpecializationNode.this.findStart();
+        SpecializationNode current = start;
+        while (current != null) {
+            if (current.isSame(SpecializationNode.this)) {
+                NodeUtil.nonAtomicReplace(current, current.next, reason);
+                if (current == start) {
+                    start = start.next;
+                }
             }
-        });
+            current = current.next;
+        }
+        return SpecializationNode.this.findEnd().findStart();
     }
 
     /** Find the topmost of the specialization chain. */
@@ -377,86 +384,65 @@
 
     protected final Object uninitialized(Frame frame) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        SpecializationNode nextSpecialization = createNext(frame);
-        if (nextSpecialization == null) {
-            nextSpecialization = createFallback();
-        }
-        if (nextSpecialization == null) {
+        SpecializationNode newNode = atomic(new InsertionEvent0(this, "insert new specialization", frame));
+        if (newNode == null) {
             return unsupported(frame);
         }
-        return atomic(new InsertionEvent0(this, "insert new specialization", frame, nextSpecialization)).acceptAndExecute(frame);
+        return newNode.acceptAndExecute(frame);
     }
 
     protected final Object uninitialized(Frame frame, Object o1) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        SpecializationNode nextSpecialization = createNext(frame, o1);
-        if (nextSpecialization == null) {
-            nextSpecialization = createFallback();
-        }
-        if (nextSpecialization == null) {
+        SpecializationNode newNode = atomic(new InsertionEvent1(this, "insert new specialization", frame, o1));
+        if (newNode == null) {
             return unsupported(frame, o1);
         }
-        return atomic(new InsertionEvent1(this, "insert new specialization", frame, o1, nextSpecialization)).acceptAndExecute(frame, o1);
+        return newNode.acceptAndExecute(frame, o1);
     }
 
     protected final Object uninitialized(Frame frame, Object o1, Object o2) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        SpecializationNode nextSpecialization = createNext(frame, o1, o2);
-        if (nextSpecialization == null) {
-            nextSpecialization = createFallback();
-        }
-        if (nextSpecialization == null) {
+        SpecializationNode newNode = atomic(new InsertionEvent2(this, "insert new specialization", frame, o1, o2));
+        if (newNode == null) {
             return unsupported(frame, o1, o2);
         }
-        return atomic(new InsertionEvent2(this, "insert new specialization", frame, o1, o2, nextSpecialization)).acceptAndExecute(frame, o1, o2);
+        return newNode.acceptAndExecute(frame, o1, o2);
     }
 
     protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        SpecializationNode nextSpecialization = createNext(frame, o1, o2, o3);
-        if (nextSpecialization == null) {
-            nextSpecialization = createFallback();
-        }
-        if (nextSpecialization == null) {
+        SpecializationNode newNode = atomic(new InsertionEvent3(this, "insert new specialization", frame, o1, o2, o3));
+        if (newNode == null) {
             return unsupported(frame, o1, o2, o3);
         }
-        return atomic(new InsertionEvent3(this, "insert new specialization", frame, o1, o2, o3, nextSpecialization)).acceptAndExecute(frame, o1, o2, o3);
+        return newNode.acceptAndExecute(frame, o1, o2, o3);
     }
 
     protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        SpecializationNode nextSpecialization = createNext(frame, o1, o2, o3, o4);
-        if (nextSpecialization == null) {
-            nextSpecialization = createFallback();
-        }
-        if (nextSpecialization == null) {
+        SpecializationNode newNode = atomic(new InsertionEvent4(this, "insert new specialization", frame, o1, o2, o3, o4));
+        if (newNode == null) {
             return unsupported(frame, o1, o2, o3, o4);
         }
-        return atomic(new InsertionEvent4(this, "insert new specialization", frame, o1, o2, o3, o4, nextSpecialization)).acceptAndExecute(frame, o1, o2, o3, o4);
+        return newNode.acceptAndExecute(frame, o1, o2, o3, o4);
     }
 
     protected final Object uninitialized(Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        SpecializationNode nextSpecialization = createNext(frame, o1, o2, o3, o4, o5);
-        if (nextSpecialization == null) {
-            nextSpecialization = createFallback();
+        SpecializationNode newNode = atomic(new InsertionEvent5(this, "insert new specialization", frame, o1, o2, o3, o4, o5));
+        if (newNode == null) {
+            return unsupported(frame, o1, o2, o3, o4, o5);
         }
-        if (nextSpecialization == null) {
-            unsupported(frame, o1, o2, o3, o4, o5);
-        }
-        return atomic(new InsertionEvent5(this, "insert new specialization", frame, o1, o2, o3, o4, o5, nextSpecialization)).acceptAndExecute(frame, o1, o2, o3, o4, o5);
+        return newNode.acceptAndExecute(frame, o1, o2, o3, o4, o5);
     }
 
     protected final Object uninitialized(Frame frame, Object... args) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        SpecializationNode nextSpecialization = createNext(frame, args);
-        if (nextSpecialization == null) {
-            nextSpecialization = createFallback();
+        SpecializationNode newNode = atomic(new InsertionEventN(this, "insert new specialization", frame, args));
+        if (newNode == null) {
+            return unsupported(frame, args);
         }
-        if (nextSpecialization == null) {
-            unsupported(frame, args);
-        }
-        return atomic(new InsertionEventN(this, "insert new specialization", frame, args, nextSpecialization)).acceptAndExecute(frame, args);
+        return newNode.acceptAndExecute(frame, args);
     }
 
     protected final Object remove(String reason, Frame frame) {
@@ -623,14 +609,18 @@
 
     private static final class InsertionEvent0 extends SlowPathEvent0 implements Callable<SpecializationNode> {
 
-        private final SpecializationNode next;
-
-        public InsertionEvent0(SpecializationNode source, String reason, Frame frame, SpecializationNode next) {
+        public InsertionEvent0(SpecializationNode source, String reason, Frame frame) {
             super(source, reason, frame);
-            this.next = next;
         }
 
         public SpecializationNode call() throws Exception {
+            SpecializationNode next = source.createNext(frame);
+            if (next == null) {
+                next = source.createFallback();
+            }
+            if (next == null) {
+                return null;
+            }
             SpecializationNode start = source.findStart();
             if (start.index == Integer.MAX_VALUE) {
                 return insertAt(start, next, this);
@@ -643,14 +633,18 @@
 
     private static final class InsertionEvent1 extends SlowPathEvent1 implements Callable<SpecializationNode> {
 
-        private final SpecializationNode next;
-
-        public InsertionEvent1(SpecializationNode source, String reason, Frame frame, Object o1, SpecializationNode next) {
+        public InsertionEvent1(SpecializationNode source, String reason, Frame frame, Object o1) {
             super(source, reason, frame, o1);
-            this.next = next;
         }
 
         public SpecializationNode call() throws Exception {
+            SpecializationNode next = source.createNext(frame, o1);
+            if (next == null) {
+                next = source.createFallback();
+            }
+            if (next == null) {
+                return null;
+            }
             SpecializationNode start = source.findStart();
             if (start.index == Integer.MAX_VALUE) {
                 return insertAt(start, next, this);
@@ -663,14 +657,18 @@
 
     private static final class InsertionEvent2 extends SlowPathEvent2 implements Callable<SpecializationNode> {
 
-        private final SpecializationNode next;
-
-        public InsertionEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, SpecializationNode next) {
+        public InsertionEvent2(SpecializationNode source, String reason, Frame frame, Object o1, Object o2) {
             super(source, reason, frame, o1, o2);
-            this.next = next;
         }
 
         public SpecializationNode call() throws Exception {
+            SpecializationNode next = source.createNext(frame, o1, o2);
+            if (next == null) {
+                next = source.createFallback();
+            }
+            if (next == null) {
+                return null;
+            }
             SpecializationNode start = source.findStart();
             if (start.index == Integer.MAX_VALUE) {
                 return insertAt(start, next, this);
@@ -683,14 +681,18 @@
 
     private static final class InsertionEvent3 extends SlowPathEvent3 implements Callable<SpecializationNode> {
 
-        private final SpecializationNode next;
-
-        public InsertionEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, SpecializationNode next) {
+        public InsertionEvent3(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3) {
             super(source, reason, frame, o1, o2, o3);
-            this.next = next;
         }
 
         public SpecializationNode call() throws Exception {
+            SpecializationNode next = source.createNext(frame, o1, o2, o3);
+            if (next == null) {
+                next = source.createFallback();
+            }
+            if (next == null) {
+                return null;
+            }
             SpecializationNode start = source.findStart();
             if (start.index == Integer.MAX_VALUE) {
                 return insertAt(start, next, this);
@@ -703,14 +705,18 @@
 
     private static final class InsertionEvent4 extends SlowPathEvent4 implements Callable<SpecializationNode> {
 
-        private final SpecializationNode next;
-
-        public InsertionEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, SpecializationNode next) {
+        public InsertionEvent4(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4) {
             super(source, reason, frame, o1, o2, o3, o4);
-            this.next = next;
         }
 
         public SpecializationNode call() throws Exception {
+            SpecializationNode next = source.createNext(frame, o1, o2, o3, o4);
+            if (next == null) {
+                next = source.createFallback();
+            }
+            if (next == null) {
+                return null;
+            }
             SpecializationNode start = source.findStart();
             if (start.index == Integer.MAX_VALUE) {
                 return insertAt(start, next, this);
@@ -723,14 +729,18 @@
 
     private static final class InsertionEvent5 extends SlowPathEvent5 implements Callable<SpecializationNode> {
 
-        private final SpecializationNode next;
-
-        public InsertionEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5, SpecializationNode next) {
+        public InsertionEvent5(SpecializationNode source, String reason, Frame frame, Object o1, Object o2, Object o3, Object o4, Object o5) {
             super(source, reason, frame, o1, o2, o3, o4, o5);
-            this.next = next;
         }
 
         public SpecializationNode call() throws Exception {
+            SpecializationNode next = source.createNext(frame, o1, o2, o3, o4, o5);
+            if (next == null) {
+                next = source.createFallback();
+            }
+            if (next == null) {
+                return null;
+            }
             SpecializationNode start = source.findStart();
             if (start.index == Integer.MAX_VALUE) {
                 return insertAt(start, next, this);
@@ -743,14 +753,18 @@
 
     private static final class InsertionEventN extends SlowPathEventN implements Callable<SpecializationNode> {
 
-        private final SpecializationNode next;
-
-        public InsertionEventN(SpecializationNode source, String reason, Frame frame, Object[] args, SpecializationNode next) {
+        public InsertionEventN(SpecializationNode source, String reason, Frame frame, Object[] args) {
             super(source, reason, frame, args);
-            this.next = next;
         }
 
         public SpecializationNode call() throws Exception {
+            SpecializationNode next = source.createNext(frame, args);
+            if (next == null) {
+                next = source.createFallback();
+            }
+            if (next == null) {
+                return null;
+            }
             SpecializationNode start = source.findStart();
             if (start.index == Integer.MAX_VALUE) {
                 return insertAt(start, next, this);
@@ -767,7 +781,7 @@
         }
 
         public SpecializationNode call() throws Exception {
-            return removeSameImpl(source, this);
+            return source.removeSame(this);
         }
 
     }
@@ -779,7 +793,7 @@
         }
 
         public SpecializationNode call() throws Exception {
-            return removeSameImpl(source, this);
+            return source.removeSame(this);
         }
 
     }
@@ -791,7 +805,7 @@
         }
 
         public SpecializationNode call() throws Exception {
-            return removeSameImpl(source, this);
+            return source.removeSame(this);
         }
 
     }
@@ -803,7 +817,7 @@
         }
 
         public SpecializationNode call() throws Exception {
-            return removeSameImpl(source, this);
+            return source.removeSame(this);
         }
 
     }
@@ -815,7 +829,7 @@
         }
 
         public SpecializationNode call() throws Exception {
-            return removeSameImpl(source, this);
+            return source.removeSame(this);
         }
 
     }
@@ -827,7 +841,7 @@
         }
 
         public SpecializationNode call() throws Exception {
-            return removeSameImpl(source, this);
+            return source.removeSame(this);
         }
 
     }
@@ -839,7 +853,7 @@
         }
 
         public SpecializationNode call() throws Exception {
-            return removeSameImpl(source, this);
+            return source.removeSame(this);
         }
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Wed Mar 11 20:43:52 2015 +0100
@@ -269,6 +269,7 @@
 
     final void replaceHelper(Node newNode, CharSequence reason) {
         CompilerAsserts.neverPartOfCompilation();
+        assert inAtomicBlock();
         if (this.getParent() == null) {
             throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent.");
         }
@@ -573,7 +574,12 @@
     public final void atomic(Runnable closure) {
         RootNode rootNode = getRootNode();
         synchronized (rootNode != null ? rootNode : GIL) {
-            closure.run();
+            assert enterAtomic();
+            try {
+                closure.run();
+            } finally {
+                assert exitAtomic();
+            }
         }
     }
 
@@ -581,7 +587,12 @@
         try {
             RootNode rootNode = getRootNode();
             synchronized (rootNode != null ? rootNode : GIL) {
-                return closure.call();
+                assert enterAtomic();
+                try {
+                    return closure.call();
+                } finally {
+                    assert exitAtomic();
+                }
             }
         } catch (RuntimeException | Error e) {
             throw e;
@@ -618,4 +629,28 @@
     }
 
     private static final Object GIL = new Object();
+
+    private static final ThreadLocal<Integer> IN_ATOMIC_BLOCK = new ThreadLocal<>();
+
+    private static boolean inAtomicBlock() {
+        Integer value = IN_ATOMIC_BLOCK.get();
+        if (value == null) {
+            return false;
+        }
+        return value > 0;
+    }
+
+    private static boolean enterAtomic() {
+        Integer currentValue = IN_ATOMIC_BLOCK.get();
+        if (currentValue == null) {
+            currentValue = 0;
+        }
+        IN_ATOMIC_BLOCK.set(currentValue + 1);
+        return true;
+    }
+
+    private static boolean exitAtomic() {
+        IN_ATOMIC_BLOCK.set(IN_ATOMIC_BLOCK.get() - 1);
+        return true;
+    }
 }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java	Wed Mar 11 20:43:12 2015 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java	Wed Mar 11 20:43:52 2015 +0100
@@ -517,9 +517,7 @@
             }
         };
 
-        builder.startIf().string("isSame(other)").end().startBlock();
         builder.tree(createGuardAndCast(group, typeSystem.getGenericTypeData(), currentLocals, executionFactory));
-        builder.end();
         builder.returnFalse();
         return method;
     }
--- a/mx/mx_graal.py	Wed Mar 11 20:43:12 2015 +0100
+++ b/mx/mx_graal.py	Wed Mar 11 20:43:52 2015 +0100
@@ -1498,6 +1498,10 @@
             vm(['-esa', '-XX:-TieredCompilation', '-version'])
 
     with VM('graal', 'fastdebug'):
+        with Task('BootstrapEconomyWithSystemAssertions:fastdebug', tasks):
+            vm(['-esa', '-XX:-TieredCompilation', '-G:CompilerConfiguration=economy', '-version'])
+
+    with VM('graal', 'fastdebug'):
         with Task('BootstrapWithSystemAssertionsNoCoop:fastdebug', tasks):
             vm(['-esa', '-XX:-TieredCompilation', '-XX:-UseCompressedOops', '-version'])
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Mar 11 20:43:52 2015 +0100
@@ -186,6 +186,7 @@
   /* Support for Graal */                                                                                                \
   do_klass(BitSet_klass,                                java_util_BitSet,                          Opt                 ) \
   /* Graal classes. These are loaded on-demand. */                                                                                 \
+  GRAAL_ONLY(do_klass(Debug_klass,                           com_oracle_graal_debug_Debug,                                 Graal)) \
   GRAAL_ONLY(do_klass(Node_klass,                            com_oracle_graal_graph_Node,                                  Graal)) \
   GRAAL_ONLY(do_klass(NodeClass_klass,                       com_oracle_graal_graph_NodeClass,                             Graal)) \
   GRAAL_ONLY(do_klass(HotSpotCompiledCode_klass,             com_oracle_graal_hotspot_HotSpotCompiledCode,                 Graal)) \
@@ -258,7 +259,7 @@
     WKID_LIMIT,
 
 #ifdef GRAAL
-    FIRST_GRAAL_WKID = WK_KLASS_ENUM_NAME(Node_klass),
+    FIRST_GRAAL_WKID = WK_KLASS_ENUM_NAME(Debug_klass),
     LAST_GRAAL_WKID  = WK_KLASS_ENUM_NAME(AbstractValue_klass),
 #endif
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Mar 11 20:43:52 2015 +0100
@@ -291,6 +291,7 @@
                                                                                                                                       \
   /* Support for Graal */                                                                                                             \
   template(java_util_BitSet,                                         "java/util/BitSet")                                              \
+  GRAAL_ONLY(template(com_oracle_graal_debug_Debug,                             "com/oracle/graal/debug/Debug"))                                  \
   GRAAL_ONLY(template(com_oracle_graal_graph_Node,                              "com/oracle/graal/graph/Node"))                                   \
   GRAAL_ONLY(template(com_oracle_graal_graph_NodeClass,                         "com/oracle/graal/graph/NodeClass"))                              \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotGraalRuntime,             "com/oracle/graal/hotspot/HotSpotGraalRuntime"))                  \
--- a/src/share/vm/graal/graalCompiler.cpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/graal/graalCompiler.cpp	Wed Mar 11 20:43:52 2015 +0100
@@ -85,12 +85,15 @@
   }
 
   int qsize;
-  jlong sleep_time = 1000;
+  bool first_round = true;
   int z = 0;
   do {
-    os::sleep(THREAD, sleep_time, true);
-    sleep_time = 100;
-    qsize = CompileBroker::queue_size(CompLevel_full_optimization);
+    // Loop until there is something in the queue.
+    do {
+      os::sleep(THREAD, 100, true);
+      qsize = CompileBroker::queue_size(CompLevel_full_optimization);
+    } while (first_round && qsize == 0);
+    first_round = false;
     if (PrintBootstrap) {
       while (z < (_methodsCompiled / 100)) {
         ++z;
--- a/src/share/vm/graal/graalEnv.cpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/graal/graalEnv.cpp	Wed Mar 11 20:43:52 2015 +0100
@@ -421,12 +421,13 @@
 // ------------------------------------------------------------------
 // Check for changes to the system dictionary during compilation
 // class loads, evolution, breakpoints
-bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code, GraalEnv* env, char** failure_detail) {
+GraalEnv::CodeInstallResult GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code,
+                                                                               GraalEnv* env, char** failure_detail) {
   // If JVMTI capabilities were enabled during compile, the compilation is invalidated.
   if (env != NULL) {
     if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) {
       *failure_detail = (char*) "Hotswapping or breakpointing was enabled during compilation";
-      return false;
+      return GraalEnv::dependencies_failed;
     }
   }
 
@@ -434,9 +435,9 @@
   // or if we don't know whether it has changed (i.e., env == NULL).
   // In debug mode, always check dependencies.
   bool counter_changed = env != NULL && env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications();
-  bool verify_deps = env == NULL || trueInDebug;
+  bool verify_deps = env == NULL || trueInDebug || Debug::ENABLED();
   if (!counter_changed && !verify_deps) {
-    return true;
+    return GraalEnv::ok;
   }
 
   for (Dependencies::DepStream deps(dependencies); deps.next(); ) {
@@ -448,14 +449,21 @@
       stringStream st(buffer, O_BUFLEN);
       deps.print_dependency(witness, true, &st);
       *failure_detail = st.as_string();
-      return false;
+      if (env == NULL || counter_changed) {
+        return GraalEnv::dependencies_failed;
+      } else {
+        // The dependencies were invalid at the time of installation
+        // without any intervening modification of the system
+        // dictionary.  That means they were invalidly constructed.
+        return GraalEnv::dependencies_invalid;
+      }
     }
     if (LogCompilation) {
       deps.log_dependency();
     }
   }
 
-  return true;
+  return GraalEnv::ok;
 }
 
 // ------------------------------------------------------------------
@@ -496,7 +504,8 @@
     dependencies->encode_content_bytes();
 
     // Check for {class loads, evolution, breakpoints} during compilation
-    if (!check_for_system_dictionary_modification(dependencies, compiled_code, env, &failure_detail)) {
+    result = check_for_system_dictionary_modification(dependencies, compiled_code, env, &failure_detail);
+    if (result != GraalEnv::ok) {
       // While not a true deoptimization, it is a preemptive decompile.
       MethodData* mdp = method()->method_data();
       if (mdp != NULL) {
@@ -513,7 +522,6 @@
       // If the code buffer is created on each compile attempt
       // as in C2, then it must be freed.
       //code_buffer->free_blob();
-      result = GraalEnv::dependencies_failed;
     } else {
       ImplicitExceptionTable implicit_tbl;
       nm =  nmethod::new_nmethod(method,
--- a/src/share/vm/graal/graalEnv.hpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/graal/graalEnv.hpp	Wed Mar 11 20:43:52 2015 +0100
@@ -61,6 +61,7 @@
   enum CodeInstallResult {
      ok,
      dependencies_failed,
+     dependencies_invalid,
      cache_full,
      code_too_large
   };
@@ -133,7 +134,8 @@
 
   // Helper routine for determining the validity of a compilation
   // with respect to concurrent class loading.
-  static bool check_for_system_dictionary_modification(Dependencies* target, Handle compiled_code, GraalEnv* env, char** failure_detail);
+  static GraalEnv::CodeInstallResult check_for_system_dictionary_modification(Dependencies* target, Handle compiled_code,
+                                                                              GraalEnv* env, char** failure_detail);
 
 public:
   CompileTask* task() { return _task; }
--- a/src/share/vm/graal/graalJavaAccess.cpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/graal/graalJavaAccess.cpp	Wed Mar 11 20:43:52 2015 +0100
@@ -63,10 +63,11 @@
 #define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false)
 #define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true)
 #define STATIC_INT_FIELD(klass, name) FIELD(klass, name, "I", true)
+#define STATIC_BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", true)
 
 
 void graal_compute_offsets() {
-  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD)
+  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
   guarantee(InstalledCode::_address_offset == sizeof(oopDesc), "codeBlob must be first field!");
 }
 
@@ -76,7 +77,7 @@
 #define FIELD2(klass, name) int klass::_##name##_offset = 0;
 #define FIELD3(klass, name, sig) FIELD2(klass, name)
 
-COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2)
+COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2)
 
 
 
--- a/src/share/vm/graal/graalJavaAccess.hpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Mar 11 20:43:52 2015 +0100
@@ -47,7 +47,7 @@
  *
  */
 
-#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_int_field) \
+#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_int_field, static_boolean_field) \
   start_class(HotSpotResolvedObjectTypeImpl)                                                                                                                       \
     oop_field(HotSpotResolvedObjectTypeImpl, javaClass, "Ljava/lang/Class;")                                                                                       \
   end_class                                                                                                                                                    \
@@ -260,6 +260,9 @@
     objArrayOop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;")                                                                               \
     typeArrayOop_field(HotSpotStackFrameReference, localIsVirtual, "[Z")                                                                                       \
   end_class                                                                                                                                                    \
+  start_class(Debug)                                                                                                                                           \
+    static_boolean_field(Debug, ENABLED)                                                                                                                       \
+  end_class                                                                                                                                                    \
   /* end*/
 
 #define START_CLASS(name)                                                                                                                                      \
@@ -294,39 +297,43 @@
 #define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field, EMPTY_CAST)
 #define OBJARRAYOOP_FIELD(klass, name, signature) FIELD(name, objArrayOop, obj_field, (objArrayOop))
 #define TYPEARRAYOOP_FIELD(klass, name, signature) FIELD(name, typeArrayOop, obj_field, (typeArrayOop))
-#define STATIC_OOP_FIELD(klassName, name, signature)                                                                                                           \
-    static int _##name##_offset;                                                                                                                               \
-    static oop name() {                                                                                                                                        \
-      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                                                                             \
-      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields());                                                 \
-      if (UseCompressedOops) {                                                                                                                                 \
-        return oopDesc::load_decode_heap_oop((narrowOop *)addr);                                                                                               \
-      } else {                                                                                                                                                 \
-        return oopDesc::load_decode_heap_oop((oop*)addr);                                                                                                      \
-      }                                                                                                                                                        \
-    }                                                                                                                                                          \
-    static void set_##name(oop x) {                                                                                                                            \
-      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                                                                             \
-      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields());                                                 \
-      if (UseCompressedOops) {                                                                                                                                 \
-        oop_store((narrowOop *)addr, x);                                                                                                                       \
-      } else {                                                                                                                                                 \
-        oop_store((oop*)addr, x);                                                                                                                              \
-      }                                                                                                                                                        \
+#define STATIC_OOP_FIELD(klassName, name, signature)                                                           \
+    static int _##name##_offset;                                                                               \
+    static oop name() {                                                                                        \
+      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                             \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      if (UseCompressedOops) {                                                                                 \
+        return oopDesc::load_decode_heap_oop((narrowOop *)addr);                                               \
+      } else {                                                                                                 \
+        return oopDesc::load_decode_heap_oop((oop*)addr);                                                      \
+      }                                                                                                        \
+    }                                                                                                          \
+    static void set_##name(oop x) {                                                                            \
+      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                             \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      if (UseCompressedOops) {                                                                                 \
+        oop_store((narrowOop *)addr, x);                                                                       \
+      } else {                                                                                                 \
+        oop_store((oop*)addr, x);                                                                              \
+      }                                                                                                        \
     }
-#define STATIC_INT_FIELD(klassName, name)                                                                                                                      \
-    static int _##name##_offset;                                                                                                                               \
-    static int name() {                                                                                                                                        \
-      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                                                                             \
-      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields());                                                 \
-      return *((jint *)addr);                                                                                                                                  \
-    }                                                                                                                                                          \
-    static void set_##name(int x) {                                                                                                                            \
-      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                                                                             \
-      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields());                                                 \
-      *((jint *)addr) = x;                                                                                                                                     \
+#define STATIC_PRIMITIVE_FIELD(klassName, name, typename, jtypename, boolCompare)                                           \
+    static int _##name##_offset;                                                                               \
+    static typename name() {                                                                                   \
+      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                             \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      return *((jtypename *)addr) boolCompare;                                                                             \
+    }                                                                                                          \
+    static void set_##name(typename x) {                                                                       \
+      InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                             \
+      address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
+      *((jtypename *)addr) = x;                                                                                \
     }
-COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD)
+
+#define STATIC_INT_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, int, jint,)
+#define STATIC_BOOLEAN_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, bool, jboolean, != 0)
+
+COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
 #undef START_CLASS
 #undef END_CLASS
 #undef FIELD
@@ -340,6 +347,7 @@
 #undef OBJARRAYOOP_FIELD
 #undef STATIC_OOP_FIELD
 #undef STATIC_INT_FIELD
+#undef STATIC_BOOLEAN_FIELD
 #undef EMPTY_CAST
 
 void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field);
--- a/src/share/vm/graal/vmStructs_graal.hpp	Wed Mar 11 20:43:12 2015 +0100
+++ b/src/share/vm/graal/vmStructs_graal.hpp	Wed Mar 11 20:43:52 2015 +0100
@@ -52,6 +52,7 @@
   declare_constant(Deoptimization::Reason_jsr_mismatch)                                           \
   declare_constant(GraalEnv::ok)                                                                  \
   declare_constant(GraalEnv::dependencies_failed)                                                 \
+  declare_constant(GraalEnv::dependencies_invalid)                                                \
   declare_constant(GraalEnv::cache_full)                                                          \
   declare_constant(GraalEnv::code_too_large)                                                      \
                                                                                                   \