changeset 22318:3ea10576bea7

Merge with basic-graal
author Doug Simon <doug.simon@oracle.com>
date Fri, 24 Jul 2015 08:33:42 +0200
parents 6154850c82d1 (current diff) e02fa353e88c (diff)
children 42f424266138
files mx.graal/mx_graal.py mx.graal/suite.py
diffstat 309 files changed, 8094 insertions(+), 552 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,8 +25,8 @@
 import java.lang.reflect.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.runtime.*;
 import jdk.internal.jvmci.service.*;
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 import jdk.internal.jvmci.amd64.*;
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*;
 import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64RMOp.*;
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64SuitesProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64SuitesProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.compiler.amd64;
 
-import com.oracle.graal.compiler.common.*;
+import static com.oracle.graal.compiler.common.BackendOptions.*;
+
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.amd64.phases.*;
@@ -37,7 +38,7 @@
     @Override
     public LIRSuites createLIRSuites() {
         LIRSuites lirSuites = super.createLIRSuites();
-        if (StackMoveOptimizationPhase.Options.LIROptStackMoveOptimizer.getValue() && GraalOptions.SSA_LIR.getValue()) {
+        if (StackMoveOptimizationPhase.Options.LIROptStackMoveOptimizer.getValue() && ShouldOptimizeStackToStackMoves.getValue()) {
             /* Note: this phase must be inserted <b>after</b> RedundantMoveElimination */
             lirSuites.getPostAllocationOptimizationStage().appendPhase(new StackMoveOptimizationPhase());
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/BackendOptions.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,79 @@
+/*
+ * 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.common;
+
+import static com.oracle.graal.compiler.common.BackendOptions.UserOptions.*;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+import jdk.internal.jvmci.options.*;
+import jdk.internal.jvmci.options.DerivedOptionValue.*;
+
+/**
+ * Options to control the backend configuration.
+ */
+public final class BackendOptions {
+
+    public static class UserOptions {
+        // @formatter:off
+        @Option(help = "Destruct SSA LIR eagerly (before other LIR phases).", type = OptionType.Debug)
+        public static final OptionValue<Boolean> LIREagerSSADestruction = new OptionValue<>(false);
+        // @formatter:on
+    }
+
+    /* Create SSA LIR during LIR generation. */
+    public static final DerivedOptionValue<Boolean> ConstructionSSAlirDuringLirBuilding = new DerivedOptionValue<>(new OptionSupplier<Boolean>() {
+        private static final long serialVersionUID = 7657622005438210681L;
+
+        public Boolean get() {
+            return SSA_LIR.getValue();
+        }
+    });
+
+    public enum LSRAVariant {
+        NONSSA_LSAR,
+        SSA_LSRA
+    }
+
+    public static final DerivedOptionValue<LSRAVariant> LinearScanVariant = new DerivedOptionValue<>(new OptionSupplier<LSRAVariant>() {
+        private static final long serialVersionUID = 364925071685235153L;
+
+        public LSRAVariant get() {
+            if (SSA_LIR.getValue() && !LIREagerSSADestruction.getValue()) {
+                return LSRAVariant.SSA_LSRA;
+            }
+            return LSRAVariant.NONSSA_LSAR;
+        }
+    });
+
+    /* Does the backend emit stack to stack moves?. */
+    public static final DerivedOptionValue<Boolean> ShouldOptimizeStackToStackMoves = new DerivedOptionValue<>(new OptionSupplier<Boolean>() {
+        private static final long serialVersionUID = 2366072840509944317L;
+
+        public Boolean get() {
+            switch (LinearScanVariant.getValue()) {
+                case SSA_LSRA:
+                    return true;
+            }
+            return false;
+        }
+    });
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallDescriptor.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2009, 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.common.spi;
+
+import java.util.*;
+
+/**
+ * The name and signature of a foreign call. A foreign call differs from a normal compiled Java call
+ * in at least one of these aspects:
+ * <ul>
+ * <li>The call is to C/C++/assembler code.</li>
+ * <li>The call uses different conventions for passing parameters or returning values.</li>
+ * <li>The callee has different register saving semantics. For example, the callee may save all
+ * registers (apart from some specified temporaries) in which case the register allocator doesn't
+ * not need to spill all live registers around the call site.</li>
+ * <li>The call does not occur at an INVOKE* bytecode. Such a call could be transformed into a
+ * standard Java call if the foreign routine is a normal Java method and the runtime supports
+ * linking Java calls at arbitrary bytecodes.</li>
+ * </ul>
+ */
+public class ForeignCallDescriptor {
+
+    private final String name;
+    private final Class<?> resultType;
+    private final Class<?>[] argumentTypes;
+
+    public ForeignCallDescriptor(String name, Class<?> resultType, Class<?>... argumentTypes) {
+        this.name = name;
+        this.resultType = resultType;
+        this.argumentTypes = argumentTypes;
+    }
+
+    /**
+     * Gets the name of this foreign call.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Gets the return type of this foreign call.
+     */
+    public Class<?> getResultType() {
+        return resultType;
+    }
+
+    /**
+     * Gets the argument types of this foreign call.
+     */
+    public Class<?>[] getArgumentTypes() {
+        return argumentTypes.clone();
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ForeignCallDescriptor) {
+            ForeignCallDescriptor other = (ForeignCallDescriptor) obj;
+            return other.name.equals(name) && other.resultType.equals(resultType) && Arrays.equals(other.argumentTypes, argumentTypes);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(name).append('(');
+        String sep = "";
+        for (Class<?> arg : argumentTypes) {
+            sb.append(sep).append(arg.getSimpleName());
+            sep = ",";
+        }
+        return sb.append(')').append(resultType.getSimpleName()).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallLinkage.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.common.spi;
+
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.meta.*;
+
+/**
+ * The runtime specific details of a {@linkplain ForeignCallDescriptor foreign} call.
+ */
+public interface ForeignCallLinkage extends InvokeTarget {
+
+    /**
+     * Gets the details of where parameters are passed and value(s) are returned from the caller's
+     * perspective.
+     */
+    CallingConvention getOutgoingCallingConvention();
+
+    /**
+     * Gets the details of where parameters are passed and value(s) are returned from the callee's
+     * perspective.
+     */
+    CallingConvention getIncomingCallingConvention();
+
+    /**
+     * Returns the maximum absolute offset of PC relative call to this stub from any position in the
+     * code cache or -1 when not applicable. Intended for determining the required size of
+     * address/offset fields.
+     */
+    long getMaxCallTargetOffset();
+
+    ForeignCallDescriptor getDescriptor();
+
+    /**
+     * Gets the values used/killed by this foreign call.
+     */
+    Value[] getTemporaries();
+
+    /**
+     * Determines if the foreign call target destroys all registers.
+     *
+     * @return {@code true} if the register allocator must save all live registers around a call to
+     *         this target
+     */
+    boolean destroysRegisters();
+
+    /**
+     * Determines if debug info needs to be associated with this call. Debug info is required if the
+     * function can raise an exception, try to lock, trigger GC or do anything else that requires
+     * the VM to be able to inspect the thread's execution state.
+     */
+    boolean needsDebugInfo();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/spi/ForeignCallsProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,54 @@
+/*
+ * 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.common.spi;
+
+import jdk.internal.jvmci.meta.*;
+
+/**
+ * Details about a set of supported {@link ForeignCallDescriptor foreign calls}.
+ */
+public interface ForeignCallsProvider {
+
+    /**
+     * Determines if a given foreign call is side-effect free. Deoptimization cannot return
+     * execution to a point before a foreign call that has a side effect.
+     */
+    boolean isReexecutable(ForeignCallDescriptor descriptor);
+
+    /**
+     * Gets the set of memory locations killed by a given foreign call. Returning the special value
+     * {@link LocationIdentity#any()} denotes that the call kills all memory locations. Returning
+     * any empty array denotes that the call does not kill any memory locations.
+     */
+    LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor);
+
+    /**
+     * Determines if deoptimization can occur during a given foreign call.
+     */
+    boolean canDeoptimize(ForeignCallDescriptor descriptor);
+
+    /**
+     * Gets the linkage for a foreign call.
+     */
+    ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor);
+}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static jdk.internal.jvmci.debug.DelegatingDebugConfig.Feature.*;
+import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -31,16 +31,16 @@
 import java.util.zip.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.code.Register.*;
-import jdk.internal.jvmci.compiler.*;
-import jdk.internal.jvmci.compiler.CompilerThreadFactory.*;
-import jdk.internal.jvmci.debug.*;
+import jdk.internal.jvmci.code.Register.RegisterCategory;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
 
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess;
 import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
@@ -125,7 +125,7 @@
         String[] filters = property == null ? null : property.split(",");
 
         CompilerThreadFactory factory = new CompilerThreadFactory("CheckInvariantsThread", new DebugConfigAccess() {
-            public JVMCIDebugConfig getDebugConfig() {
+            public GraalDebugConfig getDebugConfig() {
                 return DebugEnvironment.initialize(System.out);
             }
         });
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 import java.lang.reflect.*;
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.meta.Assumptions.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -65,7 +65,10 @@
 import jdk.internal.jvmci.code.CallingConvention.Type;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
+
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.compiler.test;
 
 import static com.oracle.graal.graph.iterators.NodePredicates.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ImplicitNullCheckTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ImplicitNullCheckTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,8 +29,8 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.options.*;
 import jdk.internal.jvmci.options.OptionValue.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MergeCanonicalizerTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/NestedLoopTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushThroughIfTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest2.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SchedulingTest2.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StaticInterfaceFieldTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StaticInterfaceFieldTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.compiler.test;
 
-import static jdk.internal.jvmci.debug.DelegatingDebugConfig.Feature.*;
+import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*;
 
 import java.lang.reflect.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,6 +26,8 @@
 
 import jdk.internal.jvmci.debug.*;
 
+import com.oracle.graal.debug.*;
+
 import org.junit.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,8 +25,8 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.CallingConvention.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import static jdk.internal.jvmci.code.CodeUtil.*;
 
 import com.oracle.graal.compiler.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.test.ea;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,8 +23,8 @@
 package com.oracle.graal.compiler.test.inlining;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,8 +27,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.CallingConvention.Type;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.Scope;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.runtime.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/StaticAnalysis.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,8 +25,8 @@
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 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.compiler;
+
+import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess;
+import com.oracle.graal.debug.*;
+
+/**
+ * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in the
+ * context of a thread-local {@linkplain GraalDebugConfig debug configuration}.
+ */
+public class CompilerThread extends Thread {
+
+    private final DebugConfigAccess debugConfigAccess;
+
+    public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) {
+        super(r);
+        this.setName(namePrefix + "-" + this.getId());
+        this.setPriority(Thread.MAX_PRIORITY);
+        this.setDaemon(true);
+        this.debugConfigAccess = debugConfigAccess;
+    }
+
+    @Override
+    public void run() {
+        GraalDebugConfig debugConfig = debugConfigAccess.getDebugConfig();
+        setContextClassLoader(getClass().getClassLoader());
+        try {
+            super.run();
+        } finally {
+            if (debugConfig != null) {
+                for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) {
+                    try {
+                        dumpHandler.close();
+                    } catch (Throwable t) {
+                    }
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler;
+
+import java.util.concurrent.*;
+
+import com.oracle.graal.debug.*;
+
+/**
+ * Facility for creating {@linkplain CompilerThread compiler threads}.
+ */
+public class CompilerThreadFactory implements ThreadFactory {
+
+    /**
+     * Capability to get a thread-local debug configuration for the current thread.
+     */
+    public interface DebugConfigAccess {
+        /**
+         * Get a thread-local debug configuration for the current thread. This will be null if
+         * debugging is disabled.
+         */
+        GraalDebugConfig getDebugConfig();
+    }
+
+    protected final String threadNamePrefix;
+    protected final DebugConfigAccess debugConfigAccess;
+
+    public CompilerThreadFactory(String threadNamePrefix, DebugConfigAccess debugConfigAccess) {
+        this.threadNamePrefix = threadNamePrefix;
+        this.debugConfigAccess = debugConfigAccess;
+    }
+
+    public Thread newThread(Runnable r) {
+        return new CompilerThread(r, threadNamePrefix, debugConfigAccess);
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,8 +31,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.CompilationResult.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 import jdk.internal.jvmci.options.OptionValue.*;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugInitializationPropertyProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugInitializationPropertyProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,28 +22,28 @@
  */
 package com.oracle.graal.compiler;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.service.*;
 
 /**
  * Sets system properties used in the initialization of {@link Debug} based on the values specified
- * for various {@link JVMCIDebugConfig} options.
+ * for various {@link GraalDebugConfig} options.
  */
 @ServiceProvider(DebugInitializationPropertyProvider.class)
 class GraalDebugInitializationPropertyProvider implements DebugInitializationPropertyProvider {
 
     @Override
     public void apply() {
-        if (JVMCIDebugConfig.areDebugScopePatternsEnabled()) {
+        if (GraalDebugConfig.areDebugScopePatternsEnabled()) {
             System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true");
         }
-        if ("".equals(JVMCIDebugConfig.Meter.getValue())) {
+        if ("".equals(GraalDebugConfig.Meter.getValue())) {
             System.setProperty(Debug.ENABLE_UNSCOPED_METRICS_PROPERTY_NAME, "true");
         }
-        if ("".equals(JVMCIDebugConfig.Time.getValue())) {
+        if ("".equals(GraalDebugConfig.Time.getValue())) {
             System.setProperty(Debug.ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME, "true");
         }
-        if ("".equals(JVMCIDebugConfig.TrackMemUse.getValue())) {
+        if ("".equals(GraalDebugConfig.TrackMemUse.getValue())) {
             System.setProperty(Debug.ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME, "true");
         }
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/LIRGenerationPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/LIRGenerationPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler;
 
-import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.compiler.common.BackendOptions.*;
 
 import java.util.*;
 
@@ -64,7 +64,7 @@
             emitBlock(nodeLirBuilder, lirGenRes, (Block) b, graph, schedule.getBlockToNodesMap());
         }
         context.lirGen.beforeRegisterAllocation();
-        assert !SSA_LIR.getValue() || SSAUtils.verifySSAForm(lirGenRes.getLIR());
+        assert !ConstructionSSAlirDuringLirBuilding.getValue() || SSAUtils.verifySSAForm(lirGenRes.getLIR());
     }
 
     private static void emitBlock(NodeLIRBuilderTool nodeLirGen, LIRGenerationResult lirGenRes, Block b, StructuredGraph graph, BlockMap<List<Node>> blockMap) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -35,7 +35,7 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 /**
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,10 +22,11 @@
  */
 package com.oracle.graal.compiler.gen;
 
+import static com.oracle.graal.compiler.common.BackendOptions.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.lir.LIR.*;
 import static jdk.internal.jvmci.code.ValueUtil.*;
-import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*;
+import static com.oracle.graal.debug.GraalDebugConfig.*;
 
 import java.util.*;
 import java.util.Map.Entry;
@@ -33,7 +34,10 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
+
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.calc.*;
@@ -264,7 +268,7 @@
                 emitPrologue(graph);
             } else {
                 assert block.getPredecessorCount() > 0;
-                if (SSA_LIR.getValue()) {
+                if (ConstructionSSAlirDuringLirBuilding.getValue()) {
                     // create phi-in value array
                     AbstractBeginNode begin = block.getBeginNode();
                     if (begin instanceof AbstractMergeNode) {
@@ -425,7 +429,7 @@
     public void visitEndNode(AbstractEndNode end) {
         AbstractMergeNode merge = end.merge();
         JumpOp jump = newJumpOp(getLIRBlock(merge));
-        if (SSA_LIR.getValue()) {
+        if (ConstructionSSAlirDuringLirBuilding.getValue()) {
             jump.setOutgoingValues(createPhiOut(merge, end));
         } else {
             moveToPhi(merge, end);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,12 +22,12 @@
  */
 package com.oracle.graal.compiler.match;
 
-import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*;
+import static com.oracle.graal.debug.GraalDebugConfig.*;
 
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.match.MatchPattern.Result;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchPattern.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.compiler.match;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,14 +22,14 @@
  */
 package com.oracle.graal.compiler.match;
 
-import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*;
+import static com.oracle.graal.debug.GraalDebugConfig.*;
 
 import java.util.*;
 import java.util.Map.Entry;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.service.*;
 
 import com.oracle.graal.compiler.gen.*;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.compiler.match;
 
-import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*;
+import static com.oracle.graal.debug.GraalDebugConfig.*;
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.gen.*;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/GraphChangeMonitoringPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/GraphChangeMonitoringPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,8 +25,8 @@
 import java.util.*;
 import java.util.stream.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import com.oracle.graal.graph.Graph.NodeEvent;
 import com.oracle.graal.graph.Graph.NodeEventScope;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.alloc.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2013, 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.debug.test;
+
+import java.io.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
+
+import org.junit.*;
+
+public class DebugHistogramTest {
+
+    @Test
+    public void testEmptyHistogram() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+        new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram);
+        String line = outputStream.toString().split("\r?\n")[0];
+        Assert.assertEquals("TestHistogram is empty.", line);
+
+        outputStream.reset();
+        new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram);
+        Assert.assertEquals("", outputStream.toString());
+    }
+
+    @Test
+    public void testSingleEntryHistogram() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        histogram.add(new Integer(1));
+        histogram.add(new Integer(1));
+        new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram);
+        String[] lines = outputStream.toString().split("\r?\n");
+        // @formatter:off
+        String[] expected = {
+            "TestHistogram has 1 unique elements and 2 total elements:",
+            "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+            "| 1                                                  | 2          | ==================================================================================================== |",
+            "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
+        };
+        // @formatter:on
+        Assert.assertArrayEquals(expected, lines);
+
+        outputStream.reset();
+        new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram);
+        lines = outputStream.toString().split("\r?\n");
+        // @formatter:off
+        expected = new String[] {
+            "TestHistogram <- c(2);",
+            "names(TestHistogram) <- c(\"1\");"
+        };
+        // @formatter:on
+        Assert.assertArrayEquals(expected, lines);
+    }
+
+    @Test
+    public void testMultipleEntryHistogram() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        histogram.add(new Integer(1));
+        histogram.add(new Integer(2));
+        histogram.add(new Integer(2));
+        new DebugHistogramAsciiPrinter(new PrintStream(outputStream)).print(histogram);
+        String[] lines = outputStream.toString().split("\r?\n");
+        // @formatter:off
+        String[] expected = new String[] {
+            "TestHistogram has 2 unique elements and 3 total elements:",
+            "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+            "| 2                                                  | 2          | ==================================================================================================== |",
+            "| 1                                                  | 1          | ==================================================                                                   |",
+            "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
+        };
+        // @formatter:on
+        Assert.assertArrayEquals(expected, lines);
+
+        outputStream.reset();
+        new DebugHistogramRPrinter(new PrintStream(outputStream)).print(histogram);
+        lines = outputStream.toString().split("\r?\n");
+        // @formatter:off
+        expected = new String[] {
+            "TestHistogram <- c(2, 1);",
+            "names(TestHistogram) <- c(\"2\", \"1\");"
+        };
+        // @formatter:on
+        Assert.assertArrayEquals(expected, lines);
+    }
+
+    @Test
+    public void testTooLongValueString() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        histogram.add("MyCustomValue");
+        new DebugHistogramAsciiPrinter(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10, 1).print(histogram);
+        String[] lines = outputStream.toString().split("\r?\n");
+        Assert.assertEquals(4, lines.length);
+        Assert.assertEquals("TestHistogram has 1 unique elements and 1 total elements:", lines[0]);
+        Assert.assertEquals("----------------------------------------", lines[1]);
+        Assert.assertEquals("| MyCusto... | 1          | ========== |", lines[2]);
+        Assert.assertEquals("----------------------------------------", lines[3]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugTimerTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2013, 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.debug.test;
+
+import static org.junit.Assert.*;
+
+import java.lang.management.*;
+
+import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
+import org.junit.*;
+
+public class DebugTimerTest {
+
+    private static final ThreadMXBean threadMXBean = Management.getThreadMXBean();
+
+    @Before
+    public void checkCapabilities() {
+        Assume.assumeTrue("skipping management interface test", threadMXBean.isCurrentThreadCpuTimeSupported());
+    }
+
+    /**
+     * Actively spins the current thread for at least a given number of milliseconds in such a way
+     * that timers for the current thread keep ticking over.
+     *
+     * @return the number of milliseconds actually spent spinning which is guaranteed to be >=
+     *         {@code ms}
+     */
+    private static long spin(long ms) {
+        long start = threadMXBean.getCurrentThreadCpuTime();
+        do {
+            long durationMS = (threadMXBean.getCurrentThreadCpuTime() - start) / 1000;
+            if (durationMS >= ms) {
+                return durationMS;
+            }
+        } while (true);
+    }
+
+    @Test
+    public void test1() {
+        DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out);
+        try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) {
+
+            DebugTimer timerA = Debug.timer("TimerA");
+            DebugTimer timerB = Debug.timer("TimerB");
+
+            long spinA;
+            long spinB;
+
+            try (DebugCloseable a1 = timerA.start()) {
+                spinA = spin(50);
+                try (DebugCloseable b1 = timerB.start()) {
+                    spinB = spin(50);
+                }
+            }
+
+            Assert.assertTrue(timerB.getCurrentValue() < timerA.getCurrentValue());
+            if (timerA.getFlat() != null && timerB.getFlat() != null) {
+                assertTrue(spinB >= spinA || timerB.getFlat().getCurrentValue() < timerA.getFlat().getCurrentValue());
+                assertEquals(timerA.getFlat().getCurrentValue(), timerA.getCurrentValue() - timerB.getFlat().getCurrentValue(), 10D);
+            }
+        }
+    }
+
+    @Test
+    public void test2() {
+        DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out);
+        try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) {
+            DebugTimer timerC = Debug.timer("TimerC");
+            try (DebugCloseable c1 = timerC.start()) {
+                spin(50);
+                try (DebugCloseable c2 = timerC.start()) {
+                    spin(50);
+                    try (DebugCloseable c3 = timerC.start()) {
+                        spin(50);
+                        try (DebugCloseable c4 = timerC.start()) {
+                            spin(50);
+                            try (DebugCloseable c5 = timerC.start()) {
+                                spin(50);
+                            }
+                        }
+                    }
+                }
+            }
+            if (timerC.getFlat() != null) {
+                assertEquals(timerC.getFlat().getCurrentValue(), timerC.getCurrentValue());
+            }
+        }
+    }
+
+    @Test
+    public void test3() {
+        DebugConfig debugConfig = Debug.fixedConfig(0, 0, false, false, true, false, null, null, System.out);
+        try (DebugConfigScope dcs = new DebugConfigScope(debugConfig); Debug.Scope s = Debug.scope("DebugTimerTest")) {
+
+            DebugTimer timerD = Debug.timer("TimerD");
+            DebugTimer timerE = Debug.timer("TimerE");
+
+            long spinD1;
+            long spinE;
+
+            try (DebugCloseable d1 = timerD.start()) {
+                spinD1 = spin(50);
+                try (DebugCloseable e1 = timerE.start()) {
+                    spinE = spin(50);
+                    try (DebugCloseable d2 = timerD.start()) {
+                        spin(50);
+                        try (DebugCloseable d3 = timerD.start()) {
+                            spin(50);
+                        }
+                    }
+                }
+            }
+
+            Assert.assertTrue(timerE.getCurrentValue() < timerD.getCurrentValue());
+            if (timerD.getFlat() != null && timerE.getFlat() != null) {
+                assertTrue(spinE >= spinD1 || timerE.getFlat().getCurrentValue() < timerD.getFlat().getCurrentValue());
+                assertEquals(timerD.getFlat().getCurrentValue(), timerD.getCurrentValue() - timerE.getFlat().getCurrentValue(), 10D);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/overview.html	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+This code is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+version 2 for more details (a copy is included in the LICENSE file that
+accompanied this code).
+
+You should have received a copy of the GNU General Public License version
+2 along with this work; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+or visit www.oracle.com if you need additional information or have any
+questions.
+-->
+
+</head>
+<body>
+
+Documentation for the <code>com.oracle.graal.debug</code> project.
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/AnsiColor.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, 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.debug;
+
+/**
+ * Ansi terminal color escape codes.
+ */
+public final class AnsiColor {
+    /** Foreground black. */
+    public static final String BLACK = "\u001b[30m";
+    /** Foreground red. */
+    public static final String RED = "\u001b[31m";
+    /** Foreground green. */
+    public static final String GREEN = "\u001b[32m";
+    /** Foreground yellow. */
+    public static final String YELLOW = "\u001b[33m";
+    /** Foreground blue. */
+    public static final String BLUE = "\u001b[34m";
+    /** Foreground magenta. */
+    public static final String MAGENTA = "\u001b[35m";
+    /** Foreground cyan. */
+    public static final String CYAN = "\u001b[36m";
+    /** Foreground white. */
+    public static final String WHITE = "\u001b[37m";
+
+    /** Foreground bold black. */
+    public static final String BOLD_BLACK = "\u001b[30;1m";
+    /** Foreground bold red. */
+    public static final String BOLD_RED = "\u001b[31;1m";
+    /** Foreground bold green. */
+    public static final String BOLD_GREEN = "\u001b[32;1m";
+    /** Foreground bold yellow. */
+    public static final String BOLD_YELLOW = "\u001b[33;1m";
+    /** Foreground bold blue. */
+    public static final String BOLD_BLUE = "\u001b[34;1m";
+    /** Foreground bold magenta. */
+    public static final String BOLD_MAGENTA = "\u001b[35;1m";
+    /** Foreground bold cyan. */
+    public static final String BOLD_CYAN = "\u001b[36;1m";
+    /** Foreground bold white. */
+    public static final String BOLD_WHITE = "\u001b[37;1m";
+
+    /** Background black. */
+    public static final String BG_BLACK = "\u001b[40m";
+    /** Background red. */
+    public static final String BG_RED = "\u001b[41m";
+    /** Background green. */
+    public static final String BG_GREEN = "\u001b[42m";
+    /** Background yellow. */
+    public static final String BG_YELLOW = "\u001b[43m";
+    /** Background blue. */
+    public static final String BG_BLUE = "\u001b[44m";
+    /** Background magenta. */
+    public static final String BG_MAGENTA = "\u001b[45m";
+    /** Background cyan. */
+    public static final String BG_CYAN = "\u001b[46m";
+    /** Background white. */
+    public static final String BG_WHITE = "\u001b[47m";
+
+    /** Reset. */
+    public static final String RESET = "\u001b[0m";
+    /** Underline. */
+    public static final String UNDERLINED = "\u001b[4m";
+
+    /** Prevent instantiation. */
+    private AnsiColor() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,1551 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import static java.util.FormattableFlags.*;
+import static com.oracle.graal.debug.Debug.Initialization.*;
+import static com.oracle.graal.debug.DelegatingDebugConfig.Feature.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.debug.DelegatingDebugConfig.*;
+import com.oracle.graal.debug.internal.*;
+import jdk.internal.jvmci.service.*;
+
+/**
+ * Scope based debugging facility. This facility is {@link #isEnabled()} if assertions are enabled
+ * for the {@link Debug} class or the {@value Initialization#INITIALIZER_PROPERTY_NAME} system
+ * property is {@code "true"} when {@link Debug} is initialized.
+ */
+public class Debug {
+
+    static {
+        for (DebugInitializationPropertyProvider p : Services.load(DebugInitializationPropertyProvider.class)) {
+            p.apply();
+        }
+    }
+
+    /**
+     * Class to assist with initialization of {@link Debug}.
+     */
+    public static class Initialization {
+
+        public static final String INITIALIZER_PROPERTY_NAME = "jvmci.debug.enable";
+
+        private static boolean initialized;
+
+        /**
+         * Determines if {@link Debug} has been initialized.
+         */
+        public static boolean isDebugInitialized() {
+            return initialized;
+        }
+
+    }
+
+    @SuppressWarnings("all")
+    private static boolean initialize() {
+        boolean assertionsEnabled = false;
+        assert assertionsEnabled = true;
+        Initialization.initialized = true;
+        return assertionsEnabled || Boolean.getBoolean(INITIALIZER_PROPERTY_NAME);
+    }
+
+    private static final boolean ENABLED = initialize();
+
+    public static boolean isEnabled() {
+        return ENABLED;
+    }
+
+    public static boolean isDumpEnabledForMethod() {
+        if (!ENABLED) {
+            return false;
+        }
+        DebugConfig config = DebugScope.getConfig();
+        if (config == null) {
+            return false;
+        }
+        return config.isDumpEnabledForMethod();
+    }
+
+    public static final int DEFAULT_LOG_LEVEL = 2;
+
+    public static boolean isDumpEnabled() {
+        return isDumpEnabled(DEFAULT_LOG_LEVEL);
+    }
+
+    public static boolean isDumpEnabled(int dumpLevel) {
+        return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel);
+    }
+
+    /**
+     * Determines if verification is enabled in the current method, regardless of the
+     * {@linkplain Debug#currentScope() current debug scope}.
+     *
+     * @see Debug#verify(Object, String)
+     */
+    public static boolean isVerifyEnabledForMethod() {
+        if (!ENABLED) {
+            return false;
+        }
+        DebugConfig config = DebugScope.getConfig();
+        if (config == null) {
+            return false;
+        }
+        return config.isVerifyEnabledForMethod();
+    }
+
+    /**
+     * Determines if verification is enabled in the {@linkplain Debug#currentScope() current debug
+     * scope}.
+     *
+     * @see Debug#verify(Object, String)
+     */
+    public static boolean isVerifyEnabled() {
+        return ENABLED && DebugScope.getInstance().isVerifyEnabled();
+    }
+
+    public static boolean isMeterEnabled() {
+        return ENABLED && DebugScope.getInstance().isMeterEnabled();
+    }
+
+    public static boolean isTimeEnabled() {
+        return ENABLED && DebugScope.getInstance().isTimeEnabled();
+    }
+
+    public static boolean isMemUseTrackingEnabled() {
+        return ENABLED && DebugScope.getInstance().isMemUseTrackingEnabled();
+    }
+
+    public static boolean isLogEnabledForMethod() {
+        if (!ENABLED) {
+            return false;
+        }
+        DebugConfig config = DebugScope.getConfig();
+        if (config == null) {
+            return false;
+        }
+        return config.isLogEnabledForMethod();
+    }
+
+    public static boolean isLogEnabled() {
+        return isLogEnabled(DEFAULT_LOG_LEVEL);
+    }
+
+    public static boolean isLogEnabled(int logLevel) {
+        return ENABLED && DebugScope.getInstance().isLogEnabled(logLevel);
+    }
+
+    @SuppressWarnings("unused")
+    public static Runnable decorateDebugRoot(Runnable runnable, String name, DebugConfig config) {
+        return runnable;
+    }
+
+    @SuppressWarnings("unused")
+    public static <T> Callable<T> decorateDebugRoot(Callable<T> callable, String name, DebugConfig config) {
+        return callable;
+    }
+
+    @SuppressWarnings("unused")
+    public static Runnable decorateScope(Runnable runnable, String name, Object... context) {
+        return runnable;
+    }
+
+    @SuppressWarnings("unused")
+    public static <T> Callable<T> decorateScope(Callable<T> callable, String name, Object... context) {
+        return callable;
+    }
+
+    /**
+     * Gets a string composed of the names in the current nesting of debug
+     * {@linkplain #scope(Object) scopes} separated by {@code '.'}.
+     */
+    public static String currentScope() {
+        if (ENABLED) {
+            return DebugScope.getInstance().getQualifiedName();
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * Represents a debug scope entered by {@link Debug#scope(Object)} or
+     * {@link Debug#sandbox(CharSequence, DebugConfig, Object...)}. Leaving the scope is achieved
+     * via {@link #close()}.
+     */
+    public interface Scope extends AutoCloseable {
+        void close();
+    }
+
+    /**
+     * Creates and enters a new debug scope which will be a child of the current debug scope.
+     * <p>
+     * It is recommended to use the try-with-resource statement for managing entering and leaving
+     * debug scopes. For example:
+     *
+     * <pre>
+     * try (Scope s = Debug.scope(&quot;InliningGraph&quot;, inlineeGraph)) {
+     *     ...
+     * } catch (Throwable e) {
+     *     throw Debug.handle(e);
+     * }
+     * </pre>
+     *
+     * The {@code name} argument is subject to the following type based conversion before having
+     * {@link Object#toString()} called on it:
+     *
+     * <pre>
+     *     Type          | Conversion
+     * ------------------+-----------------
+     *  java.lang.Class  | arg.getSimpleName()
+     *                   |
+     * </pre>
+     *
+     * @param name the name of the new scope
+     * @param contextObjects an array of object to be appended to the {@linkplain #context()
+     *            current} debug context
+     * @throws Throwable used to enforce a catch block.
+     * @return the scope entered by this method which will be exited when its {@link Scope#close()}
+     *         method is called
+     */
+    public static Scope scope(Object name, Object[] contextObjects) throws Throwable {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, contextObjects);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Similar to {@link #scope(Object, Object[])} but without context objects. Therefore the catch
+     * block can be omitted.
+     *
+     * @see #scope(Object, Object[])
+     */
+    public static Scope scope(Object name) {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @see #scope(Object, Object[])
+     * @param context an object to be appended to the {@linkplain #context() current} debug context
+     */
+    public static Scope scope(Object name, Object context) throws Throwable {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @see #scope(Object, Object[])
+     * @param context1 first object to be appended to the {@linkplain #context() current} debug
+     *            context
+     * @param context2 second object to be appended to the {@linkplain #context() current} debug
+     *            context
+     */
+    public static Scope scope(Object name, Object context1, Object context2) throws Throwable {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context1, context2);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @see #scope(Object, Object[])
+     * @param context1 first object to be appended to the {@linkplain #context() current} debug
+     *            context
+     * @param context2 second object to be appended to the {@linkplain #context() current} debug
+     *            context
+     * @param context3 third object to be appended to the {@linkplain #context() current} debug
+     *            context
+     */
+    public static Scope scope(Object name, Object context1, Object context2, Object context3) throws Throwable {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(convertFormatArg(name).toString(), null, context1, context2, context3);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Creates and enters a new debug scope which will be disjoint from the current debug scope.
+     * <p>
+     * It is recommended to use the try-with-resource statement for managing entering and leaving
+     * debug scopes. For example:
+     *
+     * <pre>
+     * try (Scope s = Debug.sandbox(&quot;CompilingStub&quot;, null, stubGraph)) {
+     *     ...
+     * } catch (Throwable e) {
+     *     throw Debug.handle(e);
+     * }
+     * </pre>
+     *
+     * @param name the name of the new scope
+     * @param config the debug configuration to use for the new scope
+     * @param context objects to be appended to the {@linkplain #context() current} debug context
+     * @return the scope entered by this method which will be exited when its {@link Scope#close()}
+     *         method is called
+     */
+    public static Scope sandbox(CharSequence name, DebugConfig config, Object... context) throws Throwable {
+        if (ENABLED) {
+            DebugConfig sandboxConfig = config == null ? silentConfig() : config;
+            return DebugScope.getInstance().scope(name, sandboxConfig, context);
+        } else {
+            return null;
+        }
+    }
+
+    public static Scope forceLog() throws Throwable {
+        ArrayList<Object> context = new ArrayList<>();
+        for (Object obj : context()) {
+            context.add(obj);
+        }
+        return Debug.sandbox("forceLog", new DelegatingDebugConfig().override(Level.LOG, Integer.MAX_VALUE).enable(LOG_METHOD), context.toArray());
+    }
+
+    /**
+     * Opens a scope in which exception {@linkplain DebugConfig#interceptException(Throwable)
+     * interception} is disabled. It is recommended to use the try-with-resource statement for
+     * managing entering and leaving such scopes:
+     *
+     * <pre>
+     * try (DebugConfigScope s = Debug.disableIntercept()) {
+     *     ...
+     * }
+     * </pre>
+     *
+     * This is particularly useful to suppress extraneous output in JUnit tests that are expected to
+     * throw an exception.
+     */
+    public static DebugConfigScope disableIntercept() {
+        return Debug.setConfig(new DelegatingDebugConfig().disable(INTERCEPT));
+    }
+
+    /**
+     * Handles an exception in the context of the debug scope just exited. The just exited scope
+     * must have the current scope as its parent which will be the case if the try-with-resource
+     * pattern recommended by {@link #scope(Object)} and
+     * {@link #sandbox(CharSequence, DebugConfig, Object...)} is used
+     *
+     * @see #scope(Object, Object[])
+     * @see #sandbox(CharSequence, DebugConfig, Object...)
+     */
+    public static RuntimeException handle(Throwable exception) {
+        if (ENABLED) {
+            return DebugScope.getInstance().handle(exception);
+        } else {
+            if (exception instanceof Error) {
+                throw (Error) exception;
+            }
+            if (exception instanceof RuntimeException) {
+                throw (RuntimeException) exception;
+            }
+            throw new RuntimeException(exception);
+        }
+    }
+
+    public static void log(String msg) {
+        log(DEFAULT_LOG_LEVEL, msg);
+    }
+
+    /**
+     * Prints a message to the current debug scope's logging stream if logging is enabled.
+     *
+     * @param msg the message to log
+     */
+    public static void log(int logLevel, String msg) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, msg);
+        }
+    }
+
+    public static void log(String format, Object arg) {
+        log(DEFAULT_LOG_LEVEL, format, arg);
+    }
+
+    /**
+     * Prints a message to the current debug scope's logging stream if logging is enabled.
+     *
+     * @param format a format string
+     * @param arg the argument referenced by the format specifiers in {@code format}
+     */
+    public static void log(int logLevel, String format, Object arg) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg);
+        }
+    }
+
+    public static void log(String format, int arg) {
+        log(DEFAULT_LOG_LEVEL, format, arg);
+    }
+
+    /**
+     * Prints a message to the current debug scope's logging stream if logging is enabled.
+     *
+     * @param format a format string
+     * @param arg the argument referenced by the format specifiers in {@code format}
+     */
+    public static void log(int logLevel, String format, int arg) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg);
+        }
+    }
+
+    public static void log(String format, Object arg1, Object arg2) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, Object arg1, Object arg2) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2);
+        }
+    }
+
+    public static void log(String format, int arg1, Object arg2) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, int arg1, Object arg2) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2);
+        }
+    }
+
+    public static void log(String format, Object arg1, int arg2) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, Object arg1, int arg2) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2);
+        }
+    }
+
+    public static void log(String format, int arg1, int arg2) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, int arg1, int arg2) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2);
+        }
+    }
+
+    public static void log(String format, Object arg1, Object arg2, Object arg3) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3);
+        }
+    }
+
+    public static void log(String format, int arg1, int arg2, int arg3) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, int arg1, int arg2, int arg3) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3);
+        }
+    }
+
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4);
+        }
+    }
+
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5);
+        }
+    }
+
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6);
+        }
+    }
+
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+    }
+
+    public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) {
+        log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+    }
+
+    /**
+     * @see #log(int, String, Object)
+     */
+    public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+        }
+    }
+
+    public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8) {
+        if (ENABLED) {
+            DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+        }
+    }
+
+    public static void logv(String format, Object... args) {
+        logv(DEFAULT_LOG_LEVEL, format, args);
+    }
+
+    /**
+     * Prints a message to the current debug scope's logging stream. This method must only be called
+     * if debugging is {@linkplain Debug#isEnabled() enabled} as it incurs allocation at the call
+     * site. If possible, call one of the other {@code log()} methods in this class that take a
+     * fixed number of parameters.
+     *
+     * @param format a format string
+     * @param args the arguments referenced by the format specifiers in {@code format}
+     */
+    public static void logv(int logLevel, String format, Object... args) {
+        if (!ENABLED) {
+            throw new InternalError("Use of Debug.logv() must be guarded by a test of Debug.isEnabled()");
+        }
+        DebugScope.getInstance().log(logLevel, format, args);
+    }
+
+    /**
+     * This override exists to catch cases when {@link #log(String, Object)} is called with one
+     * argument bound to a varargs method parameter. It will bind to this method instead of the
+     * single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void log(String format, Object[] args) {
+        assert false : "shouldn't use this";
+        log(DEFAULT_LOG_LEVEL, format, args);
+    }
+
+    /**
+     * This override exists to catch cases when {@link #log(int, String, Object)} is called with one
+     * argument bound to a varargs method parameter. It will bind to this method instead of the
+     * single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void log(int logLevel, String format, Object[] args) {
+        assert false : "shouldn't use this";
+        logv(logLevel, format, args);
+    }
+
+    public static void dump(Object object, String msg) {
+        dump(DEFAULT_LOG_LEVEL, object, msg);
+    }
+
+    public static void dump(int dumpLevel, Object object, String msg) {
+        if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) {
+            DebugScope.getInstance().dump(dumpLevel, object, msg);
+        }
+    }
+
+    public static void dump(Object object, String format, Object arg) {
+        dump(DEFAULT_LOG_LEVEL, object, format, arg);
+    }
+
+    public static void dump(int dumpLevel, Object object, String format, Object arg) {
+        if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) {
+            DebugScope.getInstance().dump(dumpLevel, object, format, arg);
+        }
+    }
+
+    public static void dump(Object object, String format, Object arg1, Object arg2) {
+        dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2);
+    }
+
+    public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2) {
+        if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) {
+            DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2);
+        }
+    }
+
+    public static void dump(Object object, String format, Object arg1, Object arg2, Object arg3) {
+        dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2, arg3);
+    }
+
+    public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2, Object arg3) {
+        if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) {
+            DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2, arg3);
+        }
+    }
+
+    /**
+     * This override exists to catch cases when {@link #dump(Object, String, Object)} is called with
+     * one argument bound to a varargs method parameter. It will bind to this method instead of the
+     * single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void dump(Object object, String format, Object[] args) {
+        assert false : "shouldn't use this";
+        dump(DEFAULT_LOG_LEVEL, object, format, args);
+    }
+
+    /**
+     * This override exists to catch cases when {@link #dump(int, Object, String, Object)} is called
+     * with one argument bound to a varargs method parameter. It will bind to this method instead of
+     * the single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void dump(int dumpLevel, Object object, String format, Object[] args) {
+        assert false : "shouldn't use this";
+        if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) {
+            DebugScope.getInstance().dump(dumpLevel, object, format, args);
+        }
+    }
+
+    /**
+     * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig()
+     * config} to perform verification on a given object.
+     *
+     * @param object object to verify
+     * @param message description of verification context
+     *
+     * @see DebugVerifyHandler#verify(Object, String)
+     */
+    public static void verify(Object object, String message) {
+        if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
+            DebugScope.getInstance().verify(object, message);
+        }
+    }
+
+    /**
+     * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig()
+     * config} to perform verification on a given object.
+     *
+     * @param object object to verify
+     * @param format a format string for the description of the verification context
+     * @param arg the argument referenced by the format specifiers in {@code format}
+     *
+     * @see DebugVerifyHandler#verify(Object, String)
+     */
+    public static void verify(Object object, String format, Object arg) {
+        if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
+            DebugScope.getInstance().verify(object, format, arg);
+        }
+    }
+
+    /**
+     * This override exists to catch cases when {@link #verify(Object, String, Object)} is called
+     * with one argument bound to a varargs method parameter. It will bind to this method instead of
+     * the single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void verify(Object object, String format, Object[] args) {
+        assert false : "shouldn't use this";
+        if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) {
+            DebugScope.getInstance().verify(object, format, args);
+        }
+    }
+
+    /**
+     * Opens a new indentation level (by adding some spaces) based on the current indentation level.
+     * This should be used in a {@linkplain Indent try-with-resources} pattern.
+     *
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     * @see #logAndIndent(int, String)
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent indent() {
+        if (ENABLED) {
+            DebugScope scope = DebugScope.getInstance();
+            return scope.pushIndentLogger();
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String msg) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, msg);
+    }
+
+    /**
+     * A convenience function which combines {@link #log(String)} and {@link #indent()}.
+     *
+     * @param msg the message to log
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     */
+    public static Indent logAndIndent(int logLevel, String msg) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, msg);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg);
+    }
+
+    /**
+     * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}.
+     *
+     * @param format a format string
+     * @param arg the argument referenced by the format specifiers in {@code format}
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, int arg) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg);
+    }
+
+    /**
+     * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}.
+     *
+     * @param format a format string
+     * @param arg the argument referenced by the format specifiers in {@code format}
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     */
+    public static Indent logAndIndent(int logLevel, String format, int arg) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, int arg1, Object arg2) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, int arg1, Object arg2) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg1, int arg2) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, int arg1, int arg2) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg1, Object arg2) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, int arg1, int arg2, int arg3) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, int arg1, int arg2, int arg3) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg1, int arg2, int arg3) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg1, int arg2, int arg3) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4, arg5);
+        }
+        return null;
+    }
+
+    public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) {
+        return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6);
+    }
+
+    /**
+     * @see #logAndIndent(int, String, Object)
+     */
+    public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) {
+        if (ENABLED && Debug.isLogEnabled(logLevel)) {
+            return logvAndIndentInternal(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6);
+        }
+        return null;
+    }
+
+    /**
+     * A convenience function which combines {@link #logv(int, String, Object...)} and
+     * {@link #indent()}.
+     *
+     * @param format a format string
+     * @param args the arguments referenced by the format specifiers in {@code format}
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     */
+    public static Indent logvAndIndent(int logLevel, String format, Object... args) {
+        if (ENABLED) {
+            if (Debug.isLogEnabled(logLevel)) {
+                return logvAndIndentInternal(logLevel, format, args);
+            }
+            return null;
+        }
+        throw new InternalError("Use of Debug.logvAndIndent() must be guarded by a test of Debug.isEnabled()");
+    }
+
+    private static Indent logvAndIndentInternal(int logLevel, String format, Object... args) {
+        assert ENABLED && Debug.isLogEnabled(logLevel) : "must have checked Debug.isLogEnabled()";
+        DebugScope scope = DebugScope.getInstance();
+        scope.log(logLevel, format, args);
+        return scope.pushIndentLogger();
+    }
+
+    /**
+     * This override exists to catch cases when {@link #logAndIndent(String, Object)} is called with
+     * one argument bound to a varargs method parameter. It will bind to this method instead of the
+     * single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void logAndIndent(String format, Object[] args) {
+        assert false : "shouldn't use this";
+        logAndIndent(DEFAULT_LOG_LEVEL, format, args);
+    }
+
+    /**
+     * This override exists to catch cases when {@link #logAndIndent(int, String, Object)} is called
+     * with one argument bound to a varargs method parameter. It will bind to this method instead of
+     * the single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void logAndIndent(int logLevel, String format, Object[] args) {
+        assert false : "shouldn't use this";
+        logvAndIndent(logLevel, format, args);
+    }
+
+    public static Iterable<Object> context() {
+        if (ENABLED) {
+            return DebugScope.getInstance().getCurrentContext();
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> contextSnapshot(Class<T> clazz) {
+        if (ENABLED) {
+            List<T> result = new ArrayList<>();
+            for (Object o : context()) {
+                if (clazz.isInstance(o)) {
+                    result.add((T) o);
+                }
+            }
+            return result;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * Searches the current debug scope, bottom up, for a context object that is an instance of a
+     * given type. The first such object found is returned.
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T contextLookup(Class<T> clazz) {
+        if (ENABLED) {
+            for (Object o : context()) {
+                if (clazz.isInstance(o)) {
+                    return ((T) o);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates a {@linkplain DebugMemUseTracker memory use tracker} that is enabled iff debugging is
+     * {@linkplain #isEnabled() enabled}.
+     * <p>
+     * A disabled tracker has virtually no overhead.
+     */
+    public static DebugMemUseTracker memUseTracker(CharSequence name) {
+        if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) {
+            return VOID_MEM_USE_TRACKER;
+        }
+        return createMemUseTracker("%s", name, null);
+    }
+
+    /**
+     * Creates a debug memory use tracker. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.memUseTracker(format, arg, null)
+     * </pre>
+     *
+     * except that the string formatting only happens if metering is enabled.
+     *
+     * @see #metric(String, Object, Object)
+     */
+    public static DebugMemUseTracker memUseTracker(String format, Object arg) {
+        if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) {
+            return VOID_MEM_USE_TRACKER;
+        }
+        return createMemUseTracker(format, arg, null);
+    }
+
+    /**
+     * Creates a debug memory use tracker. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.memUseTracker(String.format(format, arg1, arg2))
+     * </pre>
+     *
+     * except that the string formatting only happens if memory use tracking is enabled. In
+     * addition, each argument is subject to the following type based conversion before being passed
+     * as an argument to {@link String#format(String, Object...)}:
+     *
+     * <pre>
+     *     Type          | Conversion
+     * ------------------+-----------------
+     *  java.lang.Class  | arg.getSimpleName()
+     *                   |
+     * </pre>
+     *
+     * @see #memUseTracker(CharSequence)
+     */
+    public static DebugMemUseTracker memUseTracker(String format, Object arg1, Object arg2) {
+        if (!isUnconditionalMemUseTrackingEnabled && !ENABLED) {
+            return VOID_MEM_USE_TRACKER;
+        }
+        return createMemUseTracker(format, arg1, arg2);
+    }
+
+    private static DebugMemUseTracker createMemUseTracker(String format, Object arg1, Object arg2) {
+        String name = formatDebugName(format, arg1, arg2);
+        return new MemUseTrackerImpl(name, !isUnconditionalMemUseTrackingEnabled);
+    }
+
+    /**
+     * Creates a {@linkplain DebugMetric metric} that is enabled iff debugging is
+     * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to
+     * {@value #ENABLE_METRIC_PROPERTY_NAME_PREFIX} to {@code name} is
+     * {@linkplain Boolean#getBoolean(String) true}. If the latter condition is true, then the
+     * returned metric is {@linkplain DebugMetric#isConditional() unconditional} otherwise it is
+     * conditional.
+     * <p>
+     * A disabled metric has virtually no overhead.
+     */
+    public static DebugMetric metric(CharSequence name) {
+        if (!areUnconditionalMetricsEnabled() && !ENABLED) {
+            return VOID_METRIC;
+        }
+        return createMetric("%s", name, null);
+    }
+
+    public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
+        if (flags == 0 && width < 0) {
+            return s;
+        }
+        StringBuilder sb = new StringBuilder(s);
+
+        // apply width and justification
+        int len = sb.length();
+        if (len < width) {
+            for (int i = 0; i < width - len; i++) {
+                if ((flags & LEFT_JUSTIFY) == LEFT_JUSTIFY) {
+                    sb.append(' ');
+                } else {
+                    sb.insert(0, ' ');
+                }
+            }
+        }
+
+        String res = sb.toString();
+        if ((flags & UPPERCASE) == UPPERCASE) {
+            res = res.toUpperCase();
+        }
+        return res;
+    }
+
+    /**
+     * Creates a debug metric. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.metric(format, arg, null)
+     * </pre>
+     *
+     * except that the string formatting only happens if metering is enabled.
+     *
+     * @see #metric(String, Object, Object)
+     */
+    public static DebugMetric metric(String format, Object arg) {
+        if (!areUnconditionalMetricsEnabled() && !ENABLED) {
+            return VOID_METRIC;
+        }
+        return createMetric(format, arg, null);
+    }
+
+    /**
+     * Creates a debug metric. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.metric(String.format(format, arg1, arg2))
+     * </pre>
+     *
+     * except that the string formatting only happens if metering is enabled. In addition, each
+     * argument is subject to the following type based conversion before being passed as an argument
+     * to {@link String#format(String, Object...)}:
+     *
+     * <pre>
+     *     Type          | Conversion
+     * ------------------+-----------------
+     *  java.lang.Class  | arg.getSimpleName()
+     *                   |
+     * </pre>
+     *
+     * @see #metric(CharSequence)
+     */
+    public static DebugMetric metric(String format, Object arg1, Object arg2) {
+        if (!areUnconditionalMetricsEnabled() && !ENABLED) {
+            return VOID_METRIC;
+        }
+        return createMetric(format, arg1, arg2);
+    }
+
+    private static DebugMetric createMetric(String format, Object arg1, Object arg2) {
+        String name = formatDebugName(format, arg1, arg2);
+        boolean conditional = enabledMetrics == null || !findMatch(enabledMetrics, enabledMetricsSubstrings, name);
+        if (!ENABLED && conditional) {
+            return VOID_METRIC;
+        }
+        return new MetricImpl(name, conditional);
+    }
+
+    /**
+     * Changes the debug configuration for the current thread.
+     *
+     * @param config new configuration to use for the current thread
+     * @return an object that when {@linkplain DebugConfigScope#close() closed} will restore the
+     *         debug configuration for the current thread to what it was before this method was
+     *         called
+     */
+    public static DebugConfigScope setConfig(DebugConfig config) {
+        if (ENABLED) {
+            return new DebugConfigScope(config);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Creates an object for counting value frequencies.
+     */
+    public static DebugHistogram createHistogram(String name) {
+        return new DebugHistogramImpl(name);
+    }
+
+    public static DebugConfig silentConfig() {
+        return fixedConfig(0, 0, false, false, false, false, Collections.<DebugDumpHandler> emptyList(), Collections.<DebugVerifyHandler> emptyList(), null);
+    }
+
+    public static DebugConfig fixedConfig(final int logLevel, final int dumpLevel, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled,
+                    final boolean isVerifyEnabled, final Collection<DebugDumpHandler> dumpHandlers, final Collection<DebugVerifyHandler> verifyHandlers, final PrintStream output) {
+        return new DebugConfig() {
+
+            @Override
+            public int getLogLevel() {
+                return logLevel;
+            }
+
+            public boolean isLogEnabledForMethod() {
+                return logLevel > 0;
+            }
+
+            @Override
+            public boolean isMeterEnabled() {
+                return isMeterEnabled;
+            }
+
+            @Override
+            public boolean isMemUseTrackingEnabled() {
+                return isMemUseTrackingEnabled;
+            }
+
+            @Override
+            public int getDumpLevel() {
+                return dumpLevel;
+            }
+
+            public boolean isDumpEnabledForMethod() {
+                return dumpLevel > 0;
+            }
+
+            @Override
+            public boolean isVerifyEnabled() {
+                return isVerifyEnabled;
+            }
+
+            public boolean isVerifyEnabledForMethod() {
+                return isVerifyEnabled;
+            }
+
+            @Override
+            public boolean isTimeEnabled() {
+                return isTimerEnabled;
+            }
+
+            @Override
+            public RuntimeException interceptException(Throwable e) {
+                return null;
+            }
+
+            @Override
+            public Collection<DebugDumpHandler> dumpHandlers() {
+                return dumpHandlers;
+            }
+
+            @Override
+            public Collection<DebugVerifyHandler> verifyHandlers() {
+                return verifyHandlers;
+            }
+
+            @Override
+            public PrintStream output() {
+                return output;
+            }
+
+            @Override
+            public void addToContext(Object o) {
+            }
+
+            @Override
+            public void removeFromContext(Object o) {
+            }
+        };
+    }
+
+    private static final DebugMetric VOID_METRIC = new DebugMetric() {
+
+        public void increment() {
+        }
+
+        public void add(long value) {
+        }
+
+        public void setConditional(boolean flag) {
+            throw new InternalError("Cannot make void metric conditional");
+        }
+
+        public boolean isConditional() {
+            return false;
+        }
+
+        public long getCurrentValue() {
+            return 0L;
+        }
+    };
+
+    private static final DebugMemUseTracker VOID_MEM_USE_TRACKER = new DebugMemUseTracker() {
+
+        public DebugCloseable start() {
+            return DebugCloseable.VOID_CLOSEABLE;
+        }
+
+        public long getCurrentValue() {
+            return 0;
+        }
+    };
+
+    public static final String ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME = "jvmci.debug.unscopedTimers";
+    public static final String ENABLE_UNSCOPED_METRICS_PROPERTY_NAME = "jvmci.debug.unscopedMetrics";
+    public static final String ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME = "jvmci.debug.unscopedMemUseTrackers";
+
+    /**
+     * @see #timer(CharSequence)
+     */
+    public static final String ENABLE_TIMER_PROPERTY_NAME_PREFIX = "jvmci.debug.timer.";
+
+    /**
+     * @see #metric(CharSequence)
+     */
+    public static final String ENABLE_METRIC_PROPERTY_NAME_PREFIX = "jvmci.debug.metric.";
+
+    /**
+     * Set of unconditionally enabled metrics. Possible values and their meanings:
+     * <ul>
+     * <li>{@code null}: no unconditionally enabled metrics</li>
+     * <li>{@code isEmpty()}: all metrics are unconditionally enabled</li>
+     * <li>{@code !isEmpty()}: use {@link #findMatch(Set, Set, String)} on this set and
+     * {@link #enabledMetricsSubstrings} to determine which metrics are unconditionally enabled</li>
+     * </ul>
+     */
+    private static final Set<String> enabledMetrics;
+
+    /**
+     * Set of unconditionally enabled timers. Same interpretation of values as for
+     * {@link #enabledMetrics}.
+     */
+    private static final Set<String> enabledTimers;
+
+    private static final Set<String> enabledMetricsSubstrings = new HashSet<>();
+    private static final Set<String> enabledTimersSubstrings = new HashSet<>();
+
+    /**
+     * Specifies if all mem use trackers are unconditionally enabled.
+     */
+    private static final boolean isUnconditionalMemUseTrackingEnabled;
+
+    static {
+        Set<String> metrics = new HashSet<>();
+        Set<String> timers = new HashSet<>();
+        parseMetricAndTimerSystemProperties(metrics, timers, enabledMetricsSubstrings, enabledTimersSubstrings);
+        metrics = metrics.isEmpty() && enabledMetricsSubstrings.isEmpty() ? null : metrics;
+        timers = timers.isEmpty() && enabledTimersSubstrings.isEmpty() ? null : timers;
+        if (metrics == null && Boolean.getBoolean(ENABLE_UNSCOPED_METRICS_PROPERTY_NAME)) {
+            metrics = Collections.emptySet();
+        }
+        if (timers == null && Boolean.getBoolean(ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME)) {
+            timers = Collections.emptySet();
+        }
+        enabledMetrics = metrics;
+        enabledTimers = timers;
+        isUnconditionalMemUseTrackingEnabled = Boolean.getBoolean(ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME);
+    }
+
+    private static boolean findMatch(Set<String> haystack, Set<String> haystackSubstrings, String needle) {
+        if (haystack.isEmpty()) {
+            // Empty haystack means match all
+            return true;
+        }
+        if (haystack.contains(needle)) {
+            return true;
+        }
+        if (!haystackSubstrings.isEmpty()) {
+            for (String h : haystackSubstrings) {
+                if (needle.startsWith(h)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean areUnconditionalTimersEnabled() {
+        return enabledTimers != null;
+    }
+
+    public static boolean areUnconditionalMetricsEnabled() {
+        return enabledMetrics != null;
+    }
+
+    protected static void parseMetricAndTimerSystemProperties(Set<String> metrics, Set<String> timers, Set<String> metricsSubstrings, Set<String> timersSubstrings) {
+        do {
+            try {
+                for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) {
+                    String name = e.getKey().toString();
+                    if (name.startsWith(ENABLE_METRIC_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) {
+                        if (name.endsWith("*")) {
+                            metricsSubstrings.add(name.substring(ENABLE_METRIC_PROPERTY_NAME_PREFIX.length(), name.length() - 1));
+                        } else {
+                            metrics.add(name.substring(ENABLE_METRIC_PROPERTY_NAME_PREFIX.length()));
+                        }
+                    }
+                    if (name.startsWith(ENABLE_TIMER_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) {
+                        if (name.endsWith("*")) {
+                            timersSubstrings.add(name.substring(ENABLE_TIMER_PROPERTY_NAME_PREFIX.length(), name.length() - 1));
+                        } else {
+                            timers.add(name.substring(ENABLE_TIMER_PROPERTY_NAME_PREFIX.length()));
+                        }
+                    }
+                }
+                return;
+            } catch (ConcurrentModificationException e) {
+                // Iterating over the system properties may race with another thread that is
+                // updating the system properties. Simply try again in this case.
+            }
+        } while (true);
+    }
+
+    /**
+     * Creates a {@linkplain DebugTimer timer} that is enabled iff debugging is
+     * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to
+     * {@value #ENABLE_TIMER_PROPERTY_NAME_PREFIX} to {@code name} is
+     * {@linkplain Boolean#getBoolean(String) true}. If the latter condition is true, then the
+     * returned timer is {@linkplain DebugMetric#isConditional() unconditional} otherwise it is
+     * conditional.
+     * <p>
+     * A disabled timer has virtually no overhead.
+     */
+    public static DebugTimer timer(CharSequence name) {
+        if (!areUnconditionalTimersEnabled() && !ENABLED) {
+            return VOID_TIMER;
+        }
+        return createTimer("%s", name, null);
+    }
+
+    /**
+     * Creates a debug timer. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.timer(format, arg, null)
+     * </pre>
+     *
+     * except that the string formatting only happens if timing is enabled.
+     *
+     * @see #timer(String, Object, Object)
+     */
+    public static DebugTimer timer(String format, Object arg) {
+        if (!areUnconditionalTimersEnabled() && !ENABLED) {
+            return VOID_TIMER;
+        }
+        return createTimer(format, arg, null);
+    }
+
+    /**
+     * Creates a debug timer. Invoking this method is equivalent to:
+     *
+     * <pre>
+     * Debug.timer(String.format(format, arg1, arg2))
+     * </pre>
+     *
+     * except that the string formatting only happens if timing is enabled. In addition, each
+     * argument is subject to the following type based conversion before being passed as an argument
+     * to {@link String#format(String, Object...)}:
+     *
+     * <pre>
+     *     Type          | Conversion
+     * ------------------+-----------------
+     *  java.lang.Class  | arg.getSimpleName()
+     *                   |
+     * </pre>
+     *
+     * @see #timer(CharSequence)
+     */
+    public static DebugTimer timer(String format, Object arg1, Object arg2) {
+        if (!areUnconditionalTimersEnabled() && !ENABLED) {
+            return VOID_TIMER;
+        }
+        return createTimer(format, arg1, arg2);
+    }
+
+    /**
+     * There are paths where construction of formatted class names are common and the code below is
+     * surprisingly expensive, so compute it once and cache it.
+     */
+    private static final ClassValue<String> formattedClassName = new ClassValue<String>() {
+        @Override
+        protected String computeValue(Class<?> c) {
+            final String simpleName = c.getSimpleName();
+            Class<?> enclosingClass = c.getEnclosingClass();
+            if (enclosingClass != null) {
+                String prefix = "";
+                while (enclosingClass != null) {
+                    prefix = enclosingClass.getSimpleName() + "_" + prefix;
+                    enclosingClass = enclosingClass.getEnclosingClass();
+                }
+                return prefix + simpleName;
+            } else {
+                return simpleName;
+            }
+        }
+    };
+
+    public static Object convertFormatArg(Object arg) {
+        if (arg instanceof Class) {
+            return formattedClassName.get((Class<?>) arg);
+        }
+        return arg;
+    }
+
+    private static String formatDebugName(String format, Object arg1, Object arg2) {
+        return String.format(format, convertFormatArg(arg1), convertFormatArg(arg2));
+    }
+
+    private static DebugTimer createTimer(String format, Object arg1, Object arg2) {
+        String name = formatDebugName(format, arg1, arg2);
+        boolean conditional = enabledTimers == null || !findMatch(enabledTimers, enabledTimersSubstrings, name);
+        if (!ENABLED && conditional) {
+            return VOID_TIMER;
+        }
+        return new TimerImpl(name, conditional);
+    }
+
+    private static final DebugTimer VOID_TIMER = new DebugTimer() {
+
+        public DebugCloseable start() {
+            return DebugCloseable.VOID_CLOSEABLE;
+        }
+
+        public void setConditional(boolean flag) {
+            throw new InternalError("Cannot make void timer conditional");
+        }
+
+        public boolean isConditional() {
+            return false;
+        }
+
+        public long getCurrentValue() {
+            return 0L;
+        }
+
+        public TimeUnit getTimeUnit() {
+            return null;
+        }
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugCloseable.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+/**
+ * An object returned by {@link DebugTimer#start()} that when closed, stops the associated timer and
+ * adds the elapsed time since {@code start()} to the total for the timer.
+ */
+public interface DebugCloseable extends AutoCloseable {
+
+    DebugCloseable VOID_CLOSEABLE = new DebugCloseable() {
+
+        @Override
+        public void close() {
+        }
+    };
+
+    void close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import java.io.*;
+import java.util.*;
+
+public interface DebugConfig {
+
+    /**
+     * Determines the current log level in the {@linkplain Debug#currentScope() current debug scope}
+     * .
+     */
+    int getLogLevel();
+
+    /**
+     * Determines the current dump level in the {@linkplain Debug#currentScope() current debug
+     * scope}.
+     */
+    int getDumpLevel();
+
+    /**
+     * Determines if logging can be enabled in the current method, regardless of the
+     * {@linkplain Debug#currentScope() current debug scope}.
+     */
+    boolean isLogEnabledForMethod();
+
+    /**
+     * Determines if metering is enabled in the {@linkplain Debug#currentScope() current debug
+     * scope}.
+     *
+     * @see Debug#metric(CharSequence)
+     */
+    boolean isMeterEnabled();
+
+    /**
+     * Determines if memory use tracking is enabled in the {@linkplain Debug#currentScope() current
+     * debug scope}.
+     *
+     * @see Debug#memUseTracker(CharSequence)
+     */
+    boolean isMemUseTrackingEnabled();
+
+    /**
+     * Determines if dumping can be enabled in the current method, regardless of the
+     * {@linkplain Debug#currentScope() current debug scope}.
+     */
+    boolean isDumpEnabledForMethod();
+
+    /**
+     * @see Debug#isVerifyEnabled()
+     */
+    boolean isVerifyEnabled();
+
+    /**
+     * @see Debug#isVerifyEnabledForMethod()
+     */
+    boolean isVerifyEnabledForMethod();
+
+    /**
+     * Adds an object the context used by this configuration to do filtering.
+     */
+    void addToContext(Object o);
+
+    /**
+     * Removes an object the context used by this configuration to do filtering.
+     *
+     * This should only removes extra context added by {@link #addToContext(Object)}.
+     */
+    void removeFromContext(Object o);
+
+    /**
+     * @see Debug#timer(CharSequence)
+     */
+    boolean isTimeEnabled();
+
+    /**
+     * Handles notification of an exception occurring within a debug scope.
+     *
+     * @return the exception object that is to be propagated to parent scope. A value of
+     *         {@code null} indicates that {@code e} is to be propagated.
+     */
+    RuntimeException interceptException(Throwable e);
+
+    /**
+     * Gets the modifiable collection of dump handlers registered with this configuration.
+     */
+    Collection<DebugDumpHandler> dumpHandlers();
+
+    PrintStream output();
+
+    /**
+     * Gets the modifiable collection of verify handlers registered with this configuration.
+     */
+    Collection<DebugVerifyHandler> verifyHandlers();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigCustomizer.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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.debug;
+
+public interface DebugConfigCustomizer {
+    void customize(DebugConfig config);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigScope.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import com.oracle.graal.debug.internal.*;
+
+/**
+ * A utility for scoping a change to the current debug
+ * {@linkplain DebugScope#setConfig(DebugConfig) configuration}. For example:
+ *
+ * <pre>
+ *     DebugConfig config = ...;
+ *     try (DebugConfigScope s = new DebugConfigScope(config)) {
+ *         // ...
+ *     }
+ * </pre>
+ */
+public class DebugConfigScope implements AutoCloseable {
+
+    private final DebugConfig current;
+
+    /**
+     * Sets the current debug {@linkplain DebugScope#setConfig(DebugConfig) configuration} to a
+     * given value and creates an object that when {@linkplain #close() closed} resets the
+     * configuration to the {@linkplain DebugScope#getConfig() current} configuration.
+     */
+    public DebugConfigScope(DebugConfig config) {
+        this.current = DebugScope.getConfig();
+        DebugScope.getInstance().setConfig(config);
+    }
+
+    public void close() {
+        DebugScope.getInstance().setConfig(current);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpHandler.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import java.io.*;
+
+public interface DebugDumpHandler extends Closeable {
+
+    void dump(Object object, String message);
+
+    /**
+     * Flushes and releases resources managed by this dump handler. A subsequent call to
+     * {@link #dump(Object, String)} will create and open new resources. That is, this method can be
+     * used to reset the handler.
+     */
+    @Override
+    void close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpScope.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+public class DebugDumpScope {
+
+    public final String name;
+
+    /**
+     * Specifies if this scope decorates an inner scope. A hierarchical or tree representation of
+     * nested scopes may choose to represent a decorator scope at the same level as the scope it
+     * decorates.
+     */
+    public final boolean decorator;
+
+    public DebugDumpScope(String name) {
+        this(name, false);
+    }
+
+    public DebugDumpScope(String name, boolean decorator) {
+        this.name = name;
+        this.decorator = decorator;
+    }
+
+    @Override
+    public String toString() {
+        return "DebugDumpScope[" + name + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugEnvironment.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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.debug;
+
+import static com.oracle.graal.debug.GraalDebugConfig.*;
+
+import java.io.*;
+import java.util.*;
+
+import jdk.internal.jvmci.service.*;
+
+public class DebugEnvironment {
+
+    public static GraalDebugConfig initialize(PrintStream log) {
+
+        if (!Debug.isEnabled()) {
+            log.println("WARNING: Scope debugging needs to be enabled with -esa or -D" + Debug.Initialization.INITIALIZER_PROPERTY_NAME + "=true");
+            return null;
+        }
+        List<DebugDumpHandler> dumpHandlers = new ArrayList<>();
+        List<DebugVerifyHandler> verifyHandlers = new ArrayList<>();
+        GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), Verify.getValue(), MethodFilter.getValue(),
+                        log, dumpHandlers, verifyHandlers);
+
+        for (DebugConfigCustomizer customizer : Services.load(DebugConfigCustomizer.class)) {
+            customizer.customize(debugConfig);
+        }
+
+        Debug.setConfig(debugConfig);
+        return debugConfig;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugFilter.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import java.util.*;
+import java.util.regex.*;
+
+import com.oracle.graal.debug.internal.*;
+
+/**
+ * Implements the filter specified by the {@link GraalDebugConfig#Dump},
+ * {@link GraalDebugConfig#Log}, {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time}
+ * options.
+ * <p>
+ * These options enable the associated debug facility if their filter matches the
+ * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current
+ * scope}. For the {@link GraalDebugConfig#Dump} and {@link GraalDebugConfig#Log} options, the log
+ * or dump level is set. The {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time}
+ * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0}
+ * means enabled.
+ * <p>
+ * A filter is a list of comma-separated terms of the form {@code <pattern>[:<level>]}.
+ * {@code <pattern>} is interpreted as a glob pattern if it contains a "*" or "?" character.
+ * Otherwise, it is interpreted as a substring. If {@code <pattern>} is empty, it matches every
+ * scope. If {@code :<level>} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term
+ * {@code ~<pattern>} is a shorthand for {@code <pattern>:0} to disable a debug facility for a
+ * pattern.
+ * <p>
+ * The resulting log level of a scope is determined by the <em>last</em> matching term. If no term
+ * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log
+ * level of {@link Debug#DEFAULT_LOG_LEVEL}.
+ *
+ * <h2>Examples of filters</h2>
+ *
+ * <ul>
+ * <li>(empty string)<br>
+ * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}.
+ *
+ * <li> {@code :1}<br>
+ * Matches any scope with log level 1.
+ *
+ * <li> {@code *}<br>
+ * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}.
+ *
+ * <li> {@code CodeGen,CodeInstall}<br>
+ * Matches scopes containing "CodeGen" or "CodeInstall", both with log level
+ * {@link Debug#DEFAULT_LOG_LEVEL}.
+ *
+ * <li> {@code CodeGen:2,CodeInstall:1}<br>
+ * Matches scopes containing "CodeGen" with log level 2, or "CodeInstall" with log level 1.
+ *
+ * <li> {@code :1,Dead:2}<br>
+ * Matches scopes containing "Dead" with log level 2, and all other scopes with log level 1.
+ *
+ * <li> {@code :1,Dead:0}<br>
+ * Matches all scopes with log level 1, except those containing "Dead".
+ *
+ * <li> {@code Code*}<br>
+ * Matches scopes starting with "Code" with log level {@link Debug#DEFAULT_LOG_LEVEL}.
+ *
+ * <li> {@code Code,~Dead}<br>
+ * Matches scopes containing "Code" but not "Dead", with log level {@link Debug#DEFAULT_LOG_LEVEL}.
+ * </ul>
+ */
+final class DebugFilter {
+
+    public static DebugFilter parse(String spec) {
+        if (spec == null) {
+            return null;
+        }
+        return new DebugFilter(spec.split(","));
+    }
+
+    private final Term[] terms;
+
+    private DebugFilter(String[] terms) {
+        if (terms.length == 0) {
+            this.terms = null;
+        } else {
+            this.terms = new Term[terms.length];
+            for (int i = 0; i < terms.length; i++) {
+                String t = terms[i];
+                int idx = t.indexOf(':');
+
+                String pattern;
+                int level;
+                if (idx < 0) {
+                    if (t.startsWith("~")) {
+                        pattern = t.substring(1);
+                        level = 0;
+                    } else {
+                        pattern = t;
+                        level = Debug.DEFAULT_LOG_LEVEL;
+                    }
+                } else {
+                    pattern = t.substring(0, idx);
+                    if (idx + 1 < t.length()) {
+                        level = Integer.parseInt(t.substring(idx + 1));
+                    } else {
+                        level = Debug.DEFAULT_LOG_LEVEL;
+                    }
+                }
+
+                this.terms[i] = new Term(pattern, level);
+            }
+        }
+    }
+
+    /**
+     * Check whether a given input is matched by this filter, and determine the log level.
+     */
+    public int matchLevel(String input) {
+        if (terms == null) {
+            return Debug.DEFAULT_LOG_LEVEL;
+        } else {
+            int level = 0;
+            for (Term t : terms) {
+                if (t.matches(input)) {
+                    level = t.level;
+                }
+            }
+            return level;
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder("DebugFilter");
+        if (terms != null) {
+            buf.append(Arrays.toString(terms));
+        } else {
+            buf.append("[]");
+        }
+        return buf.toString();
+    }
+
+    private static class Term {
+
+        private final Pattern pattern;
+        public final int level;
+
+        public Term(String filter, int level) {
+            this.level = level;
+            if (filter.isEmpty()) {
+                this.pattern = null;
+            } else if (filter.contains("*") || filter.contains("?")) {
+                this.pattern = Pattern.compile(MethodFilter.createGlobString(filter));
+            } else {
+                this.pattern = Pattern.compile(".*" + MethodFilter.createGlobString(filter) + ".*");
+            }
+        }
+
+        /**
+         * Determines if a given input is matched by this filter.
+         */
+        public boolean matches(String input) {
+            return pattern == null || pattern.matcher(input).matches();
+        }
+
+        @Override
+        public String toString() {
+            return (pattern == null ? ".*" : pattern.toString()) + ":" + level;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,102 @@
+/*
+ * 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.debug;
+
+import java.util.*;
+
+/**
+ * Facility for recording value frequencies.
+ */
+public interface DebugHistogram {
+
+    /**
+     * Gets the name specified when this objected was {@linkplain Debug#createHistogram(String)
+     * created}.
+     */
+    String getName();
+
+    /**
+     * Increments the count for a given value.
+     */
+    void add(Object value);
+
+    void add(Object value, long count);
+
+    /**
+     * A value and a frequency. The ordering imposed by {@link #compareTo(CountedValue)} places
+     * values with higher frequencies first.
+     */
+    public class CountedValue implements Comparable<CountedValue> {
+
+        private long count;
+        private final Object value;
+
+        public CountedValue(long count, Object value) {
+            this.count = count;
+            this.value = value;
+        }
+
+        public int compareTo(CountedValue o) {
+            if (count < o.count) {
+                return 1;
+            } else if (count > o.count) {
+                return -1;
+            }
+            return 0;
+        }
+
+        @Override
+        public String toString() {
+            return count + " -> " + value;
+        }
+
+        public void inc() {
+            count++;
+        }
+
+        public void add(long n) {
+            count += n;
+        }
+
+        public long getCount() {
+            return count;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+    }
+
+    /**
+     * Gets a list of the counted values, sorted in descending order of frequency.
+     */
+    List<CountedValue> getValues();
+
+    /**
+     * Interface for a service that can render a visualization of a histogram.
+     */
+    public interface Printer {
+
+        void print(DebugHistogram histogram);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugInitializationPropertyProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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.debug;
+
+/**
+ * Sets one or more system properties used during initialization of the {@link Debug} class.
+ */
+public interface DebugInitializationPropertyProvider {
+    void apply();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMemUseTracker.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import com.sun.management.*;
+
+/**
+ * Tracks memory usage within a scope using {@link ThreadMXBean}. This facility should be employed
+ * using the try-with-resources pattern:
+ *
+ * <pre>
+ * try (DebugMemUseTracker.Closeable a = memUseTracker.start()) {
+ *     // the code to measure
+ * }
+ * </pre>
+ */
+public interface DebugMemUseTracker {
+
+    /**
+     * Creates a point from which memory usage will be recorded if memory use tracking is
+     * {@linkplain Debug#isMemUseTrackingEnabled() enabled}.
+     *
+     * @return an object that must be closed once the activity has completed to add the memory used
+     *         since this call to the total for this tracker
+     */
+    DebugCloseable start();
+
+    /**
+     * Gets the current value of this tracker.
+     */
+    long getCurrentValue();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugMetric.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+/**
+ * A counter for some value of interest.
+ */
+public interface DebugMetric {
+
+    /**
+     * Adds 1 to this counter if metering is {@link Debug#isMeterEnabled() enabled} or this is an
+     * {@linkplain #isConditional() unconditional} metric.
+     */
+    void increment();
+
+    /**
+     * Adds {@code value} to this counter if metering is {@link Debug#isMeterEnabled() enabled} or
+     * this is an {@linkplain #isConditional() unconditional} metric.
+     */
+    void add(long value);
+
+    /**
+     * Sets a flag determining if this counter is only enabled if metering is
+     * {@link Debug#isMeterEnabled() enabled}.
+     */
+    void setConditional(boolean flag);
+
+    /**
+     * Determines if this counter is only enabled if metering is {@link Debug#isMeterEnabled()
+     * enabled}.
+     */
+    boolean isConditional();
+
+    /**
+     * Gets the current value of this metric.
+     */
+    long getCurrentValue();
+
+    /**
+     * Determines if this counter is enabled (either conditionally or unconditionally).
+     */
+    default boolean isEnabled() {
+        return !isConditional() || Debug.isMeterEnabled();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugTimer.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import java.util.concurrent.*;
+
+/**
+ * A timer for some activity of interest. A timer should be deployed using the try-with-resources
+ * pattern:
+ *
+ * <pre>
+ * try (TimerCloseable a = timer.start()) {
+ *     // the code to time
+ * }
+ * </pre>
+ */
+public interface DebugTimer {
+
+    /**
+     * Starts this timer if timing is {@linkplain Debug#isTimeEnabled() enabled} or this is an
+     * {@linkplain #isConditional() unconditional} timer.
+     *
+     * @return an object that must be closed once the activity has completed to add the elapsed time
+     *         since this call to the total for this timer
+     */
+    DebugCloseable start();
+
+    /**
+     * Sets a flag determining if this timer is only enabled if timing is
+     * {@link Debug#isTimeEnabled() enabled}.
+     */
+    void setConditional(boolean flag);
+
+    /**
+     * Determines if this timer is only enabled if timing is {@link Debug#isTimeEnabled() enabled}.
+     */
+    boolean isConditional();
+
+    /**
+     * Gets the current value of this timer.
+     */
+    long getCurrentValue();
+
+    /**
+     * Gets the time unit of this timer.
+     */
+    TimeUnit getTimeUnit();
+
+    /**
+     * Gets the timer recording the amount time spent within a timed scope minus the time spent in
+     * any nested timed scopes.
+     *
+     * @return null if this timer does not support flat timing
+     */
+    default DebugTimer getFlat() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+/**
+ * Performs some kind of verification on an object.
+ */
+public interface DebugVerifyHandler {
+
+    /**
+     * Verifies that a given object satisfies some invariants.
+     *
+     * @param object object to verify
+     * @param message description of verification context
+     */
+    void verify(Object object, String message);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,238 @@
+/*
+ * 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.debug;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.debug.internal.*;
+
+public class DelegatingDebugConfig implements DebugConfig {
+
+    protected final DebugConfig delegate;
+
+    /**
+     * The features of a {@link DelegatingDebugConfig} that can be force
+     * {@linkplain DelegatingDebugConfig#enable(Feature) enabled}/
+     * {@linkplain DelegatingDebugConfig#disable(Feature) disabled} or
+     * {@linkplain DelegatingDebugConfig#delegate(Feature) delegated}.
+     */
+    public enum Feature {
+        /**
+         * @see Debug#isLogEnabledForMethod()
+         */
+        LOG_METHOD,
+        /**
+         * @see Debug#isDumpEnabledForMethod()
+         */
+        DUMP_METHOD,
+        /**
+         * @see Debug#isVerifyEnabled()
+         */
+        VERIFY,
+        /**
+         * @see Debug#isVerifyEnabledForMethod()
+         */
+        VERIFY_METHOD,
+        /**
+         * @see Debug#isMeterEnabled()
+         */
+        METER,
+        /**
+         * @see Debug#isMemUseTrackingEnabled()
+         */
+        TRACK_MEM_USE,
+        /**
+         * @see Debug#isTimeEnabled()
+         */
+        TIME,
+        /**
+         * @see DebugConfig#interceptException(Throwable)
+         */
+        INTERCEPT
+    }
+
+    private final Map<Feature, Boolean> featureState = new EnumMap<>(Feature.class);
+
+    /**
+     * The debug levels of a {@link DelegatingDebugConfig} than can be
+     * {@linkplain DelegatingDebugConfig#override(Level, int) overridden} or
+     * {@linkplain DelegatingDebugConfig#delegate(Level) delegated}.
+     */
+    public enum Level {
+        LOG,
+        DUMP
+    }
+
+    private final Map<Level, Integer> levelState = new EnumMap<>(Level.class);
+
+    /**
+     * Creates a config that delegates to the {@link DebugScope#getConfig() current config}.
+     */
+    public DelegatingDebugConfig() {
+        this(DebugScope.getConfig());
+    }
+
+    /**
+     * Creates a config that delegates to a given config.
+     */
+    public DelegatingDebugConfig(DebugConfig delegate) {
+        this.delegate = delegate;
+    }
+
+    public DelegatingDebugConfig enable(Feature feature) {
+        featureState.put(feature, Boolean.TRUE);
+        return this;
+    }
+
+    public DelegatingDebugConfig disable(Feature feature) {
+        featureState.put(feature, Boolean.FALSE);
+        return this;
+    }
+
+    public DelegatingDebugConfig override(Level level, int newLevel) {
+        levelState.put(level, newLevel);
+        return this;
+    }
+
+    public DelegatingDebugConfig delegate(Feature feature) {
+        featureState.put(feature, null);
+        return this;
+    }
+
+    public DelegatingDebugConfig delegate(Level level) {
+        levelState.put(level, null);
+        return this;
+    }
+
+    @Override
+    public int getLogLevel() {
+        Integer ls = levelState.get(Level.LOG);
+        if (ls == null) {
+            return delegate.getLogLevel();
+        }
+        return ls.intValue();
+    }
+
+    public boolean isLogEnabledForMethod() {
+        Boolean fs = featureState.get(Feature.LOG_METHOD);
+        if (fs == null) {
+            return delegate.isLogEnabledForMethod();
+        }
+        return fs.booleanValue();
+    }
+
+    @Override
+    public boolean isMeterEnabled() {
+        Boolean fs = featureState.get(Feature.METER);
+        if (fs == null) {
+            return delegate.isMeterEnabled();
+        }
+        return fs.booleanValue();
+    }
+
+    public boolean isMemUseTrackingEnabled() {
+        Boolean fs = featureState.get(Feature.TRACK_MEM_USE);
+        if (fs == null) {
+            return delegate.isMemUseTrackingEnabled();
+        }
+        return fs.booleanValue();
+    }
+
+    @Override
+    public int getDumpLevel() {
+        Integer ls = levelState.get(Level.DUMP);
+        if (ls == null) {
+            return delegate.getDumpLevel();
+        }
+        return ls.intValue();
+    }
+
+    public boolean isDumpEnabledForMethod() {
+        Boolean fs = featureState.get(Feature.DUMP_METHOD);
+        if (fs == null) {
+            return delegate.isDumpEnabledForMethod();
+        }
+        return fs.booleanValue();
+    }
+
+    @Override
+    public boolean isVerifyEnabled() {
+        Boolean fs = featureState.get(Feature.VERIFY);
+        if (fs == null) {
+            return delegate.isVerifyEnabled();
+        }
+        return fs.booleanValue();
+    }
+
+    public boolean isVerifyEnabledForMethod() {
+        Boolean fs = featureState.get(Feature.VERIFY_METHOD);
+        if (fs == null) {
+            return delegate.isVerifyEnabledForMethod();
+        }
+        return fs.booleanValue();
+    }
+
+    @Override
+    public boolean isTimeEnabled() {
+        Boolean fs = featureState.get(Feature.TIME);
+        if (fs == null) {
+            return delegate.isTimeEnabled();
+        }
+        return fs.booleanValue();
+    }
+
+    @Override
+    public RuntimeException interceptException(Throwable e) {
+        Boolean fs = featureState.get(Feature.INTERCEPT);
+        if (fs == null || fs) {
+            return delegate.interceptException(e);
+        }
+        return null;
+    }
+
+    @Override
+    public Collection<DebugDumpHandler> dumpHandlers() {
+        return delegate.dumpHandlers();
+    }
+
+    @Override
+    public Collection<DebugVerifyHandler> verifyHandlers() {
+        return delegate.verifyHandlers();
+    }
+
+    @Override
+    public PrintStream output() {
+        return delegate.output();
+    }
+
+    @Override
+    public void addToContext(Object o) {
+        delegate.addToContext(o);
+    }
+
+    @Override
+    public void removeFromContext(Object o) {
+        delegate.removeFromContext(o);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Fingerprint.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,145 @@
+/*
+ * 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.debug;
+
+import java.util.*;
+import java.util.stream.*;
+
+/**
+ * Facility for fingerprinting execution.
+ */
+public class Fingerprint implements AutoCloseable {
+
+    public static final String ENABLED_PROPERTY_NAME = "jvmci.fingerprint";
+
+    /**
+     * Determines whether fingerprinting is enabled. This is set by the
+     * {@value #ENABLED_PROPERTY_NAME} system property when this class is initialized.
+     */
+    public static final boolean ENABLED = Boolean.getBoolean(ENABLED_PROPERTY_NAME);
+
+    private static final ThreadLocal<Fingerprint> current = ENABLED ? new ThreadLocal<>() : null;
+
+    private final List<String> events;
+    private int index;
+
+    /**
+     * Creates an object to record a fingerprint.
+     */
+    public Fingerprint() {
+        events = new ArrayList<>();
+        index = -1;
+    }
+
+    /**
+     * Creates an object to verify execution matches a given fingerprint.
+     *
+     * @param toVerifyAgainst the fingerprint events to verify against
+     */
+    public Fingerprint(List<String> toVerifyAgainst) {
+        this.events = toVerifyAgainst;
+        index = 0;
+    }
+
+    /**
+     * Creates an object to verify execution matches a given fingerprint.
+     *
+     * @param toVerifyAgainst the fingerprint to verify against
+     */
+    public Fingerprint(Fingerprint toVerifyAgainst) {
+        this(toVerifyAgainst.events);
+    }
+
+    public Collection<String> getEvents() {
+        return Collections.unmodifiableCollection(events);
+    }
+
+    /**
+     * Starts fingerprint recording or verification for the current thread. At most one fingerprint
+     * object can be active for any thread.
+     */
+    public Fingerprint open() {
+        if (ENABLED) {
+            assert current.get() == null;
+            current.set(this);
+            return this;
+        }
+        return null;
+    }
+
+    /**
+     * Finishes fingerprint recording or verification for the current thread.
+     */
+    public void close() {
+        if (ENABLED) {
+            assert current.get() == this;
+            current.set(null);
+        }
+    }
+
+    private static final int BREAKPOINT_EVENT = Integer.getInteger(ENABLED_PROPERTY_NAME + ".breakpointEvent", -1);
+
+    /**
+     * Submits an execution event for the purpose of recording or verifying a fingerprint. This must
+     * only be called if {@link #ENABLED} is {@code true}.
+     */
+    public static void submit(String format, Object... args) {
+        assert ENABLED : "fingerprinting must be enabled (-D" + ENABLED_PROPERTY_NAME + "=true)";
+        Fingerprint fingerprint = current.get();
+        if (fingerprint != null) {
+            int eventId = fingerprint.nextEventId();
+            if (eventId == BREAKPOINT_EVENT) {
+                // Set IDE breakpoint on the following line and set the relevant
+                // system property to debug a fingerprint verification error.
+                System.console();
+            }
+            fingerprint.event(String.format(eventId + ": " + format, args));
+        }
+    }
+
+    private int nextEventId() {
+        return index == -1 ? events.size() : index;
+    }
+
+    private static final int MAX_EVENT_TAIL_IN_ERROR_MESSAGE = Integer.getInteger("jvmci.fingerprint.errorEventTailLength", 50);
+
+    private String tail() {
+        int start = Math.max(index - MAX_EVENT_TAIL_IN_ERROR_MESSAGE, 0);
+        return events.subList(start, index).stream().collect(Collectors.joining(String.format("%n")));
+    }
+
+    private void event(String entry) {
+        if (index == -1) {
+            events.add(entry);
+        } else {
+            if (index > events.size()) {
+                throw new InternalError(String.format("%s%nOriginal fingerprint limit reached", tail()));
+            }
+            String l = events.get(index);
+            if (!l.equals(entry)) {
+                throw new InternalError(String.format("%s%nFingerprint differs at event %d%nexpected: %s%n  actual: %s", tail(), index, l, entry));
+            }
+            index++;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/GraalDebugConfig.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import java.io.*;
+import java.util.*;
+
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.meta.*;
+import jdk.internal.jvmci.options.*;
+
+public class GraalDebugConfig implements DebugConfig {
+    @SuppressWarnings("all")
+    private static boolean assertionsEnabled() {
+        boolean assertionsEnabled = false;
+        assert assertionsEnabled = true;
+        return assertionsEnabled;
+    }
+
+    // @formatter:off
+    @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug)
+    public static final OptionValue<String> Dump = new OptionValue<>(null);
+    @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " +
+                   "An empty value enables all metrics unconditionally.", type = OptionType.Debug)
+    public static final OptionValue<String> Meter = new OptionValue<>(null);
+    @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug)
+    public static final OptionValue<String> Verify = new OptionValue<String>() {
+        @Override
+        protected String defaultValue() {
+            return assertionsEnabled() ? "" : null;
+        }
+    };
+    @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " +
+                   "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug)
+    public static final OptionValue<String> TrackMemUse = new OptionValue<>(null);
+    @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " +
+                   "An empty value enables all timers unconditionally.", type = OptionType.Debug)
+    public static final OptionValue<String> Time = new OptionValue<>(null);
+    @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug)
+    public static final OptionValue<String> Log = new OptionValue<>(null);
+    @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug)
+    public static final OptionValue<String> MethodFilter = new OptionValue<>(null);
+    @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug)
+    public static final OptionValue<Boolean> MethodFilterRootOnly = new OptionValue<>(false);
+
+    @Option(help = "How to print metric and timing values:%n" +
+                   "Name - aggregate by unqualified name%n" +
+                   "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" +
+                   "Complete - aggregate by qualified name%n" +
+                   "Thread - aggregate by qualified name and thread", type = OptionType.Debug)
+    public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name");
+    @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug)
+    public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true);
+    @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug)
+    public static final OptionValue<String> DebugValueThreadFilter = new OptionValue<>(null);
+    @Option(help = "Send JVMCI compiler IR to dump handlers on error", type = OptionType.Debug)
+    public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false);
+    @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug)
+    public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false);
+    @Option(help = "Enable more verbose log output when available", type = OptionType.Debug)
+    public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false);
+    // @formatter:on
+
+    static boolean isNotEmpty(OptionValue<String> option) {
+        return option.getValue() != null && !option.getValue().isEmpty();
+    }
+
+    public static boolean areDebugScopePatternsEnabled() {
+        return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled();
+    }
+
+    /**
+     * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null,
+     * non-empty value.
+     */
+    public static boolean areScopedMetricsOrTimersEnabled() {
+        return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse);
+    }
+
+    private final DebugFilter logFilter;
+    private final DebugFilter meterFilter;
+    private final DebugFilter trackMemUseFilter;
+    private final DebugFilter timerFilter;
+    private final DebugFilter dumpFilter;
+    private final DebugFilter verifyFilter;
+    private final MethodFilter[] methodFilter;
+    private final List<DebugDumpHandler> dumpHandlers;
+    private final List<DebugVerifyHandler> verifyHandlers;
+    private final PrintStream output;
+    private final Set<Object> extraFilters = new HashSet<>();
+
+    public GraalDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output,
+                    List<DebugDumpHandler> dumpHandlers, List<DebugVerifyHandler> verifyHandlers) {
+        this.logFilter = DebugFilter.parse(logFilter);
+        this.meterFilter = DebugFilter.parse(meterFilter);
+        this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter);
+        this.timerFilter = DebugFilter.parse(timerFilter);
+        this.dumpFilter = DebugFilter.parse(dumpFilter);
+        this.verifyFilter = DebugFilter.parse(verifyFilter);
+        if (methodFilter == null || methodFilter.isEmpty()) {
+            this.methodFilter = null;
+        } else {
+            this.methodFilter = com.oracle.graal.debug.MethodFilter.parse(methodFilter);
+        }
+
+        // Report the filters that have been configured so the user can verify it's what they expect
+        if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) {
+            // TTY.println(Thread.currentThread().getName() + ": " + toString());
+        }
+        this.dumpHandlers = dumpHandlers;
+        this.verifyHandlers = verifyHandlers;
+        this.output = output;
+    }
+
+    public int getLogLevel() {
+        return getLevel(logFilter);
+    }
+
+    public boolean isLogEnabledForMethod() {
+        return isEnabledForMethod(logFilter);
+    }
+
+    public boolean isMeterEnabled() {
+        return isEnabled(meterFilter);
+    }
+
+    public boolean isMemUseTrackingEnabled() {
+        return isEnabled(trackMemUseFilter);
+    }
+
+    public int getDumpLevel() {
+        return getLevel(dumpFilter);
+    }
+
+    public boolean isDumpEnabledForMethod() {
+        return isEnabledForMethod(dumpFilter);
+    }
+
+    public boolean isVerifyEnabled() {
+        return isEnabled(verifyFilter);
+    }
+
+    public boolean isVerifyEnabledForMethod() {
+        return isEnabledForMethod(verifyFilter);
+    }
+
+    public boolean isTimeEnabled() {
+        return isEnabled(timerFilter);
+    }
+
+    public PrintStream output() {
+        return output;
+    }
+
+    private boolean isEnabled(DebugFilter filter) {
+        return getLevel(filter) > 0;
+    }
+
+    private int getLevel(DebugFilter filter) {
+        int level;
+        if (filter == null) {
+            level = 0;
+        } else {
+            level = filter.matchLevel(Debug.currentScope());
+        }
+        if (level > 0 && !checkMethodFilter()) {
+            level = 0;
+        }
+        return level;
+    }
+
+    private boolean isEnabledForMethod(DebugFilter filter) {
+        return filter != null && checkMethodFilter();
+    }
+
+    /**
+     * Extracts a {@link JavaMethod} from an opaque debug context.
+     *
+     * @return the {@link JavaMethod} represented by {@code context} or null
+     */
+    public static JavaMethod asJavaMethod(Object context) {
+        if (context instanceof JavaMethodContex) {
+            return ((JavaMethodContex) context).asJavaMethod();
+        }
+        return null;
+    }
+
+    private boolean checkMethodFilter() {
+        if (methodFilter == null && extraFilters.isEmpty()) {
+            return true;
+        } else {
+            JavaMethod lastMethod = null;
+            for (Object o : Debug.context()) {
+                if (extraFilters.contains(o)) {
+                    return true;
+                } else if (methodFilter != null) {
+                    JavaMethod method = asJavaMethod(o);
+                    if (method != null) {
+                        if (!MethodFilterRootOnly.getValue()) {
+                            if (com.oracle.graal.debug.MethodFilter.matches(methodFilter, method)) {
+                                return true;
+                            }
+                        } else {
+                            /*
+                             * The context values operate as a stack so if we want MethodFilter to
+                             * only apply to the root method we have to check only the last method
+                             * seen.
+                             */
+                            lastMethod = method;
+                        }
+                    }
+                }
+            }
+            if (lastMethod != null && com.oracle.graal.debug.MethodFilter.matches(methodFilter, lastMethod)) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Debug config:");
+        add(sb, "Log", logFilter);
+        add(sb, "Meter", meterFilter);
+        add(sb, "Time", timerFilter);
+        add(sb, "Dump", dumpFilter);
+        add(sb, "MethodFilter", methodFilter);
+        return sb.toString();
+    }
+
+    private static void add(StringBuilder sb, String name, Object filter) {
+        if (filter != null) {
+            sb.append(' ');
+            sb.append(name);
+            sb.append('=');
+            if (filter instanceof Object[]) {
+                sb.append(Arrays.toString((Object[]) filter));
+            } else {
+                sb.append(String.valueOf(filter));
+            }
+        }
+    }
+
+    @Override
+    public RuntimeException interceptException(Throwable e) {
+        if (e instanceof BailoutException && !InterceptBailout.getValue()) {
+            return null;
+        }
+        Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output));
+        Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope()));
+        for (Object o : Debug.context()) {
+            if (DumpOnError.getValue()) {
+                Debug.dump(o, "Exception: " + e.toString());
+            } else {
+                Debug.log("Context obj %s", o);
+            }
+
+        }
+        return null;
+    }
+
+    @Override
+    public Collection<DebugDumpHandler> dumpHandlers() {
+        return dumpHandlers;
+    }
+
+    @Override
+    public Collection<DebugVerifyHandler> verifyHandlers() {
+        return verifyHandlers;
+    }
+
+    @Override
+    public void addToContext(Object o) {
+        extraFilters.add(o);
+    }
+
+    @Override
+    public void removeFromContext(Object o) {
+        extraFilters.remove(o);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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.debug;
+
+/**
+ * Object used to close a debug {@link Debug#indent() indentation} scope.
+ * <p>
+ * Example usage:
+ *
+ * <pre>
+ *
+ *      try (Indent i1 = Debug.logAndIndent("header message")) {
+ *          ...
+ *          Debug.log("message");
+ *          ...
+ *          try (Indent i2 = Debug.logAndIndent(sub-header message")) {
+ *              ...
+ *              Debug.log("inner message");
+ *              ...
+ *          }
+ *      }
+ *
+ * </pre>
+ */
+public interface Indent extends AutoCloseable {
+
+    /**
+     * Closes the current indentation scope.
+     */
+    void close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/JavaMethodContex.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,33 @@
+/*
+ * 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.debug;
+
+import jdk.internal.jvmci.meta.*;
+
+/**
+ * Interface for objects used in Debug {@linkplain Debug#context() context} that can provide a
+ * {@link JavaMethod}.
+ */
+public interface JavaMethodContex {
+    JavaMethod asJavaMethod();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/MethodFilter.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import java.util.*;
+import java.util.regex.*;
+
+import jdk.internal.jvmci.meta.*;
+
+/**
+ * This class implements a method filter that can filter based on class name, method name and
+ * parameters. The syntax for the source pattern that is passed to the constructor is as follows:
+ *
+ * <pre>
+ * SourcePatterns = SourcePattern ["," SourcePatterns] .
+ * SourcePattern = [ Class "." ] method [ "(" [ Parameter { ";" Parameter } ] ")" ] .
+ * Parameter = Class | "int" | "long" | "float" | "double" | "short" | "char" | "boolean" .
+ * Class = { package "." } class .
+ * </pre>
+ *
+ *
+ * Glob pattern matching (*, ?) is allowed in all parts of the source pattern. Examples for valid
+ * filters are:
+ *
+ * <ul>
+ * <li>
+ *
+ * <pre>
+ * visit(Argument;BlockScope)
+ * </pre>
+ *
+ * Matches all methods named "visit", with the first parameter of type "Argument", and the second
+ * parameter of type "BlockScope". The packages of the parameter types are irrelevant.</li>
+ * <li>
+ *
+ * <pre>
+ * arraycopy(Object;;;;)
+ * </pre>
+ *
+ * Matches all methods named "arraycopy", with the first parameter of type "Object", and four more
+ * parameters of any type. The packages of the parameter types are irrelevant.</li>
+ * <li>
+ *
+ * <pre>
+ * com.oracle.graal.compiler.graph.PostOrderNodeIterator.*
+ * </pre>
+ *
+ * Matches all methods in the class "com.oracle.graal.compiler.graph.PostOrderNodeIterator".</li>
+ * <li>
+ *
+ * <pre>
+ * *
+ * </pre>
+ *
+ * Matches all methods in all classes</li>
+ * <li>
+ *
+ * <pre>
+ * com.oracle.graal.compiler.graph.*.visit
+ * </pre>
+ *
+ * Matches all methods named "visit" in classes in the package "com.oracle.graal.compiler.graph".
+ * <li>
+ *
+ * <pre>
+ * arraycopy,toString
+ * </pre>
+ *
+ * Matches all methods named "arraycopy" or "toString", meaning that ',' acts as an <i>or</i>
+ * operator.</li>
+ * </ul>
+ */
+public class MethodFilter {
+
+    private final Pattern clazz;
+    private final Pattern methodName;
+    private final Pattern[] signature;
+
+    /**
+     * Parses a string containing list of comma separated filter patterns into an array of
+     * {@link MethodFilter}s.
+     */
+    public static MethodFilter[] parse(String commaSeparatedPatterns) {
+        String[] filters = commaSeparatedPatterns.split(",");
+        MethodFilter[] methodFilters = new MethodFilter[filters.length];
+        for (int i = 0; i < filters.length; i++) {
+            methodFilters[i] = new MethodFilter(filters[i]);
+        }
+        return methodFilters;
+    }
+
+    /**
+     * Determines if a given method is matched by a given array of filters.
+     */
+    public static boolean matches(MethodFilter[] filters, JavaMethod method) {
+        for (MethodFilter filter : filters) {
+            if (filter.matches(method)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determines if a given class name is matched by a given array of filters.
+     */
+    public static boolean matchesClassName(MethodFilter[] filters, String className) {
+        for (MethodFilter filter : filters) {
+            if (filter.matchesClassName(className)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public MethodFilter(String sourcePattern) {
+        String pattern = sourcePattern.trim();
+
+        // extract parameter part
+        int pos = pattern.indexOf('(');
+        if (pos != -1) {
+            if (pattern.charAt(pattern.length() - 1) != ')') {
+                throw new IllegalArgumentException("missing ')' at end of method filter pattern: " + pattern);
+            }
+            String[] signatureClasses = pattern.substring(pos + 1, pattern.length() - 1).split(";", -1);
+            signature = new Pattern[signatureClasses.length];
+            for (int i = 0; i < signatureClasses.length; i++) {
+                signature[i] = createClassGlobPattern(signatureClasses[i].trim());
+            }
+            pattern = pattern.substring(0, pos);
+        } else {
+            signature = null;
+        }
+
+        // If there is at least one "." then everything before the last "." is the class name.
+        // Otherwise, the pattern contains only the method name.
+        pos = pattern.lastIndexOf('.');
+        if (pos != -1) {
+            clazz = createClassGlobPattern(pattern.substring(0, pos));
+            methodName = Pattern.compile(createGlobString(pattern.substring(pos + 1)));
+        } else {
+            clazz = null;
+            methodName = Pattern.compile(createGlobString(pattern));
+        }
+    }
+
+    public static String createGlobString(String pattern) {
+        return Pattern.quote(pattern).replace("?", "\\E.\\Q").replace("*", "\\E.*\\Q");
+    }
+
+    private static Pattern createClassGlobPattern(String pattern) {
+        if (pattern.length() == 0) {
+            return null;
+        } else if (pattern.contains(".")) {
+            return Pattern.compile(createGlobString(pattern));
+        } else {
+            return Pattern.compile("([^\\.\\$]*[\\.\\$])*" + createGlobString(pattern));
+        }
+    }
+
+    /**
+     * Determines if the class part of this filter matches a given class name.
+     */
+    public boolean matchesClassName(String className) {
+        return clazz == null || clazz.matcher(className).matches();
+    }
+
+    public boolean matches(JavaMethod o) {
+        // check method name first, since MetaUtil.toJavaName is expensive
+        if (methodName != null && !methodName.matcher(o.getName()).matches()) {
+            return false;
+        }
+        if (clazz != null && !clazz.matcher(o.getDeclaringClass().toJavaName()).matches()) {
+            return false;
+        }
+        if (signature != null) {
+            Signature sig = o.getSignature();
+            if (sig.getParameterCount(false) != signature.length) {
+                return false;
+            }
+            for (int i = 0; i < signature.length; i++) {
+                JavaType type = sig.getParameterType(i, null);
+                String javaName = type.toJavaName();
+                if (signature[i] != null && !signature[i].matcher(javaName).matches()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buf = new StringBuilder("MethodFilter[");
+        String sep = "";
+        if (clazz != null) {
+            buf.append(sep).append("clazz=").append(clazz);
+            sep = ", ";
+        }
+        if (methodName != null) {
+            buf.append(sep).append("methodName=").append(methodName);
+            sep = ", ";
+        }
+        if (signature != null) {
+            buf.append(sep).append("signature=").append(Arrays.toString(signature));
+            sep = ", ";
+        }
+        return buf.append("]").toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/TopLevelDebugConfig.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 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.debug;
+
+/**
+ * A marker class for a scoped debug configuration covering a compilation region. Useful for
+ * programmatically enabling debug config features.
+ *
+ */
+public class TopLevelDebugConfig extends DelegatingDebugConfig {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/AccumulatedDebugValue.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,32 @@
+/*
+ * 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.debug.internal;
+
+public abstract class AccumulatedDebugValue extends DebugValue {
+    protected final DebugValue flat;
+
+    public AccumulatedDebugValue(String name, boolean conditional, DebugValue flat) {
+        super(name + "_Accm", conditional);
+        this.flat = flat;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/CloseableCounterImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,70 @@
+/*
+ * 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.debug.internal;
+
+import com.oracle.graal.debug.*;
+
+/**
+ * A helper class for DebugValues that can nest and need to split out accumulated and flat values
+ * for some kind of counter-like measurement.
+ */
+abstract class CloseableCounterImpl implements DebugCloseable {
+
+    protected final CloseableCounterImpl parent;
+    protected final AccumulatedDebugValue counter;
+    protected final long start;
+    protected long nestedAmountToSubtract;
+
+    CloseableCounterImpl(CloseableCounterImpl parent, AccumulatedDebugValue counter) {
+        this.parent = parent;
+        this.start = getCounterValue();
+        this.counter = counter;
+    }
+
+    @Override
+    public void close() {
+        long end = getCounterValue();
+        long difference = end - start;
+        if (parent != null) {
+            if (!counter.getName().equals(parent.counter.getName())) {
+                parent.nestedAmountToSubtract += difference;
+
+                // Look for our counter in an outer scope and fix up
+                // the adjustment to the flat count
+                CloseableCounterImpl ancestor = parent.parent;
+                while (ancestor != null) {
+                    if (ancestor.counter.getName().equals(counter.getName())) {
+                        ancestor.nestedAmountToSubtract -= difference;
+                        break;
+                    }
+                    ancestor = ancestor.parent;
+                }
+            }
+        }
+        long flatAmount = difference - nestedAmountToSubtract;
+        counter.addToCurrentValue(difference);
+        counter.flat.addToCurrentValue(flatAmount);
+    }
+
+    abstract long getCounterValue();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramAsciiPrinter.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,102 @@
+/*
+ * 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.debug.internal;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.DebugHistogram.*;
+
+/**
+ * Renders a textual representation of a histogram to a given print stream.
+ */
+public class DebugHistogramAsciiPrinter implements Printer {
+
+    public static final int NumberSize = 10;
+    public static final int DefaultNameSize = 50;
+    public static final int DefaultBarSize = 100;
+    public static final int DefaultScale = 1;
+
+    private final PrintStream os;
+    private final int limit;
+    private final int nameSize;
+    private final int barSize;
+    private final int scale;
+
+    public DebugHistogramAsciiPrinter(PrintStream os) {
+        this(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize, DefaultScale);
+    }
+
+    /**
+     * @param os where to print
+     * @param limit limits printing to the {@code limit} most frequent values
+     * @param nameSize the width of the value names column
+     * @param barSize the width of the value frequency column
+     * @param scale a factor by which every result is divided
+     */
+    public DebugHistogramAsciiPrinter(PrintStream os, int limit, int nameSize, int barSize, int scale) {
+        this.os = os;
+        this.limit = limit;
+        this.nameSize = nameSize;
+        this.barSize = barSize;
+        this.scale = scale;
+    }
+
+    public void print(DebugHistogram histogram) {
+        List<CountedValue> list = histogram.getValues();
+        if (list.isEmpty()) {
+            os.printf("%s is empty.%n", histogram.getName());
+            return;
+        }
+
+        // Sum up the total number of elements.
+        long total = list.stream().mapToLong(CountedValue::getCount).sum();
+
+        // Print header.
+        os.printf("%s has %d unique elements and %d total elements:%n", histogram.getName(), list.size(), total / scale);
+
+        long max = list.get(0).getCount() / scale;
+        final int lineSize = nameSize + NumberSize + barSize + 10;
+        printLine(os, '-', lineSize);
+        String formatString = "| %-" + nameSize + "s | %-" + NumberSize + "d | %-" + barSize + "s |\n";
+        for (int i = 0; i < list.size() && i < limit; ++i) {
+            CountedValue cv = list.get(i);
+            long value = cv.getCount() / scale;
+            char[] bar = new char[(int) (((double) value / (double) max) * barSize)];
+            Arrays.fill(bar, '=');
+            String objectString = String.valueOf(cv.getValue());
+            if (objectString.length() > nameSize) {
+                objectString = objectString.substring(0, nameSize - 3) + "...";
+            }
+            os.printf(formatString, objectString, value, new String(bar));
+        }
+        printLine(os, '-', lineSize);
+    }
+
+    private static void printLine(PrintStream printStream, char c, int lineSize) {
+        char[] charArr = new char[lineSize];
+        Arrays.fill(charArr, c);
+        printStream.printf("%s%n", new String(charArr));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,66 @@
+/*
+ * 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.debug.internal;
+
+import java.util.*;
+
+import com.oracle.graal.debug.*;
+
+public class DebugHistogramImpl implements DebugHistogram {
+
+    private final String name;
+    private HashMap<Object, CountedValue> map = new HashMap<>();
+
+    public DebugHistogramImpl(String name) {
+        this.name = name;
+    }
+
+    public void add(Object value) {
+        CountedValue cv = map.get(value);
+        if (cv == null) {
+            map.put(value, new CountedValue(1, value));
+        } else {
+            cv.inc();
+        }
+    }
+
+    public void add(Object value, long count) {
+        CountedValue cv = map.get(value);
+        if (cv == null) {
+            map.put(value, new CountedValue(count, value));
+        } else {
+            cv.add(count);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public List<CountedValue> getValues() {
+        ArrayList<CountedValue> res = new ArrayList<>(map.values());
+        Collections.sort(res);
+        return res;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramRPrinter.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,80 @@
+/*
+ * 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.debug.internal;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.DebugHistogram.*;
+
+/**
+ * Renders a histogram as an R script to a given print stream. The R script emitted for a histogram
+ * is a simple set of statements for defining a vector of named objects.
+ */
+public class DebugHistogramRPrinter implements Printer {
+
+    private PrintStream os;
+    private int limit;
+
+    public DebugHistogramRPrinter(PrintStream os) {
+        this(os, Integer.MAX_VALUE);
+    }
+
+    /**
+     * @param os where to print
+     * @param limit limits printing to the {@code limit} most frequent values
+     */
+    public DebugHistogramRPrinter(PrintStream os, int limit) {
+        this.os = os;
+        this.limit = limit;
+    }
+
+    public void print(DebugHistogram histogram) {
+        List<CountedValue> list = histogram.getValues();
+        if (list.isEmpty()) {
+            return;
+        }
+
+        String var = histogram.getName().replace('-', '.').replace(' ', '_');
+        os.print(var + " <- c(");
+        for (int i = 0; i < list.size() && i < limit; ++i) {
+            CountedValue cv = list.get(i);
+            if (i != 0) {
+                os.print(", ");
+            }
+            os.print(cv.getCount());
+        }
+        os.println(");");
+
+        os.print("names(" + var + ") <- c(");
+        for (int i = 0; i < list.size() && i < limit; ++i) {
+            CountedValue cv = list.get(i);
+            if (i != 0) {
+                os.print(", ");
+            }
+            os.print("\"" + cv.getValue() + "\"");
+        }
+        os.println(");");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
+public final class DebugScope implements Debug.Scope {
+
+    private final class IndentImpl implements Indent {
+
+        private static final String INDENTATION_INCREMENT = "  ";
+
+        final String indent;
+        final IndentImpl parentIndent;
+
+        IndentImpl(IndentImpl parentIndent) {
+            this.parentIndent = parentIndent;
+            this.indent = (parentIndent == null ? "" : parentIndent.indent + INDENTATION_INCREMENT);
+        }
+
+        private void printScopeName(StringBuilder str) {
+            if (logScopeName) {
+                if (parentIndent != null) {
+                    parentIndent.printScopeName(str);
+                }
+                str.append(indent).append("[thread:").append(Thread.currentThread().getId()).append("] scope: ").append(getQualifiedName()).append(System.lineSeparator());
+                logScopeName = false;
+            }
+        }
+
+        public void log(int logLevel, String msg, Object... args) {
+            if (isLogEnabled(logLevel)) {
+                StringBuilder str = new StringBuilder();
+                printScopeName(str);
+                str.append(indent);
+                String result = args.length == 0 ? msg : String.format(msg, args);
+                String lineSep = System.lineSeparator();
+                str.append(result.replace(lineSep, lineSep.concat(indent)));
+                str.append(lineSep);
+                output.append(str);
+                lastUsedIndent = this;
+            }
+        }
+
+        IndentImpl indent() {
+            lastUsedIndent = new IndentImpl(this);
+            return lastUsedIndent;
+        }
+
+        @Override
+        public void close() {
+            if (parentIndent != null) {
+                lastUsedIndent = parentIndent;
+            }
+        }
+    }
+
+    private static final ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>();
+    private static final ThreadLocal<DebugScope> lastClosedTL = new ThreadLocal<>();
+    private static final ThreadLocal<DebugConfig> configTL = new ThreadLocal<>();
+    private static final ThreadLocal<Throwable> lastExceptionThrownTL = new ThreadLocal<>();
+
+    private final DebugScope parent;
+    private final DebugConfig parentConfig;
+    private final boolean sandbox;
+    private IndentImpl lastUsedIndent;
+    private boolean logScopeName;
+
+    private final Object[] context;
+
+    private DebugValueMap valueMap;
+
+    private String qualifiedName;
+    private final String unqualifiedName;
+
+    private static final char SCOPE_SEP = '.';
+
+    private boolean meterEnabled;
+    private boolean timeEnabled;
+    private boolean memUseTrackingEnabled;
+    private boolean verifyEnabled;
+
+    private int currentDumpLevel;
+    private int currentLogLevel;
+
+    private PrintStream output;
+
+    public static DebugScope getInstance() {
+        DebugScope result = instanceTL.get();
+        if (result == null) {
+            DebugScope topLevelDebugScope = new DebugScope(Thread.currentThread());
+            instanceTL.set(topLevelDebugScope);
+            return topLevelDebugScope;
+        } else {
+            return result;
+        }
+    }
+
+    public static DebugConfig getConfig() {
+        return configTL.get();
+    }
+
+    static final Object[] EMPTY_CONTEXT = new Object[0];
+
+    private DebugScope(Thread thread) {
+        this(thread.getName(), null, false);
+        computeValueMap(thread.getName());
+        DebugValueMap.registerTopLevel(getValueMap());
+    }
+
+    private DebugScope(String unqualifiedName, DebugScope parent, boolean sandbox, Object... context) {
+        this.parent = parent;
+        this.sandbox = sandbox;
+        this.parentConfig = getConfig();
+        this.context = context;
+        this.unqualifiedName = unqualifiedName;
+        if (parent != null) {
+            logScopeName = !unqualifiedName.equals("");
+        } else {
+            logScopeName = true;
+        }
+
+        this.output = TTY.out;
+        assert context != null;
+    }
+
+    private void computeValueMap(String name) {
+        if (parent != null) {
+            for (DebugValueMap child : parent.getValueMap().getChildren()) {
+                if (child.getName().equals(name)) {
+                    this.valueMap = child;
+                    return;
+                }
+            }
+            this.valueMap = new DebugValueMap(name);
+            parent.getValueMap().addChild(this.valueMap);
+        } else {
+            this.valueMap = new DebugValueMap(name);
+        }
+    }
+
+    public void close() {
+        instanceTL.set(parent);
+        configTL.set(parentConfig);
+        lastClosedTL.set(this);
+    }
+
+    public boolean isDumpEnabled(int dumpLevel) {
+        assert dumpLevel > 0;
+        return currentDumpLevel >= dumpLevel;
+    }
+
+    /**
+     * Enable dumping at the new {@code dumpLevel} for the remainder of enclosing scopes. This only
+     * works if a {@link TopLevelDebugConfig} was installed at a higher scope.
+     *
+     * @param dumpLevel
+     */
+    public static void setDumpLevel(int dumpLevel) {
+        TopLevelDebugConfig config = fetchTopLevelDebugConfig("setDebugLevel");
+        if (config != null) {
+            config.override(DelegatingDebugConfig.Level.DUMP, dumpLevel);
+            recursiveUpdateFlags();
+        }
+    }
+
+    /**
+     * Enable logging at the new {@code logLevel} for the remainder of enclosing scopes. This only
+     * works if a {@link TopLevelDebugConfig} was installed at a higher scope.
+     *
+     * @param logLevel
+     */
+    public static void setLogLevel(int logLevel) {
+        TopLevelDebugConfig config = fetchTopLevelDebugConfig("setLogLevel");
+        if (config != null) {
+            config.override(DelegatingDebugConfig.Level.LOG, logLevel);
+            config.delegate(DelegatingDebugConfig.Feature.LOG_METHOD);
+            recursiveUpdateFlags();
+        }
+    }
+
+    private static void recursiveUpdateFlags() {
+        DebugScope c = DebugScope.getInstance();
+        while (c != null) {
+            c.updateFlags();
+            c = c.parent;
+        }
+    }
+
+    private static TopLevelDebugConfig fetchTopLevelDebugConfig(String msg) {
+        DebugConfig config = getConfig();
+        if (config instanceof TopLevelDebugConfig) {
+            return (TopLevelDebugConfig) config;
+        } else {
+            if (config == null) {
+                TTY.println("DebugScope.%s ignored because debugging is disabled", msg);
+            } else {
+                TTY.println("DebugScope.%s ignored because top level delegate config missing", msg);
+            }
+            return null;
+        }
+    }
+
+    public boolean isVerifyEnabled() {
+        return verifyEnabled;
+    }
+
+    public boolean isLogEnabled(int logLevel) {
+        assert logLevel > 0;
+        return currentLogLevel >= logLevel;
+    }
+
+    public boolean isMeterEnabled() {
+        return meterEnabled;
+    }
+
+    public boolean isTimeEnabled() {
+        return timeEnabled;
+    }
+
+    public boolean isMemUseTrackingEnabled() {
+        return memUseTrackingEnabled;
+    }
+
+    public void log(int logLevel, String msg, Object... args) {
+        if (isLogEnabled(logLevel)) {
+            getLastUsedIndent().log(logLevel, msg, args);
+        }
+    }
+
+    public void dump(int dumpLevel, Object object, String formatString, Object... args) {
+        if (isDumpEnabled(dumpLevel)) {
+            DebugConfig config = getConfig();
+            if (config != null) {
+                String message = String.format(formatString, args);
+                for (DebugDumpHandler dumpHandler : config.dumpHandlers()) {
+                    dumpHandler.dump(object, message);
+                }
+            }
+        }
+    }
+
+    /**
+     * This method exists mainly to allow a debugger (e.g., Eclipse) to force dump a graph.
+     */
+    public static void forceDump(Object object, String format, Object... args) {
+        DebugConfig config = getConfig();
+        if (config != null) {
+            String message = String.format(format, args);
+            for (DebugDumpHandler dumpHandler : config.dumpHandlers()) {
+                dumpHandler.dump(object, message);
+            }
+        } else {
+            TTY.println("Forced dump ignored because debugging is disabled - use -G:Dump=xxx option");
+        }
+    }
+
+    /**
+     * @see Debug#verify(Object, String)
+     */
+    public void verify(Object object, String formatString, Object... args) {
+        if (isVerifyEnabled()) {
+            DebugConfig config = getConfig();
+            if (config != null) {
+                String message = String.format(formatString, args);
+                for (DebugVerifyHandler handler : config.verifyHandlers()) {
+                    handler.verify(object, message);
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates and enters a new debug scope which is either a child of the current scope or a
+     * disjoint top level scope.
+     *
+     * @param name the name of the new scope
+     * @param sandboxConfig the configuration to use for a new top level scope, or null if the new
+     *            scope should be a child scope
+     * @param newContextObjects objects to be appended to the debug context
+     * @return the new scope which will be exited when its {@link #close()} method is called
+     */
+    public DebugScope scope(CharSequence name, DebugConfig sandboxConfig, Object... newContextObjects) {
+        DebugScope newScope = null;
+        if (sandboxConfig != null) {
+            newScope = new DebugScope(name.toString(), this, true, newContextObjects);
+            configTL.set(sandboxConfig);
+        } else {
+            newScope = this.createChild(name.toString(), newContextObjects);
+        }
+        instanceTL.set(newScope);
+        newScope.updateFlags();
+        return newScope;
+    }
+
+    public RuntimeException handle(Throwable e) {
+        DebugScope lastClosed = lastClosedTL.get();
+        assert lastClosed.parent == this : "Debug.handle() used with no matching Debug.scope(...) or Debug.sandbox(...)";
+        if (e != lastExceptionThrownTL.get()) {
+            RuntimeException newException = null;
+            instanceTL.set(lastClosed);
+            try (DebugScope s = lastClosed) {
+                newException = s.interceptException(e);
+            }
+            assert instanceTL.get() == this;
+            assert lastClosed == lastClosedTL.get();
+            if (newException == null) {
+                lastExceptionThrownTL.set(e);
+            } else {
+                lastExceptionThrownTL.set(newException);
+                throw newException;
+            }
+        }
+        if (e instanceof Error) {
+            throw (Error) e;
+        }
+        if (e instanceof RuntimeException) {
+            throw (RuntimeException) e;
+        }
+        throw new RuntimeException(e);
+    }
+
+    private void updateFlags() {
+        DebugConfig config = getConfig();
+        if (config == null) {
+            meterEnabled = false;
+            memUseTrackingEnabled = false;
+            timeEnabled = false;
+            verifyEnabled = false;
+
+            currentDumpLevel = 0;
+
+            // Be pragmatic: provide a default log stream to prevent a crash if the stream is not
+            // set while logging
+            output = TTY.out;
+        } else {
+            meterEnabled = config.isMeterEnabled();
+            memUseTrackingEnabled = config.isMemUseTrackingEnabled();
+            timeEnabled = config.isTimeEnabled();
+            verifyEnabled = config.isVerifyEnabled();
+            output = config.output();
+            currentDumpLevel = config.getDumpLevel();
+            currentLogLevel = config.getLogLevel();
+        }
+    }
+
+    private RuntimeException interceptException(final Throwable e) {
+        final DebugConfig config = getConfig();
+        if (config != null) {
+            try (DebugScope s = scope("InterceptException", null, e)) {
+                return config.interceptException(e);
+            } catch (Throwable t) {
+                return new RuntimeException("Exception while intercepting exception", t);
+            }
+        }
+        return null;
+    }
+
+    private DebugValueMap getValueMap() {
+        if (valueMap == null) {
+            computeValueMap(unqualifiedName);
+        }
+        return valueMap;
+    }
+
+    long getCurrentValue(int index) {
+        return getValueMap().getCurrentValue(index);
+    }
+
+    void setCurrentValue(int index, long l) {
+        getValueMap().setCurrentValue(index, l);
+    }
+
+    private DebugScope createChild(String newName, Object[] newContext) {
+        return new DebugScope(newName, this, false, newContext);
+    }
+
+    public Iterable<Object> getCurrentContext() {
+        final DebugScope scope = this;
+        return new Iterable<Object>() {
+
+            @Override
+            public Iterator<Object> iterator() {
+                return new Iterator<Object>() {
+
+                    DebugScope currentScope = scope;
+                    int objectIndex;
+
+                    @Override
+                    public boolean hasNext() {
+                        selectScope();
+                        return currentScope != null;
+                    }
+
+                    private void selectScope() {
+                        while (currentScope != null && currentScope.context.length <= objectIndex) {
+                            currentScope = currentScope.sandbox ? null : currentScope.parent;
+                            objectIndex = 0;
+                        }
+                    }
+
+                    @Override
+                    public Object next() {
+                        selectScope();
+                        if (currentScope != null) {
+                            return currentScope.context[objectIndex++];
+                        }
+                        throw new IllegalStateException("May only be called if there is a next element.");
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException("This iterator is read only.");
+                    }
+                };
+            }
+        };
+    }
+
+    public static <T> T call(Callable<T> callable) {
+        try {
+            return callable.call();
+        } catch (Exception e) {
+            if (e instanceof RuntimeException) {
+                throw (RuntimeException) e;
+            } else {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public void setConfig(DebugConfig newConfig) {
+        configTL.set(newConfig);
+        updateFlags();
+    }
+
+    public String getQualifiedName() {
+        if (qualifiedName == null) {
+            if (parent == null) {
+                qualifiedName = unqualifiedName;
+            } else {
+                qualifiedName = parent.getQualifiedName() + SCOPE_SEP + unqualifiedName;
+            }
+        }
+        return qualifiedName;
+    }
+
+    public Indent pushIndentLogger() {
+        lastUsedIndent = getLastUsedIndent().indent();
+        return lastUsedIndent;
+    }
+
+    public IndentImpl getLastUsedIndent() {
+        if (lastUsedIndent == null) {
+            if (parent != null) {
+                lastUsedIndent = new IndentImpl(parent.getLastUsedIndent());
+            } else {
+                lastUsedIndent = new IndentImpl(null);
+            }
+        }
+        return lastUsedIndent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValue.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+/**
+ * A name and index for a value managed in a thread local value map. All access to the value is made
+ * via a {@link DebugValue} instance.
+ */
+public abstract class DebugValue implements Comparable<DebugValue> {
+
+    private final String name;
+    private int index;
+    private boolean conditional;
+
+    protected DebugValue(String name, boolean conditional) {
+        this.name = name;
+        this.index = -1;
+        this.conditional = conditional;
+    }
+
+    public long getCurrentValue() {
+        ensureInitialized();
+        return DebugScope.getInstance().getCurrentValue(index);
+    }
+
+    protected void setCurrentValue(long l) {
+        ensureInitialized();
+        DebugScope.getInstance().setCurrentValue(index, l);
+    }
+
+    public void setConditional(boolean flag) {
+        conditional = flag;
+    }
+
+    public boolean isConditional() {
+        return conditional;
+    }
+
+    private void ensureInitialized() {
+        if (index == -1) {
+            index = KeyRegistry.register(this);
+        }
+    }
+
+    protected void addToCurrentValue(long value) {
+        setCurrentValue(getCurrentValue() + value);
+    }
+
+    /**
+     * Gets the globally unique index for the value represented by this object.
+     */
+    public int getIndex() {
+        ensureInitialized();
+        return index;
+    }
+
+    /**
+     * Gets the globally unique name for the value represented by this object.
+     */
+    public String getName() {
+        return name;
+    }
+
+    public int compareTo(DebugValue o) {
+        return name.compareTo(o.name);
+    }
+
+    @Override
+    public String toString() {
+        return name + "@" + index;
+    }
+
+    public abstract String toString(long value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugValueMap.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import java.util.*;
+
+/**
+ * A node in a tree of {@link DebugValue}s.
+ */
+public class DebugValueMap {
+
+    private static final List<DebugValueMap> topLevelMaps = new ArrayList<>();
+
+    private long[] values;
+    private List<DebugValueMap> children;
+    private String name;
+
+    public DebugValueMap(String name) {
+        this.name = name;
+    }
+
+    public void setCurrentValue(int index, long l) {
+        ensureSize(index);
+        values[index] = l;
+    }
+
+    public long getCurrentValue(int index) {
+        ensureSize(index);
+        return values[index];
+    }
+
+    public void clearChildren() {
+        if (children != null) {
+            children.clear();
+        }
+    }
+
+    public void reset() {
+        if (values != null) {
+            Arrays.fill(values, 0L);
+        }
+        if (children != null) {
+            for (DebugValueMap child : children) {
+                child.reset();
+            }
+        }
+    }
+
+    private void ensureSize(int index) {
+        if (values == null) {
+            values = new long[index + 1];
+        }
+        if (values.length <= index) {
+            values = Arrays.copyOf(values, index + 1);
+        }
+    }
+
+    private int capacity() {
+        return (values == null) ? 0 : values.length;
+    }
+
+    public void addChild(DebugValueMap map) {
+        if (children == null) {
+            children = new ArrayList<>(4);
+        }
+        children.add(map);
+    }
+
+    public List<DebugValueMap> getChildren() {
+        if (children == null) {
+            return Collections.emptyList();
+        } else {
+            return Collections.unmodifiableList(children);
+        }
+    }
+
+    public boolean hasChildren() {
+        return children != null && !children.isEmpty();
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public String toString() {
+        return "DebugValueMap<" + getName() + ">";
+    }
+
+    public static synchronized void registerTopLevel(DebugValueMap map) {
+        topLevelMaps.add(map);
+    }
+
+    public static synchronized List<DebugValueMap> getTopLevelMaps() {
+        return topLevelMaps;
+    }
+
+    public void normalize() {
+        if (hasChildren()) {
+            Map<String, DebugValueMap> occurred = new HashMap<>();
+            for (DebugValueMap map : children) {
+                String mapName = map.getName();
+                if (!occurred.containsKey(mapName)) {
+                    occurred.put(mapName, map);
+                    map.normalize();
+                } else {
+                    occurred.get(mapName).mergeWith(map);
+                    occurred.get(mapName).normalize();
+                }
+            }
+
+            if (occurred.values().size() < children.size()) {
+                // At least one duplicate was found.
+                children.clear();
+                for (DebugValueMap map : occurred.values()) {
+                    addChild(map);
+                    map.normalize();
+                }
+            }
+        }
+    }
+
+    private void mergeWith(DebugValueMap map) {
+        if (map.hasChildren()) {
+            if (hasChildren()) {
+                children.addAll(map.children);
+            } else {
+                children = map.children;
+            }
+            map.children = null;
+        }
+
+        int size = Math.max(this.capacity(), map.capacity());
+        ensureSize(size);
+        for (int i = 0; i < size; ++i) {
+            long curValue = getCurrentValue(i);
+            long otherValue = map.getCurrentValue(i);
+            setCurrentValue(i, curValue + otherValue);
+        }
+    }
+
+    public void group() {
+        if (this.hasChildren()) {
+            List<DebugValueMap> oldChildren = new ArrayList<>(this.children);
+            this.children.clear();
+            for (DebugValueMap map : oldChildren) {
+                mergeWith(map);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/KeyRegistry.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import java.util.*;
+
+/**
+ * Registry for allocating a globally unique integer id to each {@link DebugValue}.
+ */
+public class KeyRegistry {
+
+    private static final Map<String, Integer> keyMap = new HashMap<>();
+    private static final List<DebugValue> debugValues = new ArrayList<>();
+
+    /**
+     * Ensures a given debug value is registered.
+     *
+     * @return the globally unique id for {@code value}
+     */
+    public static synchronized int register(DebugValue value) {
+        String name = value.getName();
+        if (!keyMap.containsKey(name)) {
+            keyMap.put(name, debugValues.size());
+            debugValues.add(value);
+        }
+        return keyMap.get(name);
+    }
+
+    /**
+     * Gets a immutable view of the registered debug values.
+     *
+     * @return a list where {@code get(i).getIndex() == i}
+     */
+    public static synchronized List<DebugValue> getDebugValues() {
+        return Collections.unmodifiableList(debugValues);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import static com.oracle.graal.debug.DebugCloseable.*;
+import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
+public final class MemUseTrackerImpl extends AccumulatedDebugValue implements DebugMemUseTracker {
+
+    public static long getCurrentThreadAllocatedBytes() {
+        return Management.getCurrentThreadAllocatedBytes();
+    }
+
+    /**
+     * Records the most recent active tracker.
+     */
+    private static final ThreadLocal<CloseableCounterImpl> currentTracker = new ThreadLocal<>();
+
+    public MemUseTrackerImpl(String name, boolean conditional) {
+        super(name, conditional, new DebugValue(name + "_Flat", conditional) {
+
+            @Override
+            public String toString(long value) {
+                return valueToString(value);
+            }
+        });
+    }
+
+    @Override
+    public DebugCloseable start() {
+        if (!isConditional() || Debug.isMemUseTrackingEnabled()) {
+            MemUseCloseableCounterImpl result = new MemUseCloseableCounterImpl(this);
+            currentTracker.set(result);
+            return result;
+        } else {
+            return VOID_CLOSEABLE;
+        }
+    }
+
+    public static String valueToString(long value) {
+        return String.format("%d bytes", value);
+    }
+
+    @Override
+    public String toString(long value) {
+        return valueToString(value);
+    }
+
+    private static final class MemUseCloseableCounterImpl extends CloseableCounterImpl implements DebugCloseable {
+
+        private MemUseCloseableCounterImpl(AccumulatedDebugValue counter) {
+            super(currentTracker.get(), counter);
+        }
+
+        @Override
+        long getCounterValue() {
+            return getCurrentThreadAllocatedBytes();
+        }
+
+        @Override
+        public void close() {
+            super.close();
+            currentTracker.set(parent);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import com.oracle.graal.debug.*;
+
+public final class MetricImpl extends DebugValue implements DebugMetric {
+
+    public MetricImpl(String name, boolean conditional) {
+        super(name, conditional);
+        if (isEnabled()) {
+            // Allows for zero-count metrics to be shown
+            getCurrentValue();
+        }
+    }
+
+    public void increment() {
+        add(1);
+    }
+
+    public void add(long value) {
+        if (isEnabled()) {
+            super.addToCurrentValue(value);
+        }
+    }
+
+    @Override
+    public String toString(long value) {
+        return Long.toString(value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/TimerImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import static com.oracle.graal.debug.DebugCloseable.*;
+
+import java.lang.management.*;
+import java.util.concurrent.*;
+
+import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
+public final class TimerImpl extends AccumulatedDebugValue implements DebugTimer {
+
+    private static final ThreadMXBean threadMXBean = Management.getThreadMXBean();
+
+    /**
+     * Records the most recent active timer.
+     */
+    private static final ThreadLocal<CloseableCounterImpl> currentTimer = new ThreadLocal<>();
+
+    static class FlatTimer extends DebugValue implements DebugTimer {
+        private TimerImpl accm;
+
+        public FlatTimer(String name, boolean conditional) {
+            super(name + "_Flat", conditional);
+        }
+
+        @Override
+        public String toString(long value) {
+            return valueToString(value);
+        }
+
+        public TimeUnit getTimeUnit() {
+            return accm.getTimeUnit();
+        }
+
+        public DebugCloseable start() {
+            return accm.start();
+        }
+    }
+
+    public TimerImpl(String name, boolean conditional) {
+        super(name, conditional, new FlatTimer(name, conditional));
+        ((FlatTimer) flat).accm = this;
+    }
+
+    @Override
+    public DebugCloseable start() {
+        if (!isConditional() || Debug.isTimeEnabled()) {
+            AbstractTimer result;
+            if (threadMXBean.isCurrentThreadCpuTimeSupported()) {
+                result = new CpuTimeTimer(this);
+            } else {
+                result = new SystemNanosTimer(this);
+            }
+            currentTimer.set(result);
+            return result;
+        } else {
+            return VOID_CLOSEABLE;
+        }
+    }
+
+    public static String valueToString(long value) {
+        return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10);
+    }
+
+    public DebugTimer getFlat() {
+        return (FlatTimer) flat;
+    }
+
+    @Override
+    public String toString(long value) {
+        return valueToString(value);
+    }
+
+    public TimeUnit getTimeUnit() {
+        return TimeUnit.NANOSECONDS;
+    }
+
+    private abstract static class AbstractTimer extends CloseableCounterImpl implements DebugCloseable {
+
+        private AbstractTimer(AccumulatedDebugValue counter) {
+            super(currentTimer.get(), counter);
+        }
+
+        @Override
+        public void close() {
+            super.close();
+            currentTimer.set(parent);
+        }
+    }
+
+    private final class SystemNanosTimer extends AbstractTimer {
+
+        public SystemNanosTimer(TimerImpl timer) {
+            super(timer);
+        }
+
+        @Override
+        protected long getCounterValue() {
+            return System.nanoTime();
+        }
+    }
+
+    private final class CpuTimeTimer extends AbstractTimer {
+
+        public CpuTimeTimer(TimerImpl timer) {
+            super(timer);
+        }
+
+        @Override
+        protected long getCounterValue() {
+            return threadMXBean.getCurrentThreadCpuTime();
+        }
+    }
+}
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 import java.util.function.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.compiler.common.*;
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,7 +30,7 @@
 import java.util.function.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import sun.misc.*;
 
 import com.oracle.graal.compiler.common.*;
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Fri Jul 24 08:33:42 2015 +0200
@@ -34,7 +34,7 @@
 import java.util.concurrent.atomic.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.Edges.Type;
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ForeignCallPlugin.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/ForeignCallPlugin.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.graphbuilderconf;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,7 +31,7 @@
 import com.oracle.graal.lir.asm.*;
 
 @Opcode("DEOPT")
-final class AMD64DeoptimizeOp extends AMD64LIRInstruction implements BlockEndOp {
+final class AMD64DeoptimizeOp extends AMD64BlockEndOp implements BlockEndOp {
     public static final LIRInstructionClass<AMD64DeoptimizeOp> TYPE = LIRInstructionClass.create(AMD64DeoptimizeOp.class);
 
     @State private LIRFrameState info;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,19 +23,19 @@
 package com.oracle.graal.hotspot.amd64;
 
 import static com.oracle.graal.hotspot.HotSpotHostBackend.*;
-import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 
+import jdk.internal.jvmci.meta.*;
+
 /**
  * Removes the current frame and tail calls the uncommon trap routine.
  */
 @Opcode("DEOPT_CALLER")
-final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueBlockEndOp {
 
     public static final LIRInstructionClass<AMD64HotSpotDeoptimizeCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotDeoptimizeCallerOp.class);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueBlockEndOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, 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.hotspot.amd64;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.amd64.*;
+import com.oracle.graal.lir.asm.*;
+
+import jdk.internal.jvmci.meta.*;
+
+/**
+ * @see AMD64HotSpotEpilogueOp
+ */
+abstract class AMD64HotSpotEpilogueBlockEndOp extends AMD64BlockEndOp {
+
+    protected AMD64HotSpotEpilogueBlockEndOp(LIRInstructionClass<? extends AMD64HotSpotEpilogueBlockEndOp> c, AllocatableValue savedRbp) {
+        super(c);
+        this.savedRbp = savedRbp;
+    }
+
+    @Use({REG, STACK}) private AllocatableValue savedRbp;
+
+    protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        AMD64HotSpotEpilogueOp.leaveFrameAndRestoreRbp(savedRbp, crb, masm);
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -46,6 +46,10 @@
     @Use({REG, STACK}) private AllocatableValue savedRbp;
 
     protected void leaveFrameAndRestoreRbp(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+        leaveFrameAndRestoreRbp(savedRbp, crb, masm);
+    }
+
+    static void leaveFrameAndRestoreRbp(AllocatableValue savedRbp, CompilationResultBuilder crb, AMD64MacroAssembler masm) {
         if (isStackSlot(savedRbp)) {
             // Restoring RBP from the stack must be done before the frame is removed
             masm.movq(rbp, (AMD64Address) crb.asAddress(savedRbp));
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.hotspot.amd64;
 
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static jdk.internal.jvmci.amd64.AMD64.*;
 import static jdk.internal.jvmci.code.ValueUtil.*;
@@ -31,15 +29,17 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.amd64.AMD64Assembler.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.meta.*;
+
 /**
  * Sets up the arguments for an exception handler in the callers frame, removes the current frame
  * and jumps to the handler.
  */
 @Opcode("JUMP_TO_EXCEPTION_HANDLER_IN_CALLER")
-final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotJumpToExceptionHandlerInCallerOp extends AMD64HotSpotEpilogueBlockEndOp {
 
     public static final LIRInstructionClass<AMD64HotSpotJumpToExceptionHandlerInCallerOp> TYPE = LIRInstructionClass.create(AMD64HotSpotJumpToExceptionHandlerInCallerOp.class);
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Jul 24 08:33:42 2015 +0200
@@ -33,7 +33,7 @@
 import jdk.internal.jvmci.amd64.*;
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.hotspot.HotSpotVMConfig.*;
 import jdk.internal.jvmci.meta.*;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,6 +26,7 @@
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,6 +27,7 @@
 import static jdk.internal.jvmci.code.ValueUtil.*;
 
 import com.oracle.graal.compiler.amd64.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.nodes.*;
@@ -39,7 +40,9 @@
 
 import jdk.internal.jvmci.amd64.*;
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
@@ -89,6 +92,8 @@
 
         getGen().emitSaveRbp();
 
+        getGen().append(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack());
+
         for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
             Value paramValue = params[param.index()];
             assert paramValue.getLIRKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp()));
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,20 +23,20 @@
 package com.oracle.graal.hotspot.amd64;
 
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
-import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
-import com.oracle.graal.lir.asm.*;
-
 /**
  * Returns from a function.
  */
 @Opcode("RETURN")
-final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueBlockEndOp {
 
     public static final LIRInstructionClass<AMD64HotSpotReturnOp> TYPE = LIRInstructionClass.create(AMD64HotSpotReturnOp.class);
     @Use({REG, ILLEGAL}) protected Value value;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,21 +26,21 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static jdk.internal.jvmci.amd64.AMD64.*;
 import static jdk.internal.jvmci.code.ValueUtil.*;
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.meta.*;
 
 /**
  * Removes the current frame and jumps to the {@link UnwindExceptionToCallerStub}.
  */
 @Opcode("UNWIND")
-final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueOp implements BlockEndOp {
+final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueBlockEndOp {
     public static final LIRInstructionClass<AMD64HotSpotUnwindOp> TYPE = LIRInstructionClass.create(AMD64HotSpotUnwindOp.class);
 
     @Use({REG}) protected RegisterValue exception;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,12 +28,11 @@
 
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
 
 @Opcode("DEOPT")
-final class SPARCDeoptimizeOp extends SPARCLIRInstruction implements BlockEndOp {
+final class SPARCDeoptimizeOp extends SPARCBlockEndOp {
     public static final LIRInstructionClass<SPARCDeoptimizeOp> TYPE = LIRInstructionClass.create(SPARCDeoptimizeOp.class);
     public static final SizeEstimate SIZE = SizeEstimate.create(1);
     @Temp AllocatableValue pcRegister;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Jul 24 08:33:42 2015 +0200
@@ -37,7 +37,7 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.DataSection.Data;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEpilogueOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,17 +23,16 @@
 package com.oracle.graal.hotspot.sparc;
 
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
 
 /**
  * Superclass for operations that leave a method's frame.
  */
-abstract class SPARCHotSpotEpilogueOp extends SPARCLIRInstruction implements BlockEndOp {
+abstract class SPARCHotSpotEpilogueOp extends SPARCBlockEndOp {
     public static final LIRInstructionClass<SPARCHotSpotEpilogueOp> TYPE = LIRInstructionClass.create(SPARCHotSpotEpilogueOp.class);
 
-    protected SPARCHotSpotEpilogueOp(LIRInstructionClass<? extends LIRInstruction> c, SizeEstimate size) {
+    protected SPARCHotSpotEpilogueOp(LIRInstructionClass<? extends SPARCHotSpotEpilogueOp> c, SizeEstimate size) {
         super(c, size);
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,6 +25,7 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
 import static jdk.internal.jvmci.sparc.SPARC.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.sparc.*;
 import com.oracle.graal.hotspot.*;
@@ -37,7 +38,9 @@
 import com.oracle.graal.nodes.spi.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
@@ -137,6 +140,7 @@
         super.emitPrologue(graph);
         AllocatableValue var = getGen().getSafepointAddressValue();
         append(new SPARCHotSpotSafepointOp.SPARCLoadSafepointPollAddress(var, getGen().config));
+        getGen().append(((HotSpotDebugInfoBuilder) getDebugInfoBuilder()).lockStack());
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,6 +29,7 @@
 import static jdk.internal.jvmci.sparc.SPARC.*;
 
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ClassSubstitutionsTests.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ClassSubstitutionsTests.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,8 +23,8 @@
 
 package com.oracle.graal.hotspot.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,12 +23,12 @@
 package com.oracle.graal.hotspot.test;
 
 import static jdk.internal.jvmci.compiler.Compiler.*;
-import jdk.internal.jvmci.hotspot.*;
-import jdk.internal.jvmci.hotspot.CompileTheWorld.*;
 
 import org.junit.*;
 
 import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.CompileTheWorld.Config;
 
 /**
  * Tests {@link CompileTheWorld} functionality.
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ConstantPoolSubstitutionsTests.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ConstantPoolSubstitutionsTests.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,8 +30,8 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import sun.misc.*;
 import sun.reflect.*;
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ForeignCallDeoptimizeTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ForeignCallDeoptimizeTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,12 +22,11 @@
  */
 package com.oracle.graal.hotspot.test;
 
-import jdk.internal.jvmci.meta.*;
-
 import org.junit.*;
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,16 +22,14 @@
  */
 package com.oracle.graal.hotspot.test;
 
-import static jdk.internal.jvmci.debug.internal.MemUseTrackerImpl.*;
-import static jdk.internal.jvmci.hotspot.CompileTheWorld.*;
-import static jdk.internal.jvmci.hotspot.CompileTheWorld.Options.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.internal.*;
+import static com.oracle.graal.debug.internal.MemUseTrackerImpl.*;
 import jdk.internal.jvmci.hotspot.*;
-import jdk.internal.jvmci.hotspot.CompileTheWorld.Config;
 
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
 
 /**
@@ -173,9 +171,8 @@
     public void run() {
         compileAndTime("simple");
         compileAndTime("complex");
-        if (CompileTheWorldClasspath.getValue() != SUN_BOOT_CLASS_PATH) {
-            CompileTheWorld ctw = new CompileTheWorld(CompileTheWorldClasspath.getValue(), new Config(CompileTheWorldConfig.getValue()), CompileTheWorldStartAt.getValue(),
-                            CompileTheWorldStopAt.getValue(), CompileTheWorldMethodFilter.getValue(), CompileTheWorldExcludeMethodFilter.getValue(), CompileTheWorldVerbose.getValue());
+        if (CompileTheWorld.Options.CompileTheWorldClasspath.getValue() != CompileTheWorld.SUN_BOOT_CLASS_PATH) {
+            CompileTheWorld ctw = new CompileTheWorld();
             try {
                 ctw.compile();
             } catch (Throwable e) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,8 +26,8 @@
 
 import java.lang.ref.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,9 +24,9 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
-import jdk.internal.jvmci.debug.internal.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
+import com.oracle.graal.debug.internal.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot;
+
+import static java.lang.Thread.*;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import jdk.internal.jvmci.debug.*;
+import jdk.internal.jvmci.hotspot.*;
+
+import com.sun.management.*;
+
+@SuppressWarnings("unused")
+public final class CompilationStatistics {
+
+    private static final long RESOLUTION = 100000000;
+    private static final boolean ENABLED = Boolean.getBoolean("jvmci.comp.stats");
+
+    private static final CompilationStatistics DUMMY = new CompilationStatistics(null, false);
+
+    private static ConcurrentLinkedDeque<CompilationStatistics> list = new ConcurrentLinkedDeque<>();
+
+    private static final ThreadLocal<Deque<CompilationStatistics>> current = new ThreadLocal<Deque<CompilationStatistics>>() {
+
+        @Override
+        protected Deque<CompilationStatistics> initialValue() {
+            return new ArrayDeque<>();
+        }
+    };
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    private static @interface NotReported {
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    private static @interface TimeValue {
+    }
+
+    private static long zeroTime = System.nanoTime();
+
+    private static long getThreadAllocatedBytes() {
+        ThreadMXBean thread = (ThreadMXBean) Management.getThreadMXBean();
+        return thread.getThreadAllocatedBytes(currentThread().getId());
+    }
+
+    @NotReported private final long startTime;
+    @NotReported private long threadAllocatedBytesStart;
+
+    private int bytecodeCount;
+    private int codeSize;
+    @TimeValue private long duration;
+    private long memoryUsed;
+    private final boolean osr;
+    private final String holder;
+    private final String name;
+    private final String signature;
+
+    private CompilationStatistics(HotSpotResolvedJavaMethod method, boolean osr) {
+        this.osr = osr;
+        if (method != null) {
+            holder = method.getDeclaringClass().getName();
+            name = method.getName();
+            signature = method.getSignature().toMethodDescriptor();
+            startTime = System.nanoTime();
+            bytecodeCount = method.getCodeSize();
+            threadAllocatedBytesStart = getThreadAllocatedBytes();
+        } else {
+            holder = "";
+            name = "";
+            signature = "";
+            startTime = 0;
+        }
+    }
+
+    public void finish(HotSpotResolvedJavaMethod method, HotSpotInstalledCode code) {
+        if (ENABLED) {
+            duration = System.nanoTime() - startTime;
+            codeSize = (int) code.getCodeSize();
+            memoryUsed = getThreadAllocatedBytes() - threadAllocatedBytesStart;
+            if (current.get().getLast() != this) {
+                throw new RuntimeException("mismatch in finish()");
+            }
+            current.get().removeLast();
+        }
+    }
+
+    public static CompilationStatistics current() {
+        return current.get().isEmpty() ? null : current.get().getLast();
+    }
+
+    public static CompilationStatistics create(HotSpotResolvedJavaMethod method, boolean isOSR) {
+        if (ENABLED) {
+            CompilationStatistics stats = new CompilationStatistics(method, isOSR);
+            list.add(stats);
+            current.get().addLast(stats);
+            return stats;
+        } else {
+            return DUMMY;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public static void clear(String dumpName) {
+        if (!ENABLED) {
+            return;
+        }
+        try {
+            ConcurrentLinkedDeque<CompilationStatistics> snapshot = list;
+            long snapshotZeroTime = zeroTime;
+
+            list = new ConcurrentLinkedDeque<>();
+            zeroTime = System.nanoTime();
+
+            Date now = new Date();
+            String dateString = (now.getYear() + 1900) + "-" + (now.getMonth() + 1) + "-" + now.getDate() + "-" + now.getHours() + "" + now.getMinutes();
+
+            dumpCompilations(snapshot, dumpName, dateString);
+
+            try (FileOutputStream fos = new FileOutputStream("timeline_" + dateString + "_" + dumpName + ".csv", true); PrintStream out = new PrintStream(fos)) {
+
+                long[] timeSpent = new long[10000];
+                int maxTick = 0;
+                for (CompilationStatistics stats : snapshot) {
+                    long start = stats.startTime - snapshotZeroTime;
+                    long duration = stats.duration;
+                    if (start < 0) {
+                        duration -= -start;
+                        start = 0;
+                    }
+
+                    int tick = (int) (start / RESOLUTION);
+                    long timeLeft = RESOLUTION - (start % RESOLUTION);
+
+                    while (tick < timeSpent.length && duration > 0) {
+                        if (tick > maxTick) {
+                            maxTick = tick;
+                        }
+                        timeSpent[tick] += Math.min(timeLeft, duration);
+                        duration -= timeLeft;
+                        tick++;
+                        timeLeft = RESOLUTION;
+                    }
+                }
+                String timelineName = System.getProperty("stats.timeline.name");
+                if (timelineName != null && !timelineName.isEmpty()) {
+                    out.print(timelineName + "\t");
+                }
+                for (int i = 0; i <= maxTick; i++) {
+                    out.print((timeSpent[i] * 100 / RESOLUTION) + "\t");
+                }
+                out.println();
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected static void dumpCompilations(ConcurrentLinkedDeque<CompilationStatistics> snapshot, String dumpName, String dateString) throws IllegalAccessException, FileNotFoundException {
+        String fileName = "compilations_" + dateString + "_" + dumpName + ".csv";
+        try (PrintStream out = new PrintStream(fileName)) {
+            // output the list of all compilations
+
+            Field[] declaredFields = CompilationStatistics.class.getDeclaredFields();
+            ArrayList<Field> fields = new ArrayList<>();
+            for (Field field : declaredFields) {
+                if (!Modifier.isStatic(field.getModifiers()) && !field.isAnnotationPresent(NotReported.class)) {
+                    fields.add(field);
+                }
+            }
+            for (Field field : fields) {
+                out.print(field.getName() + "\t");
+            }
+            out.println();
+            for (CompilationStatistics stats : snapshot) {
+                for (Field field : fields) {
+                    if (field.isAnnotationPresent(TimeValue.class)) {
+                        double value = field.getLong(stats) / 1000000d;
+                        out.print(String.format(Locale.ENGLISH, "%.3f", value) + "\t");
+                    } else {
+                        out.print(field.get(stats) + "\t");
+                    }
+                }
+                out.println();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,303 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot;
+
+import static jdk.internal.jvmci.common.UnsafeAccess.*;
+import static jdk.internal.jvmci.compiler.Compiler.*;
+
+import java.util.concurrent.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.debug.internal.*;
+
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.compiler.Compiler;
+import jdk.internal.jvmci.debug.*;
+import jdk.internal.jvmci.hotspot.*;
+import jdk.internal.jvmci.hotspot.events.*;
+import jdk.internal.jvmci.hotspot.events.EventProvider.CompilationEvent;
+import jdk.internal.jvmci.hotspot.events.EventProvider.CompilerFailureEvent;
+import jdk.internal.jvmci.meta.*;
+import jdk.internal.jvmci.service.*;
+
+//JaCoCo Exclude
+
+public class CompilationTask {
+
+    private static final DebugMetric BAILOUTS = Debug.metric("Bailouts");
+
+    private static final EventProvider eventProvider;
+    static {
+        EventProvider provider = Services.loadSingle(EventProvider.class, false);
+        if (provider == null) {
+            eventProvider = new EmptyEventProvider();
+        } else {
+            eventProvider = provider;
+        }
+    }
+    private static final Compiler compiler = Services.loadSingle(Compiler.class, true);
+
+    private final HotSpotResolvedJavaMethod method;
+    private final int entryBCI;
+    private final int id;
+
+    /**
+     * Specifies whether the compilation result is installed as the
+     * {@linkplain HotSpotNmethod#isDefault() default} nmethod for the compiled method.
+     */
+    private final boolean installAsDefault;
+
+    static class Lazy {
+        /**
+         * A {@link com.sun.management.ThreadMXBean} to be able to query some information about the
+         * current compiler thread, e.g. total allocated bytes.
+         */
+        static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean();
+    }
+
+    /**
+     * The address of the JVMCIEnv associated with this compilation or 0L if no such object exists.
+     */
+    private final long jvmciEnv;
+
+    public CompilationTask(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id, boolean installAsDefault) {
+        this.method = method;
+        this.entryBCI = entryBCI;
+        this.id = id;
+        this.jvmciEnv = jvmciEnv;
+        this.installAsDefault = installAsDefault;
+    }
+
+    public ResolvedJavaMethod getMethod() {
+        return method;
+    }
+
+    /**
+     * Returns the compilation id of this task.
+     *
+     * @return compile id
+     */
+    public int getId() {
+        return id;
+    }
+
+    public int getEntryBCI() {
+        return entryBCI;
+    }
+
+    /**
+     * Time spent in compilation.
+     */
+    private static final DebugTimer CompilationTime = Debug.timer("CompilationTime");
+
+    /**
+     * Meters the {@linkplain CompilationResult#getBytecodeSize() bytecodes} compiled.
+     */
+    private static final DebugMetric CompiledBytecodes = Debug.metric("CompiledBytecodes");
+
+    public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation");
+
+    public void runCompilation() {
+        HotSpotVMConfig config = HotSpotJVMCIRuntime.runtime().getConfig();
+        final long threadId = Thread.currentThread().getId();
+        long startCompilationTime = System.nanoTime();
+        HotSpotInstalledCode installedCode = null;
+        final boolean isOSR = entryBCI != Compiler.INVOCATION_ENTRY_BCI;
+
+        // Log a compilation event.
+        CompilationEvent compilationEvent = eventProvider.newCompilationEvent();
+
+        // If there is already compiled code for this method on our level we simply return.
+        // JVMCI compiles are always at the highest compile level, even in non-tiered mode so we
+        // only need to check for that value.
+        if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) {
+            return;
+        }
+
+        CompilationResult result = null;
+        try (DebugCloseable a = CompilationTime.start()) {
+            CompilationStatistics stats = CompilationStatistics.create(method, isOSR);
+            final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
+            final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed();
+            if (printCompilation) {
+                TTY.println(getMethodDescription() + "...");
+            }
+
+            TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
+            final long start;
+            final long allocatedBytesBefore;
+            if (printAfterCompilation || printCompilation) {
+                start = System.currentTimeMillis();
+                allocatedBytesBefore = printAfterCompilation || printCompilation ? Lazy.threadMXBean.getThreadAllocatedBytes(threadId) : 0L;
+            } else {
+                start = 0L;
+                allocatedBytesBefore = 0L;
+            }
+
+            try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) {
+                // Begin the compilation event.
+                compilationEvent.begin();
+
+                result = compiler.compile(method, entryBCI, mustRecordMethodInlining(config));
+
+                result.setId(getId());
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            } finally {
+                // End the compilation event.
+                compilationEvent.end();
+
+                filter.remove();
+
+                if (printAfterCompilation || printCompilation) {
+                    final long stop = System.currentTimeMillis();
+                    final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1;
+                    final long allocatedBytesAfter = Lazy.threadMXBean.getThreadAllocatedBytes(threadId);
+                    final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024;
+
+                    if (printAfterCompilation) {
+                        TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes));
+                    } else if (printCompilation) {
+                        TTY.println(String.format("%-6d JVMCI %-70s %-45s %-50s | %4dms %5dB %5dkB", id, "", "", "", stop - start, targetCodeSize, allocatedBytes));
+                    }
+                }
+            }
+
+            try (DebugCloseable b = CodeInstallationTime.start()) {
+                installedCode = (HotSpotInstalledCode) installMethod(result);
+            }
+            stats.finish(method, installedCode);
+        } catch (BailoutException bailout) {
+            BAILOUTS.increment();
+            if (ExitVMOnBailout.getValue()) {
+                TTY.out.println(method.format("Bailout in %H.%n(%p)"));
+                bailout.printStackTrace(TTY.out);
+                System.exit(-1);
+            } else if (PrintBailout.getValue()) {
+                TTY.out.println(method.format("Bailout in %H.%n(%p)"));
+                bailout.printStackTrace(TTY.out);
+            }
+        } catch (Throwable t) {
+            if (PrintStackTraceOnException.getValue() || ExitVMOnException.getValue()) {
+                t.printStackTrace(TTY.out);
+            }
+
+            // Log a failure event.
+            CompilerFailureEvent event = eventProvider.newCompilerFailureEvent();
+            if (event.shouldWrite()) {
+                event.setCompileId(getId());
+                event.setMessage(t.getMessage());
+                event.commit();
+            }
+
+            if (ExitVMOnException.getValue()) {
+                System.exit(-1);
+            }
+        } finally {
+            int compiledBytecodes = 0;
+            int codeSize = 0;
+            if (result != null) {
+                compiledBytecodes = result.getBytecodeSize();
+            }
+            if (installedCode != null) {
+                codeSize = installedCode.getSize();
+            }
+            CompiledBytecodes.add(compiledBytecodes);
+
+            // Log a compilation event.
+            if (compilationEvent.shouldWrite()) {
+                compilationEvent.setMethod(method.format("%H.%n(%p)"));
+                compilationEvent.setCompileId(getId());
+                compilationEvent.setCompileLevel(config.compilationLevelFullOptimization);
+                compilationEvent.setSucceeded(result != null && installedCode != null);
+                compilationEvent.setIsOsr(isOSR);
+                compilationEvent.setCodeSize(codeSize);
+                compilationEvent.setInlinedBytes(compiledBytecodes);
+                compilationEvent.commit();
+            }
+
+            if (jvmciEnv != 0) {
+                long ctask = unsafe.getAddress(jvmciEnv + config.jvmciEnvTaskOffset);
+                assert ctask != 0L;
+                unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, compiledBytecodes);
+            }
+            long compilationTime = System.nanoTime() - startCompilationTime;
+            if ((config.ciTime || config.ciTimeEach) && installedCode != null) {
+                long timeUnitsPerSecond = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
+                CompilerToVM c2vm = HotSpotJVMCIRuntime.runtime().getCompilerToVM();
+                c2vm.notifyCompilationStatistics(id, method, entryBCI != Compiler.INVOCATION_ENTRY_BCI, compiledBytecodes, compilationTime, timeUnitsPerSecond, installedCode);
+            }
+        }
+    }
+
+    /**
+     * Determines whether to disable method inlining recording for the method being compiled.
+     */
+    private boolean mustRecordMethodInlining(HotSpotVMConfig config) {
+        if (config.ciTime || config.ciTimeEach || CompiledBytecodes.isEnabled()) {
+            return true;
+        }
+        if (jvmciEnv == 0 || unsafe.getByte(jvmciEnv + config.jvmciEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0) {
+            return true;
+        }
+        return false;
+    }
+
+    private String getMethodDescription() {
+        return String.format("%-6d JVMCI %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().toMethodDescriptor(),
+                        entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") ");
+    }
+
+    private InstalledCode installMethod(final CompilationResult compResult) {
+        final HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getCodeCache();
+        InstalledCode installedCode = null;
+        try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) {
+            installedCode = codeCache.installMethod(method, compResult, jvmciEnv, installAsDefault);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+        return installedCode;
+    }
+
+    @Override
+    public String toString() {
+        return "Compilation[id=" + id + ", " + method.format("%H.%n(%p)") + (entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "@" + entryBCI) + "]";
+    }
+
+    /**
+     * Compiles a method to machine code.
+     */
+    public static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
+        // Ensure a debug configuration for this thread is initialized
+        if (Debug.isEnabled() && DebugScope.getConfig() == null) {
+            DebugEnvironment.initialize(TTY.out);
+        }
+
+        CompilationTask task = new CompilationTask(method, entryBCI, jvmciEnv, id, true);
+        try (DebugConfigScope dcs = Debug.setConfig(new TopLevelDebugConfig())) {
+            task.runCompilation();
+        }
+        return;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,512 @@
+/*
+ * 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.hotspot;
+
+import static jdk.internal.jvmci.compiler.Compiler.*;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import java.util.jar.*;
+import java.util.stream.*;
+
+import jdk.internal.jvmci.compiler.Compiler;
+import jdk.internal.jvmci.debug.*;
+import jdk.internal.jvmci.hotspot.*;
+import jdk.internal.jvmci.meta.*;
+import jdk.internal.jvmci.options.*;
+import jdk.internal.jvmci.options.OptionUtils.OptionConsumer;
+import jdk.internal.jvmci.options.OptionValue.OverrideScope;
+import jdk.internal.jvmci.runtime.*;
+
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
+
+import static com.oracle.graal.hotspot.CompileTheWorld.Options.*;
+
+/**
+ * This class implements compile-the-world functionality with JVMCI.
+ */
+public final class CompileTheWorld {
+
+    /**
+     * Magic token to trigger reading files from the boot class path.
+     */
+    public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path";
+
+    public static class Options {
+        // @formatter:off
+        @Option(help = "Compile all methods in all classes on given class path", type = OptionType.Debug)
+        public static final OptionValue<String> CompileTheWorldClasspath = new OptionValue<>(SUN_BOOT_CLASS_PATH);
+        @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug)
+        public static final OptionValue<Boolean> CompileTheWorldVerbose = new OptionValue<>(true);
+        @Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug)
+        public static final OptionValue<Integer> CompileTheWorldIterations = new OptionValue<>(1);
+        @Option(help = "Only compile methods matching this filter", type = OptionType.Debug)
+        public static final OptionValue<String> CompileTheWorldMethodFilter = new OptionValue<>(null);
+        @Option(help = "Exclude methods matching this filter from compilation", type = OptionType.Debug)
+        public static final OptionValue<String> CompileTheWorldExcludeMethodFilter = new OptionValue<>(null);
+        @Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug)
+        public static final OptionValue<Integer> CompileTheWorldStartAt = new OptionValue<>(1);
+        @Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug)
+        public static final OptionValue<Integer> CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE);
+        @Option(help = "Option value overrides to use during compile the world. For example, " +
+                       "to disable inlining and partial escape analysis specify '-PartialEscapeAnalysis -Inline'. " +
+                       "The format for each option is the same as on the command line just without the '-G:' prefix.", type = OptionType.Debug)
+        public static final OptionValue<String> CompileTheWorldConfig = new OptionValue<>(null);
+
+        @Option(help = "Run CTW using as many threads as there are processors on the system", type = OptionType.Debug)
+        public static final OptionValue<Boolean> CompileTheWorldMultiThreaded = new OptionValue<>(false);
+        @Option(help = "Number of threads to use for multithreaded CTW.  Defaults to Runtime.getRuntime().availableProcessors()", type = OptionType.Debug)
+        public static final OptionValue<Integer> CompileTheWorldThreads = new OptionValue<>(0);
+        // @formatter:on
+
+        /**
+         * Overrides {@link #CompileTheWorldStartAt} and {@link #CompileTheWorldStopAt} from
+         * {@code -XX} HotSpot options of the same name if the latter have non-default values.
+         */
+        public static void overrideWithNativeOptions(HotSpotVMConfig c) {
+            if (c.compileTheWorldStartAt != 1) {
+                CompileTheWorldStartAt.setValue(c.compileTheWorldStartAt);
+            }
+            if (c.compileTheWorldStopAt != Integer.MAX_VALUE) {
+                CompileTheWorldStopAt.setValue(c.compileTheWorldStopAt);
+            }
+        }
+    }
+
+    /**
+     * A mechanism for overriding JVMCI options that affect compilation. A {@link Config} object
+     * should be used in a try-with-resources statement to ensure overriding of options is scoped
+     * properly. For example:
+     *
+     * <pre>
+     *     Config config = ...;
+     *     try (AutoCloseable s = config == null ? null : config.apply()) {
+     *         // perform a JVMCI compilation
+     *     }
+     * </pre>
+     */
+    @SuppressWarnings("serial")
+    public static class Config extends HashMap<OptionValue<?>, Object> implements OptionConsumer {
+        /**
+         * Creates a {@link Config} object by parsing a set of space separated override options.
+         *
+         * @param options a space separated set of option value settings with each option setting in
+         *            a format compatible with
+         *            {@link OptionUtils#parseOption(String, OptionConsumer)}. Ignored if null.
+         */
+        public Config(String options) {
+            if (options != null) {
+                for (String option : options.split("\\s+")) {
+                    OptionUtils.parseOption(option, this);
+                }
+            }
+        }
+
+        /**
+         * Applies the overrides represented by this object. The overrides are in effect until
+         * {@link OverrideScope#close()} is called on the returned object.
+         */
+        OverrideScope apply() {
+            return OptionValue.override(this);
+        }
+
+        public void set(OptionDescriptor desc, Object value) {
+            put(desc.getOptionValue(), value);
+        }
+    }
+
+    /** List of Zip/Jar files to compile (see {@link Options#CompileTheWorldClasspath}). */
+    private final String files;
+
+    /** Class index to start compilation at (see {@link Options#CompileTheWorldStartAt}). */
+    private final int startAt;
+
+    /** Class index to stop compilation at (see {@link Options#CompileTheWorldStopAt}). */
+    private final int stopAt;
+
+    /** Only compile methods matching one of the filters in this array if the array is non-null. */
+    private final MethodFilter[] methodFilters;
+
+    /** Exclude methods matching one of the filters in this array if the array is non-null. */
+    private final MethodFilter[] excludeMethodFilters;
+
+    // Counters
+    private int classFileCounter = 0;
+    private AtomicLong compiledMethodsCounter = new AtomicLong();
+    private AtomicLong compileTime = new AtomicLong();
+    private AtomicLong memoryUsed = new AtomicLong();
+
+    private boolean verbose;
+    private final Config config;
+
+    /**
+     * Signal that the threads should start compiling in multithreaded mode.
+     */
+    private boolean running;
+
+    private ThreadPoolExecutor threadPool;
+
+    /**
+     * Creates a compile-the-world instance.
+     *
+     * @param files {@link File#pathSeparator} separated list of Zip/Jar files to compile
+     * @param startAt index of the class file to start compilation at
+     * @param stopAt index of the class file to stop compilation at
+     * @param methodFilters
+     * @param excludeMethodFilters
+     */
+    public CompileTheWorld(String files, Config config, int startAt, int stopAt, String methodFilters, String excludeMethodFilters, boolean verbose) {
+        this.files = files;
+        this.startAt = startAt;
+        this.stopAt = stopAt;
+        this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters);
+        this.excludeMethodFilters = excludeMethodFilters == null || excludeMethodFilters.isEmpty() ? null : MethodFilter.parse(excludeMethodFilters);
+        this.verbose = verbose;
+        this.config = config;
+
+        // We don't want the VM to exit when a method fails to compile...
+        config.putIfAbsent(ExitVMOnException, false);
+
+        // ...but we want to see exceptions.
+        config.putIfAbsent(PrintBailout, true);
+        config.putIfAbsent(PrintStackTraceOnException, true);
+        config.putIfAbsent(HotSpotResolvedJavaMethodImpl.Options.UseProfilingInformation, false);
+    }
+
+    public CompileTheWorld() {
+        this(CompileTheWorldClasspath.getValue(), new Config(CompileTheWorldConfig.getValue()), CompileTheWorldStartAt.getValue(), CompileTheWorldStopAt.getValue(),
+                        CompileTheWorldMethodFilter.getValue(), CompileTheWorldExcludeMethodFilter.getValue(), CompileTheWorldVerbose.getValue());
+    }
+
+    /**
+     * Compiles all methods in all classes in the Zip/Jar archive files in
+     * {@link Options#CompileTheWorldClasspath}. If {@link Options#CompileTheWorldClasspath}
+     * contains the magic token {@link #SUN_BOOT_CLASS_PATH} passed up from HotSpot we take the
+     * files from the boot class path.
+     */
+    public void compile() throws Throwable {
+        // By default only report statistics for the CTW threads themselves
+        if (GraalDebugConfig.DebugValueThreadFilter.hasDefaultValue()) {
+            GraalDebugConfig.DebugValueThreadFilter.setValue("^CompileTheWorld");
+        }
+
+        if (SUN_BOOT_CLASS_PATH.equals(files)) {
+            final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator);
+            String bcpFiles = "";
+            for (int i = 0; i < entries.length; i++) {
+                final String entry = entries[i];
+
+                // We stop at rt.jar, unless it is the first boot class path entry.
+                if (entry.endsWith("rt.jar") && (i > 0)) {
+                    break;
+                }
+                if (i > 0) {
+                    bcpFiles += File.pathSeparator;
+                }
+                bcpFiles += entry;
+            }
+            compile(bcpFiles);
+        } else {
+            compile(files);
+        }
+    }
+
+    public void println() {
+        println("");
+    }
+
+    public void println(String format, Object... args) {
+        println(String.format(format, args));
+    }
+
+    public void println(String s) {
+        if (verbose) {
+            TTY.println(s);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    private static void dummy() {
+    }
+
+    /**
+     * Compiles all methods in all classes in the Zip/Jar files passed.
+     *
+     * @param fileList {@link File#pathSeparator} separated list of Zip/Jar files to compile
+     * @throws IOException
+     */
+    private void compile(String fileList) throws IOException {
+        final String[] entries = fileList.split(File.pathSeparator);
+        long start = System.currentTimeMillis();
+
+        CompilerThreadFactory factory = new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() {
+            public GraalDebugConfig getDebugConfig() {
+                if (Debug.isEnabled() && DebugScope.getConfig() == null) {
+                    return DebugEnvironment.initialize(System.out);
+                }
+                return null;
+            }
+        });
+
+        try {
+            // compile dummy method to get compiler initilized outside of the config debug override.
+            HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod(
+                            CompileTheWorld.class.getDeclaredMethod("dummy"));
+            CompilationTask task = new CompilationTask(dummyMethod, Compiler.INVOCATION_ENTRY_BCI, 0L, dummyMethod.allocateCompileId(Compiler.INVOCATION_ENTRY_BCI), false);
+            task.runCompilation();
+        } catch (NoSuchMethodException | SecurityException e1) {
+            e1.printStackTrace();
+        }
+
+        /*
+         * Always use a thread pool, even for single threaded mode since it simplifies the use of
+         * DebugValueThreadFilter to filter on the thread names.
+         */
+        int threadCount = 1;
+        if (Options.CompileTheWorldMultiThreaded.getValue()) {
+            threadCount = Options.CompileTheWorldThreads.getValue();
+            if (threadCount == 0) {
+                threadCount = Runtime.getRuntime().availableProcessors();
+            }
+        } else {
+            running = true;
+        }
+        threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), factory);
+
+        try (OverrideScope s = config.apply()) {
+            for (int i = 0; i < entries.length; i++) {
+                final String entry = entries[i];
+
+                // For now we only compile all methods in all classes in zip/jar files.
+                if (!entry.endsWith(".zip") && !entry.endsWith(".jar")) {
+                    println("CompileTheWorld : Skipped classes in " + entry);
+                    println();
+                    continue;
+                }
+
+                if (methodFilters == null || methodFilters.length == 0) {
+                    println("CompileTheWorld : Compiling all classes in " + entry);
+                } else {
+                    String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", "));
+                    println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include);
+                }
+                if (excludeMethodFilters != null && excludeMethodFilters.length > 0) {
+                    String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", "));
+                    println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude);
+                }
+                println();
+
+                URL url = new URL("jar", "", "file:" + entry + "!/");
+                ClassLoader loader = new URLClassLoader(new URL[]{url});
+
+                JarFile jarFile = new JarFile(entry);
+                Enumeration<JarEntry> e = jarFile.entries();
+
+                while (e.hasMoreElements()) {
+                    JarEntry je = e.nextElement();
+                    if (je.isDirectory() || !je.getName().endsWith(".class")) {
+                        continue;
+                    }
+
+                    // Are we done?
+                    if (classFileCounter >= stopAt) {
+                        break;
+                    }
+
+                    String className = je.getName().substring(0, je.getName().length() - ".class".length());
+                    String dottedClassName = className.replace('/', '.');
+                    classFileCounter++;
+
+                    if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, dottedClassName)) {
+                        continue;
+                    }
+                    if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, dottedClassName)) {
+                        continue;
+                    }
+
+                    if (dottedClassName.startsWith("jdk.management.") || dottedClassName.startsWith("jdk.internal.cmm.*")) {
+                        continue;
+                    }
+
+                    try {
+                        // Load and initialize class
+                        Class<?> javaClass = Class.forName(dottedClassName, true, loader);
+
+                        // Pre-load all classes in the constant pool.
+                        try {
+                            HotSpotResolvedObjectType objectType = HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass);
+                            ConstantPool constantPool = objectType.constantPool();
+                            for (int cpi = 1; cpi < constantPool.length(); cpi++) {
+                                constantPool.loadReferencedType(cpi, HotSpotConstantPool.Bytecodes.LDC);
+                            }
+                        } catch (Throwable t) {
+                            // If something went wrong during pre-loading we just ignore it.
+                            println("Preloading failed for (%d) %s: %s", classFileCounter, className, t);
+                        }
+
+                        // Are we compiling this class?
+                        MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+                        if (classFileCounter >= startAt) {
+                            println("CompileTheWorld (%d) : %s", classFileCounter, className);
+
+                            // Compile each constructor/method in the class.
+                            for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) {
+                                HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor);
+                                if (canBeCompiled(javaMethod, constructor.getModifiers())) {
+                                    compileMethod(javaMethod);
+                                }
+                            }
+                            for (Method method : javaClass.getDeclaredMethods()) {
+                                HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
+                                if (canBeCompiled(javaMethod, method.getModifiers())) {
+                                    compileMethod(javaMethod);
+                                }
+                            }
+                        }
+                    } catch (Throwable t) {
+                        println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString());
+                        t.printStackTrace();
+                    }
+                }
+                jarFile.close();
+            }
+        }
+
+        if (!running) {
+            startThreads();
+        }
+        int wakeups = 0;
+        while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) {
+            if (wakeups % 15 == 0) {
+                TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles");
+            }
+            try {
+                threadPool.awaitTermination(1, TimeUnit.SECONDS);
+                wakeups++;
+            } catch (InterruptedException e) {
+            }
+        }
+        threadPool = null;
+
+        long elapsedTime = System.currentTimeMillis() - start;
+
+        println();
+        if (Options.CompileTheWorldMultiThreaded.getValue()) {
+            TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime,
+                            compileTime.get(), memoryUsed.get());
+        } else {
+            TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get());
+        }
+    }
+
+    private synchronized void startThreads() {
+        running = true;
+        // Wake up any waiting threads
+        notifyAll();
+    }
+
+    private synchronized void waitToRun() {
+        while (!running) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    private void compileMethod(HotSpotResolvedJavaMethod method) throws InterruptedException, ExecutionException {
+        if (methodFilters != null && !MethodFilter.matches(methodFilters, method)) {
+            return;
+        }
+        if (excludeMethodFilters != null && MethodFilter.matches(excludeMethodFilters, method)) {
+            return;
+        }
+        Future<?> task = threadPool.submit(new Runnable() {
+            public void run() {
+                waitToRun();
+                try (OverrideScope s = config.apply()) {
+                    compileMethod(method, classFileCounter);
+                }
+            }
+        });
+        if (threadPool.getCorePoolSize() == 1) {
+            task.get();
+        }
+    }
+
+    /**
+     * Compiles a method and gathers some statistics.
+     */
+    private void compileMethod(HotSpotResolvedJavaMethod method, int counter) {
+        try {
+            long start = System.currentTimeMillis();
+            long allocatedAtStart = MemUseTrackerImpl.getCurrentThreadAllocatedBytes();
+
+            CompilationTask task = new CompilationTask(method, Compiler.INVOCATION_ENTRY_BCI, 0L, method.allocateCompileId(Compiler.INVOCATION_ENTRY_BCI), false);
+            task.runCompilation();
+
+            memoryUsed.getAndAdd(MemUseTrackerImpl.getCurrentThreadAllocatedBytes() - allocatedAtStart);
+            compileTime.getAndAdd(System.currentTimeMillis() - start);
+            compiledMethodsCounter.incrementAndGet();
+        } catch (Throwable t) {
+            // Catch everything and print a message
+            println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r"));
+            t.printStackTrace(TTY.out);
+        }
+    }
+
+    /**
+     * Determines if a method should be compiled (Cf. CompilationPolicy::can_be_compiled).
+     *
+     * @return true if it can be compiled, false otherwise
+     */
+    private static boolean canBeCompiled(HotSpotResolvedJavaMethod javaMethod, int modifiers) {
+        if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+            return false;
+        }
+        HotSpotVMConfig c = HotSpotJVMCIRuntime.runtime().getConfig();
+        if (c.dontCompileHugeMethods && javaMethod.getCodeSize() > c.hugeMethodLimit) {
+            return false;
+        }
+        // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods
+        if (!javaMethod.canBeInlined()) {
+            return false;
+        }
+        // Skip @Snippets for now
+        for (Annotation annotation : javaMethod.getAnnotations()) {
+            if (annotation.annotationType().getName().equals("com.oracle.graal.replacements.Snippet")) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot;
 
-import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*;
+import static com.oracle.graal.debug.GraalDebugConfig.*;
 
 import java.io.*;
 import java.util.*;
@@ -31,7 +31,8 @@
 
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.internal.*;
+
+import com.oracle.graal.debug.internal.*;
 
 /**
  * Facility for printing the {@linkplain KeyRegistry#getDebugValues() values} collected across all
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Fri Jul 24 08:33:42 2015 +0200
@@ -33,6 +33,7 @@
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.hotspot;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.stubs.*;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkageImpl.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkageImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -32,6 +32,7 @@
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
@@ -43,6 +44,11 @@
 public class HotSpotForeignCallLinkageImpl extends HotSpotForeignCallTarget implements HotSpotForeignCallLinkage, HotSpotProxified {
 
     /**
+     * The descriptor of the call.
+     */
+    protected final ForeignCallDescriptor descriptor;
+
+    /**
      * Non-null (eventually) iff this is a call to a compiled {@linkplain Stub stub}.
      */
     private Stub stub;
@@ -126,7 +132,8 @@
 
     public HotSpotForeignCallLinkageImpl(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Transition transition, CallingConvention outgoingCallingConvention,
                     CallingConvention incomingCallingConvention, boolean reexecutable, LocationIdentity... killedLocations) {
-        super(descriptor, address);
+        super(address);
+        this.descriptor = descriptor;
         this.address = address;
         this.effect = effect;
         this.transition = transition;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.Options.*;
 import static jdk.internal.jvmci.common.UnsafeAccess.*;
-import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*;
+import static com.oracle.graal.debug.GraalDebugConfig.*;
 import static jdk.internal.jvmci.hotspot.InitTimer.*;
 
 import java.lang.reflect.*;
@@ -35,6 +35,9 @@
 import jdk.internal.jvmci.code.stack.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.hotspot.logging.*;
 import jdk.internal.jvmci.meta.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,15 +22,27 @@
  */
 package com.oracle.graal.hotspot;
 
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.debug.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.service.*;
 
+import com.oracle.graal.debug.*;
+
 @ServiceProvider(HotSpotVMEventListener.class)
 public class HotSpotGraalVMEventListener implements HotSpotVMEventListener {
 
     @Override
     public void notifyCompileTheWorld() throws Throwable {
-
+        CompilerToVM compilerToVM = HotSpotJVMCIRuntime.runtime().getCompilerToVM();
+        int iterations = CompileTheWorld.Options.CompileTheWorldIterations.getValue();
+        for (int i = 0; i < iterations; i++) {
+            compilerToVM.resetCompilationStatistics();
+            TTY.println("CompileTheWorld : iteration " + i);
+            CompileTheWorld ctw = new CompileTheWorld();
+            ctw.compile();
+        }
+        System.exit(0);
     }
 
     @Override
@@ -40,6 +52,17 @@
 
     @Override
     public void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long jvmciEnv, int id) {
+        HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
+        CompilationTask.compileMethod(method, entryBCI, jvmciEnv, id);
+    }
 
+    @Override
+    public void notifyInstall(HotSpotCodeCacheProvider codeCache, InstalledCode installedCode, CompilationResult compResult) {
+        if (Debug.isDumpEnabled()) {
+            Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
+        }
+        if (Debug.isLogEnabled()) {
+            Debug.log("%s", codeCache.disassemble(installedCode));
+        }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,10 @@
  */
 package com.oracle.graal.hotspot;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.compiler.common.spi.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
+
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.service.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLockStack.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLockStack.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,33 +22,41 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
 
 /**
  * Manages allocation and re-use of lock slots in a scoped manner. The slots are used in HotSpot's
  * lightweight locking mechanism to store the mark word of an object being locked.
  */
-public class HotSpotLockStack {
+public class HotSpotLockStack extends LIRInstruction {
+    public static final LIRInstructionClass<HotSpotLockStack> TYPE = LIRInstructionClass.create(HotSpotLockStack.class);
+    private static final StackSlotValue[] EMPTY = new StackSlotValue[0];
 
-    private StackSlotValue[] locks;
+    @Def({STACK}) private StackSlotValue[] locks;
     private final FrameMapBuilder frameMapBuilder;
     private final LIRKind slotKind;
 
     public HotSpotLockStack(FrameMapBuilder frameMapBuilder, LIRKind slotKind) {
+        super(TYPE);
         this.frameMapBuilder = frameMapBuilder;
         this.slotKind = slotKind;
+        this.locks = EMPTY;
     }
 
     /**
      * Gets a stack slot for a lock at a given lock nesting depth, allocating it first if necessary.
      */
     public StackSlotValue makeLockSlot(int lockDepth) {
-        if (locks == null) {
+        if (locks == EMPTY) {
             locks = new StackSlotValue[lockDepth + 1];
         } else if (locks.length < lockDepth + 1) {
             locks = Arrays.copyOf(locks, lockDepth + 1);
@@ -58,4 +66,9 @@
         }
         return locks[lockDepth];
     }
+
+    @Override
+    public void emitCode(CompilationResultBuilder crb) {
+        // do nothing
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,6 +30,7 @@
 
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
+
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -35,6 +35,7 @@
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot.meta;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
+
 /**
  * HotSpot extension of {@link ForeignCallsProvider}.
  */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,6 +31,7 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
 import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,13 +29,13 @@
 import java.lang.invoke.*;
 import java.util.zip.*;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 import sun.reflect.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.graphbuilderconf.InvocationPlugin.Receiver;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -41,10 +41,10 @@
 import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
 import static com.oracle.graal.hotspot.stubs.StubUtil.*;
 import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*;
+import static com.oracle.graal.nodes.NamedLocationIdentity.*;
 import static com.oracle.graal.nodes.java.ForeignCallDescriptors.*;
 import static com.oracle.graal.replacements.Log.*;
 import static jdk.internal.jvmci.code.CallingConvention.Type.*;
-import static jdk.internal.jvmci.meta.LocationIdentity.*;
 
 import java.util.*;
 
@@ -53,8 +53,10 @@
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.word.*;
 
 /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,9 +24,9 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.replacements.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,6 +27,7 @@
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
 import static com.oracle.graal.hotspot.nodes.CStringNode.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.hotspot.phases;
 
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.nodes.ConstantNode.*;
+import static com.oracle.graal.nodes.NamedLocationIdentity.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.hotspot.*;
-import jdk.internal.jvmci.hotspot.HotSpotVMConfig.*;
+import jdk.internal.jvmci.hotspot.HotSpotVMConfig.CompressEncoding;
 import jdk.internal.jvmci.meta.*;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-import static com.oracle.graal.nodes.ConstantNode.*;
-import static jdk.internal.jvmci.meta.LocationIdentity.*;
 
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.nodes.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.compiler.Compiler;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Fri Jul 24 08:33:42 2015 +0200
@@ -33,6 +33,7 @@
 import jdk.internal.jvmci.meta.*;
 import sun.misc.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.nodes.CStringNode.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
+import jdk.internal.jvmci.code.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.meta.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,6 +30,7 @@
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.hotspot.replacements;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*;
 import static com.oracle.graal.nodes.PiNode.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,6 +29,7 @@
 import sun.misc.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Jul 24 08:33:42 2015 +0200
@@ -34,6 +34,7 @@
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -38,6 +38,7 @@
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -35,12 +35,15 @@
 import static jdk.internal.jvmci.hotspot.HotSpotMetaAccessProvider.*;
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import java.lang.reflect.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,9 +24,8 @@
 
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
-import jdk.internal.jvmci.meta.*;
-
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 
 /**
  * Substitutions for {@link java.lang.System} methods.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,9 +24,8 @@
 
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static jdk.internal.jvmci.meta.LocationIdentity.*;
-import jdk.internal.jvmci.meta.*;
-
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,6 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -32,6 +32,7 @@
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.meta.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,6 +28,7 @@
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,6 +27,7 @@
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,18 +22,19 @@
  */
 package com.oracle.graal.hotspot.replacements.arraycopy;
 
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.nodes.NamedLocationIdentity.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
-import static jdk.internal.jvmci.meta.LocationIdentity.*;
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.phases.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,6 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.hotspot.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.Options.*;
 import static com.oracle.graal.hotspot.nodes.DeoptimizationFetchUnrollInfoCallNode.*;
@@ -34,6 +33,7 @@
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,13 +24,13 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.hotspot.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.nodes.JumpToExceptionHandlerNode.*;
 import static com.oracle.graal.hotspot.nodes.PatchReturnAddressNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.stubs.StubUtil.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
 import static jdk.internal.jvmci.code.CallingConvention.Type.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,9 +29,8 @@
 import static jdk.internal.jvmci.hotspot.HotSpotMetaAccessProvider.*;
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.hotspot.*;
-import jdk.internal.jvmci.meta.*;
-
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,6 +31,7 @@
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,8 +27,8 @@
 import java.lang.reflect.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graphbuilderconf.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,9 +29,9 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
-import jdk.internal.jvmci.debug.internal.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
+import com.oracle.graal.debug.internal.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Jul 24 08:33:42 2015 +0200
@@ -34,6 +34,7 @@
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,20 +22,22 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.HotSpotBackend.Options.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.meta.*;
-import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotBackend.Options.*;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.word.*;
@@ -149,7 +151,7 @@
          * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for
          * total size of the interpreter frames plus shadow page size. Bang one page at a time
          * because large sizes can bang beyond yellow and red zones.
-         *
+         * 
          * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository.
          */
         final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,13 +23,13 @@
 package com.oracle.graal.hotspot.stubs;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.hotspot.nodes.JumpToExceptionHandlerInCallerNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*;
 import static com.oracle.graal.hotspot.stubs.StubUtil.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.bytecode.*;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java	Fri Jul 24 08:33:42 2015 +0200
@@ -39,7 +39,10 @@
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.compiler.Compiler;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.Scope;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -32,7 +32,7 @@
 import java.util.function.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.type.*;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/LocalLiveness.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/LocalLiveness.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.java;
 
 import static com.oracle.graal.bytecode.Bytecodes.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.bytecode.*;
 import com.oracle.graal.java.BciBlockMapping.BciBlock;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/ConstantPhiTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,79 @@
+/*
+ * 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.jtt.backend;
+
+import static com.oracle.graal.api.directives.GraalDirectives.*;
+
+import java.lang.reflect.*;
+
+import jdk.internal.jvmci.options.*;
+import jdk.internal.jvmci.options.OptionValue.OverrideScope;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.jtt.*;
+
+public class ConstantPhiTest extends JTTTest {
+
+    public static int test(int i, int x) throws Throwable {
+        int r;
+        if (injectBranchProbability(LIKELY_PROBABILITY, i < 0)) {
+            r = 42;
+        } else {
+            r = x;
+        }
+        destroyCallerSavedValues();
+        return r;
+    }
+
+    protected static void destroyCallerSavedValues() throws Throwable {
+        Class<ConstantPhiTest> c = ConstantPhiTest.class;
+        Method m = c.getMethod("destroyCallerSavedValues0");
+        m.invoke(null);
+    }
+
+    public static void destroyCallerSavedValues0() {
+    }
+
+    @Test
+    public void run0() {
+        try (OverrideScope os = OptionValue.override(GraalOptions.MaximumInliningSize, -1)) {
+            runTest("test", 0, 0xDEADDEAD);
+        }
+    }
+
+    @Test
+    public void run1() {
+        try (OverrideScope os = OptionValue.override(GraalOptions.MaximumInliningSize, -1)) {
+            runTest("test", -1, 0xDEADDEAD);
+        }
+    }
+
+    @Test
+    public void run2() {
+        try (OverrideScope os = OptionValue.override(GraalOptions.MaximumInliningSize, -1)) {
+            runTest("test", 1, 0xDEADDEAD);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BlockEndOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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.amd64;
+
+import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
+import com.oracle.graal.lir.asm.*;
+
+public abstract class AMD64BlockEndOp extends AbstractBlockEndOp {
+
+    public static final LIRInstructionClass<AMD64BlockEndOp> TYPE = LIRInstructionClass.create(AMD64BlockEndOp.class);
+
+    protected AMD64BlockEndOp(LIRInstructionClass<? extends AMD64BlockEndOp> c) {
+        super(c);
+    }
+
+    @Override
+    public final void emitCode(CompilationResultBuilder crb) {
+        emitCode(crb, (AMD64MacroAssembler) crb.asm);
+    }
+
+    public abstract void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm);
+}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,6 +30,7 @@
 
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.amd64.AMD64Assembler.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Fri Jul 24 08:33:42 2015 +0200
@@ -42,7 +42,7 @@
 
 public class AMD64ControlFlow {
 
-    public static final class ReturnOp extends AMD64LIRInstruction implements BlockEndOp {
+    public static final class ReturnOp extends AMD64BlockEndOp implements BlockEndOp {
         public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
         @Use({REG, ILLEGAL}) protected Value x;
 
@@ -58,7 +58,7 @@
         }
     }
 
-    public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp {
+    public static class BranchOp extends AMD64BlockEndOp implements StandardOp.BranchOp {
         public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class);
         protected final ConditionFlag condition;
         protected final LabelRef trueDestination;
@@ -125,7 +125,7 @@
         }
     }
 
-    public static final class StrategySwitchOp extends AMD64LIRInstruction implements BlockEndOp {
+    public static final class StrategySwitchOp extends AMD64BlockEndOp {
         public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class);
         @Use({CONST}) protected JavaConstant[] keyConstants;
         private final LabelRef[] keyTargets;
@@ -181,7 +181,7 @@
         }
     }
 
-    public static final class TableSwitchOp extends AMD64LIRInstruction implements BlockEndOp {
+    public static final class TableSwitchOp extends AMD64BlockEndOp {
         public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class);
         private final int lowKey;
         private final LabelRef defaultTarget;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/phases/StackMoveOptimizationPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/phases/StackMoveOptimizationPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBlockEndOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,86 @@
+/*
+ * 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.sparc;
+
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.*;
+
+import jdk.internal.jvmci.meta.*;
+
+public abstract class SPARCBlockEndOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final LIRInstructionClass<SPARCBlockEndOp> TYPE = LIRInstructionClass.create(SPARCBlockEndOp.class);
+
+    @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
+    private int size;
+
+    protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c) {
+        this(c, null);
+    }
+
+    protected SPARCBlockEndOp(LIRInstructionClass<? extends SPARCBlockEndOp> c, SizeEstimate sizeEstimate) {
+        super(c, sizeEstimate);
+        this.outgoingValues = Value.NO_VALUES;
+        this.size = 0;
+    }
+
+    public void setOutgoingValues(Value[] values) {
+        assert outgoingValues.length == 0;
+        assert values != null;
+        outgoingValues = values;
+        size = values.length;
+    }
+
+    public int getOutgoingSize() {
+        return size;
+    }
+
+    public Value getOutgoingValue(int idx) {
+        assert checkRange(idx);
+        return outgoingValues[idx];
+    }
+
+    private boolean checkRange(int idx) {
+        return idx < size;
+    }
+
+    public void clearOutgoingValues() {
+        outgoingValues = Value.NO_VALUES;
+        size = 0;
+    }
+
+    public int addOutgoingValues(Value[] v) {
+
+        int t = size + v.length;
+        if (t >= outgoingValues.length) {
+            Value[] newArray = new Value[t];
+            System.arraycopy(outgoingValues, 0, newArray, 0, size);
+            outgoingValues = newArray;
+        }
+        System.arraycopy(v, 0, outgoingValues, size, v.length);
+        size = t;
+        return t;
+
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -53,8 +53,8 @@
 
     @Override
     public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-        SPARCMove.reg2stack(crb, masm, tmpSlot, input, SPARCDelayedControlTransfer.DUMMY);
         SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot);
+        SPARCMove.emitStore(input, addr, result.getKind(), SPARCDelayedControlTransfer.DUMMY, null, crb, masm);
         if (addr.getIndex().equals(Register.None)) {
             Register tempReg = ValueUtil.asLongReg(tempIndex);
             new SPARCMacroAssembler.Setx(addr.getDisplacement(), tempReg, false).emit(masm);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Fri Jul 24 08:33:42 2015 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Sethix;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Jul 24 08:33:42 2015 +0200
@@ -38,7 +38,6 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.meta.*;
-import jdk.internal.jvmci.sparc.*;
 import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
 
 import com.oracle.graal.asm.*;
@@ -51,7 +50,6 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.BlockEndOp;
 import com.oracle.graal.lir.SwitchStrategy.BaseSwitchClosure;
 import com.oracle.graal.lir.asm.*;
 
@@ -60,7 +58,7 @@
     // if does not fit into simm5 of cbcond) instruction and the final branch instruction
     private static final int maximumSelfOffsetInstructions = 2;
 
-    public static final class ReturnOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final class ReturnOp extends SPARCBlockEndOp {
         public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(2);
 
@@ -83,7 +81,7 @@
         }
     }
 
-    public static final class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer {
+    public static final class CompareBranchOp extends SPARCBlockEndOp implements SPARCDelayedControlTransfer {
         public static final LIRInstructionClass<CompareBranchOp> TYPE = LIRInstructionClass.create(CompareBranchOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(3);
         static final EnumSet<Kind> SUPPORTED_KINDS = EnumSet.of(Kind.Long, Kind.Int, Kind.Object, Kind.Float, Kind.Double);
@@ -312,15 +310,12 @@
 
     private static boolean isShortBranch(SPARCAssembler asm, int position, LabelHint hint, Label label) {
         int disp = 0;
-        boolean dispValid = true;
         if (label.isBound()) {
             disp = label.position() - position;
         } else if (hint != null && hint.isValid()) {
             disp = hint.getTarget() - hint.getPosition();
-        } else {
-            dispValid = false;
         }
-        if (dispValid) {
+        if (disp != 0) {
             if (disp < 0) {
                 disp -= maximumSelfOffsetInstructions * asm.target.wordSize;
             } else {
@@ -333,7 +328,7 @@
         return false;
     }
 
-    public static final class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp {
+    public static final class BranchOp extends SPARCBlockEndOp implements StandardOp.BranchOp {
         public static final LIRInstructionClass<BranchOp> TYPE = LIRInstructionClass.create(BranchOp.class);
         public static final SizeEstimate SIZE = SizeEstimate.create(2);
         protected final ConditionFlag conditionFlag;
@@ -398,7 +393,7 @@
         return true;
     }
 
-    public static final class StrategySwitchOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final class StrategySwitchOp extends SPARCBlockEndOp {
         public static final LIRInstructionClass<StrategySwitchOp> TYPE = LIRInstructionClass.create(StrategySwitchOp.class);
         @Use({CONST}) protected JavaConstant[] keyConstants;
         private final LabelRef[] keyTargets;
@@ -407,8 +402,7 @@
         @Alive({REG, ILLEGAL}) protected Value constantTableBase;
         @Temp({REG}) protected Value scratch;
         private final SwitchStrategy strategy;
-        private final Map<Label, LabelHint> labelHints;
-        private final List<Label> conditionalLabels = new ArrayList<>();
+        private final LabelHint[] labelHints;
 
         public StrategySwitchOp(Value constantTableBase, SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) {
             super(TYPE);
@@ -419,7 +413,7 @@
             this.constantTableBase = constantTableBase;
             this.key = key;
             this.scratch = scratch;
-            this.labelHints = new HashMap<>();
+            this.labelHints = new LabelHint[keyTargets.length];
             assert keyConstants.length == keyTargets.length;
             assert keyConstants.length == strategy.keyProbabilities.length;
         }
@@ -429,31 +423,9 @@
             final Register keyRegister = asRegister(key);
             final Register constantBaseRegister = AllocatableValue.ILLEGAL.equals(constantTableBase) ? g0 : asRegister(constantTableBase);
             BaseSwitchClosure closure = new BaseSwitchClosure(crb, masm, keyTargets, defaultTarget) {
-                int conditionalLabelPointer = 0;
-
-                /**
-                 * This method caches the generated labels over two assembly passes to get
-                 * information about branch lengths.
-                 */
-                @Override
-                public Label conditionalJump(int index, Condition condition) {
-                    Label label;
-                    if (conditionalLabelPointer <= conditionalLabels.size()) {
-                        label = new Label();
-                        conditionalLabels.add(label);
-                        conditionalLabelPointer = conditionalLabels.size();
-                    } else {
-                        // TODO: (sa) We rely here on the order how the labels are generated during
-                        // code generation; if the order is not stable ower two assembly passes, the
-                        // result can be wrong
-                        label = conditionalLabels.get(conditionalLabelPointer++);
-                    }
-                    conditionalJump(index, condition, label);
-                    return label;
-                }
-
                 @Override
                 protected void conditionalJump(int index, Condition condition, Label target) {
+                    requestHint(masm, index);
                     JavaConstant constant = keyConstants[index];
                     CC conditionCode;
                     Long bits;
@@ -479,15 +451,10 @@
                             throw new JVMCIError("switch only supported for int, long and object");
                     }
                     ConditionFlag conditionFlag = fromCondition(conditionCode, condition, false);
-                    LabelHint hint = requestHint(masm, target);
-                    boolean isShortConstant = isSimm5(constant);
-                    int cbCondPosition = masm.position();
-                    if (!isShortConstant) { // Load constant takes one instruction
-                        cbCondPosition += SPARC.INSTRUCTION_SIZE;
-                    }
-                    boolean canUseShortBranch = masm.hasFeature(CBCOND) && isShortBranch(masm, cbCondPosition, hint, target);
+                    LabelHint hint = labelHints[index];
+                    boolean canUseShortBranch = masm.hasFeature(CBCOND) && hint.isValid() && isShortBranch(masm, masm.position(), hint, target);
                     if (bits != null && canUseShortBranch) {
-                        if (isShortConstant) {
+                        if (isSimm5(constant)) {
                             if (conditionCode == Icc) {
                                 masm.cbcondw(conditionFlag, keyRegister, (int) (long) bits, target);
                             } else {
@@ -518,13 +485,8 @@
             strategy.run(closure);
         }
 
-        private LabelHint requestHint(SPARCMacroAssembler masm, Label label) {
-            LabelHint hint = labelHints.get(label);
-            if (hint == null) {
-                hint = masm.requestLabelHint(label);
-                labelHints.put(label, hint);
-            }
-            return hint;
+        private void requestHint(SPARCMacroAssembler masm, int index) {
+            labelHints[index] = masm.requestLabelHint(keyTargets[index].label());
         }
 
         @Override
@@ -539,7 +501,7 @@
         }
     }
 
-    public static final class TableSwitchOp extends SPARCLIRInstruction implements BlockEndOp {
+    public static final class TableSwitchOp extends SPARCBlockEndOp {
         public static final LIRInstructionClass<TableSwitchOp> TYPE = LIRInstructionClass.create(TableSwitchOp.class);
 
         private final int lowKey;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Fri Jul 24 08:33:42 2015 +0200
@@ -652,13 +652,13 @@
             Value scratchRegisterValue = sc.getRegister().asValue(LIRKind.combine(input));
             emitLoad(crb, masm, inputAddress, scratchRegisterValue, false, input.getPlatformKind(), SPARCDelayedControlTransfer.DUMMY, null);
             SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
-            emitStore(scratchRegisterValue, resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm);
+            emitStore(scratchRegisterValue, resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
         }
     }
 
     public static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
         SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
-        emitStore(input, resultAddress, input.getPlatformKind(), delaySlotLir, null, crb, masm);
+        emitStore(input, resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
     }
 
     public static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import java.lang.annotation.*;
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ControlFlowOptimizer.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.gen.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,7 +29,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.lir.asm.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,6 +30,7 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
+
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,15 +27,15 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.meta.*;
-
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
 
+import jdk.internal.jvmci.code.*;
+import jdk.internal.jvmci.common.*;
+import jdk.internal.jvmci.meta.*;
+
 /**
  * A collection of machine-independent LIR operations, as well as interfaces to be implemented for
  * specific kinds or LIR operations.
@@ -47,6 +47,15 @@
      * must be the last operation in the block.
      */
     public interface BlockEndOp {
+        void setOutgoingValues(Value[] values);
+
+        int getOutgoingSize();
+
+        Value getOutgoingValue(int idx);
+
+        int addOutgoingValues(Value[] values);
+
+        void clearOutgoingValues();
     }
 
     public interface NullCheck {
@@ -74,6 +83,7 @@
          * instruction of a block, the registers are defined here in the label.
          */
         @Def({REG, STACK}) private Value[] incomingValues;
+        private int size;
 
         private final Label label;
         private final boolean align;
@@ -83,24 +93,43 @@
             this.label = label;
             this.align = align;
             this.incomingValues = Value.NO_VALUES;
+            size = 0;
         }
 
         public void setIncomingValues(Value[] values) {
-            assert incomingValues.length == 0;
+            assert this.incomingValues.length == 0;
             assert values != null;
-            incomingValues = values;
+            this.incomingValues = values;
+            size = values.length;
         }
 
         public int getIncomingSize() {
-            return incomingValues.length;
+            return size;
         }
 
         public Value getIncomingValue(int idx) {
+            assert checkRange(idx);
             return incomingValues[idx];
         }
 
         public void clearIncomingValues() {
             incomingValues = Value.NO_VALUES;
+            size = 0;
+        }
+
+        public void addIncomingValues(Value[] values) {
+            int t = size + values.length;
+            if (t >= incomingValues.length) {
+                Value[] newArray = new Value[t];
+                System.arraycopy(incomingValues, 0, newArray, 0, size);
+                incomingValues = newArray;
+            }
+            System.arraycopy(values, 0, incomingValues, size, values.length);
+            size = t;
+        }
+
+        private boolean checkRange(int idx) {
+            return idx < size;
         }
 
         @Override
@@ -123,14 +152,62 @@
         }
     }
 
+    public abstract static class AbstractBlockEndOp extends LIRInstruction implements BlockEndOp {
+        public static final LIRInstructionClass<AbstractBlockEndOp> TYPE = LIRInstructionClass.create(AbstractBlockEndOp.class);
+
+        @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
+        private int size;
+
+        protected AbstractBlockEndOp(LIRInstructionClass<? extends AbstractBlockEndOp> c) {
+            super(c);
+            this.outgoingValues = Value.NO_VALUES;
+            size = 0;
+        }
+
+        public void setOutgoingValues(Value[] values) {
+            assert this.outgoingValues.length == 0;
+            assert values != null;
+            this.outgoingValues = values;
+            size = values.length;
+        }
+
+        public int getOutgoingSize() {
+            return size;
+        }
+
+        public Value getOutgoingValue(int idx) {
+            assert checkRange(idx);
+            return outgoingValues[idx];
+        }
+
+        public void clearOutgoingValues() {
+            outgoingValues = Value.NO_VALUES;
+            size = 0;
+        }
+
+        public int addOutgoingValues(Value[] values) {
+            int t = size + values.length;
+            if (t >= outgoingValues.length) {
+                Value[] newArray = new Value[t];
+                System.arraycopy(outgoingValues, 0, newArray, 0, size);
+                outgoingValues = newArray;
+            }
+            System.arraycopy(values, 0, outgoingValues, size, values.length);
+            size = t;
+            return t;
+        }
+
+        private boolean checkRange(int idx) {
+            return idx < size;
+        }
+    }
+
     /**
      * LIR operation that is an unconditional jump to a {@link #destination()}.
      */
-    public static class JumpOp extends LIRInstruction implements BlockEndOp {
+    public static class JumpOp extends AbstractBlockEndOp {
         public static final LIRInstructionClass<JumpOp> TYPE = LIRInstructionClass.create(JumpOp.class);
 
-        @Alive({REG, STACK, CONST}) private Value[] outgoingValues;
-
         private final LabelRef destination;
 
         public JumpOp(LabelRef destination) {
@@ -140,25 +217,6 @@
         protected JumpOp(LIRInstructionClass<? extends JumpOp> c, LabelRef destination) {
             super(c);
             this.destination = destination;
-            this.outgoingValues = Value.NO_VALUES;
-        }
-
-        public void setOutgoingValues(Value[] values) {
-            assert outgoingValues.length == 0;
-            assert values != null;
-            outgoingValues = values;
-        }
-
-        public int getOutgoingSize() {
-            return outgoingValues.length;
-        }
-
-        public Value getOutgoingValue(int idx) {
-            return outgoingValues[idx];
-        }
-
-        public void clearOutgoingValues() {
-            outgoingValues = Value.NO_VALUES;
         }
 
         @Override
@@ -283,7 +341,7 @@
     public static final class BlackholeOp extends LIRInstruction {
         public static final LIRInstructionClass<BlackholeOp> TYPE = LIRInstructionClass.create(BlackholeOp.class);
 
-        @Use({REG, STACK}) private Value value;
+        @Use({REG, STACK, CONST}) private Value value;
 
         public BlackholeOp(Value value) {
             super(TYPE);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Interval.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Interval.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,6 +31,7 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
+
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.util.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/IntervalWalker.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/IntervalWalker.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.lir.alloc.lsra;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.lir.alloc.lsra.Interval.RegisterBinding;
 import com.oracle.graal.lir.alloc.lsra.Interval.RegisterBindingLists;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,8 +31,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanAssignLocationsPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanAssignLocationsPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,7 +29,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanEliminateSpillMovePhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,7 +29,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,8 +31,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanOptimizeSpillPositionPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,40 +22,34 @@
  */
 package com.oracle.graal.lir.alloc.lsra;
 
-import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.compiler.common.BackendOptions.*;
 
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.options.*;
-import jdk.internal.jvmci.options.DerivedOptionValue.*;
+import jdk.internal.jvmci.common.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.lir.gen.LIRGeneratorTool.SpillMoveFactory;
 import com.oracle.graal.lir.phases.*;
-import com.oracle.graal.lir.ssa.*;
 
 public final class LinearScanPhase extends AllocationPhase {
 
-    public static final DerivedOptionValue<Boolean> SSA_LSRA = new DerivedOptionValue<>(new OptionSupplier<Boolean>() {
-
-        private static final long serialVersionUID = 9115795480259228194L;
-
-        public Boolean get() {
-            return SSA_LIR.getValue() && !SSADestructionPhase.Options.LIREagerSSADestruction.getValue();
-        }
-    });
-
     @Override
     protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, SpillMoveFactory spillMoveFactory,
                     RegisterAllocationConfig registerAllocationConfig) {
         final LinearScan allocator;
-        if (LinearScanPhase.SSA_LSRA.getValue()) {
-            allocator = new SSALinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, linearScanOrder);
-        } else {
-            allocator = new LinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, linearScanOrder);
+        switch (LinearScanVariant.getValue()) {
+            case SSA_LSRA:
+                allocator = new SSALinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, linearScanOrder);
+                break;
+            case NONSSA_LSAR:
+                allocator = new LinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, linearScanOrder);
+                break;
+            default:
+                throw JVMCIError.shouldNotReachHere();
         }
         allocator.allocate(target, lirGenRes, codeEmittingOrder, linearScanOrder, spillMoveFactory, registerAllocationConfig);
     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanRegisterAllocationPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanResolveDataFlowPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
 import com.oracle.graal.compiler.common.cfg.*;
@@ -125,76 +125,84 @@
     void resolveDataFlow() {
         try (Indent indent = Debug.logAndIndent("resolve data flow")) {
 
-            int numBlocks = allocator.blockCount();
             MoveResolver moveResolver = allocator.createMoveResolver();
-            BitSet blockCompleted = new BitSet(numBlocks);
-            BitSet alreadyResolved = new BitSet(numBlocks);
+            BitSet blockCompleted = new BitSet(allocator.blockCount());
 
-            for (AbstractBlockBase<?> block : allocator.sortedBlocks) {
+            optimizeEmptyBlocks(moveResolver, blockCompleted);
+
+            resolveDataFlow0(moveResolver, blockCompleted);
 
-                // check if block has only one predecessor and only one successor
-                if (block.getPredecessorCount() == 1 && block.getSuccessorCount() == 1) {
-                    List<LIRInstruction> instructions = allocator.ir.getLIRforBlock(block);
-                    assert instructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
-                    assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block with successor must end with unconditional jump";
+        }
+    }
+
+    protected void optimizeEmptyBlocks(MoveResolver moveResolver, BitSet blockCompleted) {
+        for (AbstractBlockBase<?> block : allocator.sortedBlocks) {
 
-                    // check if block is empty (only label and branch)
-                    if (instructions.size() == 2) {
-                        AbstractBlockBase<?> pred = block.getPredecessors().iterator().next();
-                        AbstractBlockBase<?> sux = block.getSuccessors().iterator().next();
+            // check if block has only one predecessor and only one successor
+            if (block.getPredecessorCount() == 1 && block.getSuccessorCount() == 1) {
+                List<LIRInstruction> instructions = allocator.ir.getLIRforBlock(block);
+                assert instructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
+                assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block with successor must end with unconditional jump";
 
-                        // prevent optimization of two consecutive blocks
-                        if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) {
-                            if (Debug.isLogEnabled()) {
-                                Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
-                            }
+                // check if block is empty (only label and branch)
+                if (instructions.size() == 2) {
+                    AbstractBlockBase<?> pred = block.getPredecessors().iterator().next();
+                    AbstractBlockBase<?> sux = block.getSuccessors().iterator().next();
 
-                            blockCompleted.set(block.getLinearScanNumber());
+                    // prevent optimization of two consecutive blocks
+                    if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) {
+                        if (Debug.isLogEnabled()) {
+                            Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
+                        }
 
-                            /*
-                             * Directly resolve between pred and sux (without looking at the empty
-                             * block between).
-                             */
-                            resolveCollectMappings(pred, sux, block, moveResolver);
-                            if (moveResolver.hasMappings()) {
-                                moveResolver.setInsertPosition(instructions, 1);
-                                moveResolver.resolveAndAppendMoves();
-                            }
+                        blockCompleted.set(block.getLinearScanNumber());
+
+                        /*
+                         * Directly resolve between pred and sux (without looking at the empty block
+                         * between).
+                         */
+                        resolveCollectMappings(pred, sux, block, moveResolver);
+                        if (moveResolver.hasMappings()) {
+                            moveResolver.setInsertPosition(instructions, 1);
+                            moveResolver.resolveAndAppendMoves();
                         }
                     }
                 }
             }
+        }
+    }
 
-            for (AbstractBlockBase<?> fromBlock : allocator.sortedBlocks) {
-                if (!blockCompleted.get(fromBlock.getLinearScanNumber())) {
-                    alreadyResolved.clear();
-                    alreadyResolved.or(blockCompleted);
+    protected void resolveDataFlow0(MoveResolver moveResolver, BitSet blockCompleted) {
+        BitSet alreadyResolved = new BitSet(allocator.blockCount());
+        for (AbstractBlockBase<?> fromBlock : allocator.sortedBlocks) {
+            if (!blockCompleted.get(fromBlock.getLinearScanNumber())) {
+                alreadyResolved.clear();
+                alreadyResolved.or(blockCompleted);
 
-                    for (AbstractBlockBase<?> toBlock : fromBlock.getSuccessors()) {
+                for (AbstractBlockBase<?> toBlock : fromBlock.getSuccessors()) {
 
-                        /*
-                         * Check for duplicate edges between the same blocks (can happen with switch
-                         * blocks).
-                         */
-                        if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
-                            if (Debug.isLogEnabled()) {
-                                Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
-                            }
+                    /*
+                     * Check for duplicate edges between the same blocks (can happen with switch
+                     * blocks).
+                     */
+                    if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
+                        if (Debug.isLogEnabled()) {
+                            Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
+                        }
 
-                            alreadyResolved.set(toBlock.getLinearScanNumber());
+                        alreadyResolved.set(toBlock.getLinearScanNumber());
 
-                            // collect all intervals that have been split between
-                            // fromBlock and toBlock
-                            resolveCollectMappings(fromBlock, toBlock, null, moveResolver);
-                            if (moveResolver.hasMappings()) {
-                                resolveFindInsertPos(fromBlock, toBlock, moveResolver);
-                                moveResolver.resolveAndAppendMoves();
-                            }
+                        // collect all intervals that have been split between
+                        // fromBlock and toBlock
+                        resolveCollectMappings(fromBlock, toBlock, null, moveResolver);
+                        if (moveResolver.hasMappings()) {
+                            resolveFindInsertPos(fromBlock, toBlock, moveResolver);
+                            moveResolver.resolveAndAppendMoves();
                         }
                     }
                 }
             }
-
         }
     }
+
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanWalker.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScanWalker.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,7 +29,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig.AllocatableRegisters;
@@ -237,10 +237,10 @@
         }
     }
 
-    void spillCollectActiveAny() {
+    void spillCollectActiveAny(RegisterPriority registerPriority) {
         Interval interval = activeLists.get(RegisterBinding.Any);
         while (interval != Interval.EndMarker) {
-            setUsePos(interval, Math.min(interval.nextUsage(RegisterPriority.LiveAtLoopEnd, currentPosition), interval.to()), false);
+            setUsePos(interval, Math.min(interval.nextUsage(registerPriority, currentPosition), interval.to()), false);
             interval = interval.next;
         }
     }
@@ -485,7 +485,16 @@
     void splitForSpilling(Interval interval) {
         // calculate allowed range of splitting position
         int maxSplitPos = currentPosition;
-        int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from());
+        int previousUsage = interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos);
+        if (previousUsage == currentPosition) {
+            /*
+             * If there is a usage with ShouldHaveRegister priority at the current position fall
+             * back to MustHaveRegister priority. This only happens if register priority was
+             * downgraded to MustHaveRegister in #allocLockedRegister.
+             */
+            previousUsage = interval.previousUsage(RegisterPriority.MustHaveRegister, maxSplitPos);
+        }
+        int minSplitPos = Math.max(previousUsage + 1, interval.from());
 
         try (Indent indent = Debug.logAndIndent("splitting and spilling interval %s between %d and %d", interval, minSplitPos, maxSplitPos)) {
 
@@ -771,19 +780,6 @@
     void allocLockedRegister(Interval interval) {
         try (Indent indent = Debug.logAndIndent("alloc locked register: need to split and spill to get register for %s", interval)) {
 
-            // collect current usage of registers
-            initUseLists(false);
-            spillExcludeActiveFixed();
-            // spillBlockUnhandledFixed(cur);
-            assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0";
-            spillBlockInactiveFixed(interval);
-            spillCollectActiveAny();
-            spillCollectInactiveAny(interval);
-
-            if (Debug.isLogEnabled()) {
-                printRegisterState();
-            }
-
             // the register must be free at least until this position
             int firstUsage = interval.firstUsage(RegisterPriority.MustHaveRegister);
             int firstShouldHaveUsage = interval.firstUsage(RegisterPriority.ShouldHaveRegister);
@@ -791,37 +787,73 @@
             int intervalTo = interval.to();
             assert regNeededUntil > 0 && regNeededUntil < Integer.MAX_VALUE : "interval has no use";
 
-            Register reg = null;
-            Register ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null;
-            for (Register availableReg : availableRegs) {
-                int number = availableReg.number;
-                if (availableReg.equals(ignore)) {
-                    // this register must be ignored
-                } else if (usePos[number] > regNeededUntil) {
-                    if (reg == null || (usePos[number] > usePos[reg.number])) {
-                        reg = availableReg;
+            Register reg;
+            Register ignore;
+            /*
+             * In the common case we don't spill registers that have _any_ use position that is
+             * closer than the next use of the current interval, but if we can't spill the current
+             * interval we weaken this strategy and also allow spilling of intervals that have a
+             * non-mandatory requirements (no MustHaveRegister use position).
+             */
+            for (RegisterPriority registerPriority = RegisterPriority.LiveAtLoopEnd; true; registerPriority = RegisterPriority.MustHaveRegister) {
+                // collect current usage of registers
+                initUseLists(false);
+                spillExcludeActiveFixed();
+                // spillBlockUnhandledFixed(cur);
+                assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0";
+                spillBlockInactiveFixed(interval);
+                spillCollectActiveAny(registerPriority);
+                spillCollectInactiveAny(interval);
+                if (Debug.isLogEnabled()) {
+                    printRegisterState();
+                }
+
+                reg = null;
+                ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null;
+
+                for (Register availableReg : availableRegs) {
+                    int number = availableReg.number;
+                    if (availableReg.equals(ignore)) {
+                        // this register must be ignored
+                    } else if (usePos[number] > regNeededUntil) {
+                        if (reg == null || (usePos[number] > usePos[reg.number])) {
+                            reg = availableReg;
+                        }
                     }
                 }
-            }
 
-            int regUsePos = (reg == null ? 0 : usePos[reg.number]);
-            if (regUsePos <= firstShouldHaveUsage) {
-                if (Debug.isLogEnabled()) {
-                    Debug.log("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, regUsePos);
-                }
+                int regUsePos = (reg == null ? 0 : usePos[reg.number]);
+                if (regUsePos <= firstShouldHaveUsage) {
+                    if (Debug.isLogEnabled()) {
+                        Debug.log("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, regUsePos);
+                    }
 
-                if (firstUsage <= interval.from() + 1) {
-                    String description = "cannot spill interval (" + interval + ") that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage +
-                                    ", interval.from()=" + interval.from() + "; already used candidates: " + Arrays.toString(availableRegs);
-                    // assign a reasonable register and do a bailout in product mode to avoid errors
-                    allocator.assignSpillSlot(interval);
-                    Debug.dump(allocator.ir, description);
-                    allocator.printIntervals(description);
-                    throw new OutOfRegistersException("LinearScan: no register found", description);
+                    if (firstUsage <= interval.from() + 1) {
+                        if (registerPriority.equals(RegisterPriority.LiveAtLoopEnd)) {
+                            /*
+                             * Tool of last resort: we can not spill the current interval so we try
+                             * to spill an active interval that has a usage but do not require a
+                             * register.
+                             */
+                            Debug.log("retry with register priority must have register");
+                            continue;
+                        }
+                        String description = "cannot spill interval (" + interval + ") that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage +
+                                        ", interval.from()=" + interval.from() + "; already used candidates: " + Arrays.toString(availableRegs);
+                        /*
+                         * assign a reasonable register and do a bailout in product mode to avoid
+                         * errors
+                         */
+                        allocator.assignSpillSlot(interval);
+                        Debug.dump(allocator.ir, description);
+                        allocator.printIntervals(description);
+                        throw new OutOfRegistersException("LinearScan: no register found", description);
+                    }
+
+                    splitAndSpillInterval(interval);
+                    return;
                 }
-
-                splitAndSpillInterval(interval);
-                return;
+                break;
             }
 
             boolean needSplit = blockPos[reg.number] <= intervalTo;
@@ -842,6 +874,7 @@
 
             // perform splitting and spilling for all affected intervals
             splitAndSpillIntersectingIntervals(reg);
+            return;
         }
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,7 +29,7 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.lir.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/OptimizingLinearScanWalker.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/OptimizingLinearScanWalker.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,16 +22,17 @@
  */
 package com.oracle.graal.lir.alloc.lsra;
 
+import static jdk.internal.jvmci.code.ValueUtil.*;
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
-import static jdk.internal.jvmci.code.ValueUtil.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.lir.alloc.lsra.Interval.RegisterBinding;
 import com.oracle.graal.lir.alloc.lsra.Interval.RegisterBindingLists;
+import com.oracle.graal.lir.alloc.lsra.Interval.RegisterPriority;
 import com.oracle.graal.lir.alloc.lsra.Interval.State;
 
 public class OptimizingLinearScanWalker extends LinearScanWalker {
@@ -209,7 +210,7 @@
         // spillBlockUnhandledFixed(cur);
         assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0";
         spillBlockInactiveFixed(interval);
-        spillCollectActiveAny();
+        spillCollectActiveAny(RegisterPriority.LiveAtLoopEnd);
         spillCollectInactiveAny(interval);
 
         if (Debug.isLogEnabled()) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/RegisterVerifier.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/RegisterVerifier.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,8 +28,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.Scope;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinarScanResolveDataFlowPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinarScanResolveDataFlowPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScan.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScan.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,8 +25,8 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScanEliminateSpillMovePhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScanEliminateSpillMovePhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.lir.alloc.lsra;
 
+import static com.oracle.graal.compiler.common.BackendOptions.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
 import static jdk.internal.jvmci.code.ValueUtil.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.*;
@@ -45,7 +46,7 @@
 
     @Override
     protected boolean canEliminateSpillMove(AbstractBlockBase<?> block, MoveOp move) {
-        assert isVariable(move.getResult()) || LinearScanPhase.SSA_LSRA.getValue() : "Move should not be produced in a non-SSA compilation: " + move;
+        assert isVariable(move.getResult()) || LinearScanVariant.getValue() == LSRAVariant.SSA_LSRA : "Move should not be produced in a non-SSA compilation: " + move;
 
         if (super.canEliminateSpillMove(block, move)) {
             // SSA Linear Scan might introduce moves to stack slots
@@ -60,9 +61,7 @@
     }
 
     private boolean isPhiResolutionMove(AbstractBlockBase<?> block, MoveOp move, Interval toInterval) {
-        if (!LinearScanPhase.SSA_LSRA.getValue()) {
-            return false;
-        }
+        assert LinearScanVariant.getValue() == LSRAVariant.SSA_LSRA;
         if (!toInterval.isSplitParent()) {
             return false;
         }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScanLifetimeAnalysisPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSALinearScanLifetimeAnalysisPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.lir.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,12 +31,15 @@
 import jdk.internal.jvmci.code.CompilationResult.*;
 import jdk.internal.jvmci.code.DataSection.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.framemap.*;
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilderFactory.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilderFactory.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,6 +25,7 @@
 import jdk.internal.jvmci.code.*;
 
 import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.lir.framemap.*;
 
 /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,8 +29,8 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTreeAnalyzer.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantTreeAnalyzer.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.constopt.ConstantTree.Flags;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/debug/LIRGenerationDebugContext.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/debug/LIRGenerationDebugContext.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.lir.debug;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.lir.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/LocationMarker.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/dfa/LocationMarker.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/framemap/FrameMapBuilderImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,8 +28,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,6 +30,7 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
+
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,8 +26,8 @@
 import java.util.regex.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PreAllocationOptimizationStage.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/PreAllocationOptimizationStage.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,13 +24,14 @@
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.constopt.*;
 import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext;
 import com.oracle.graal.lir.ssa.*;
 
 public class PreAllocationOptimizationStage extends LIRPhaseSuite<PreAllocationOptimizationContext> {
     public PreAllocationOptimizationStage() {
-        if (SSA_LIR.getValue() && SSADestructionPhase.Options.LIREagerSSADestruction.getValue()) {
+        if (SSA_LIR.getValue() && BackendOptions.UserOptions.LIREagerSSADestruction.getValue()) {
             appendPhase(new SSADestructionPhase());
         }
         if (ConstantLoadOptimization.Options.LIROptConstantLoadOptimization.getValue()) {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ssa/SSADestructionPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ssa/SSADestructionPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,6 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.lir.*;
@@ -34,13 +33,6 @@
 
 public final class SSADestructionPhase extends PreAllocationOptimizationPhase {
 
-    public static class Options {
-        // @formatter:off
-        @Option(help = "Destruct SSA LIR eagerly (before other LIR phases).", type = OptionType.Debug)
-        public static final OptionValue<Boolean> LIREagerSSADestruction = new OptionValue<>(false);
-        // @formatter:on
-    }
-
     @Override
     protected <B extends AbstractBlockBase<B>> void run(TargetDescription target, LIRGenerationResult lirGenRes, List<B> codeEmittingOrder, List<B> linearScanOrder, LIRGeneratorTool lirGen) {
         LIR lir = lirGenRes.getLIR();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ssa/SSAVerifier.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/ssa/SSAVerifier.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,8 +27,8 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/FixPointIntervalBuilder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,8 +29,8 @@
 import java.util.function.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
@@ -77,8 +77,10 @@
     }
 
     public void allocateStackSlots(FrameMapBuilderTool builder, LIRGenerationResult res) {
-        try (DebugCloseable t = MainTimer.start()) {
-            new Allocator(res.getLIR(), builder).allocate();
+        if (builder.getNumberOfStackSlots() > 0) {
+            try (DebugCloseable t = MainTimer.start()) {
+                new Allocator(res.getLIR(), builder).allocate();
+            }
         }
     }
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/SimpleStackSlotAllocator.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/SimpleStackSlotAllocator.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,8 +28,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import com.oracle.graal.compiler.common.alloc.*;
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/StackSlotAllocator.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/StackSlotAllocator.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.lir.stackslotalloc;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.lir.framemap.*;
 import com.oracle.graal.lir.gen.*;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopFullUnrollPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.loop.phases;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopPeelingPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopPeelingPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.loop.phases;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopUnswitchingPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopUnswitchingPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.loop.*;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/ReassociateInvariantPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/ReassociateInvariantPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.loop.phases;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMergeNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ArithmeticOperation.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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.nodes;
+
+/**
+ * An {@code ArithmeticOperation} is an operation that does primitive value arithmetic without side
+ * effect.
+ */
+public interface ArithmeticOperation {
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.bytecode.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphDecoder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphEncoder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GraphEncoder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.util.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.meta.JavaTypeProfile.*;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/NamedLocationIdentity.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,131 @@
+/*
+ * 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.nodes;
+
+import java.util.*;
+
+import jdk.internal.jvmci.meta.*;
+import jdk.internal.jvmci.meta.Kind.FormatWithToString;
+
+/**
+ * A {@link LocationIdentity} with a name.
+ */
+public class NamedLocationIdentity extends LocationIdentity implements FormatWithToString {
+
+    /**
+     * Map for asserting all {@link NamedLocationIdentity} instances have a unique name.
+     */
+    static class DB {
+        private static final HashSet<String> map = new HashSet<>();
+
+        static boolean checkUnique(String name) {
+            if (!map.add(name)) {
+                throw new AssertionError("identity " + name + " already exists");
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Denotes the location of a value that is guaranteed to be unchanging.
+     */
+    public static final LocationIdentity FINAL_LOCATION = NamedLocationIdentity.immutable("FINAL_LOCATION");
+
+    /**
+     * Denotes the location of the length field of a Java array.
+     */
+    public static final LocationIdentity ARRAY_LENGTH_LOCATION = NamedLocationIdentity.immutable("[].length");
+
+    public static LocationIdentity any() {
+        return ANY_LOCATION;
+    }
+
+    private final String name;
+    private final boolean immutable;
+
+    protected NamedLocationIdentity(String name, boolean immutable) {
+        this.name = name;
+        this.immutable = immutable;
+        assert DB.checkUnique(name);
+    }
+
+    /**
+     * Creates a named unique location identity for read and write operations against mutable
+     * memory.
+     *
+     * @param name the name of the new location identity
+     */
+    public static NamedLocationIdentity mutable(String name) {
+        return create(name, false);
+    }
+
+    /**
+     * Creates a named unique location identity for read operations against immutable memory.
+     * Immutable memory will never have a visible write in the graph, which is more restictive than
+     * Java final.
+     *
+     * @param name the name of the new location identity
+     */
+    public static NamedLocationIdentity immutable(String name) {
+        return create(name, true);
+    }
+
+    /**
+     * Creates a named unique location identity for read and write operations.
+     *
+     * @param name the name of the new location identity
+     * @param immutable true if the location is immutable
+     */
+    private static NamedLocationIdentity create(String name, boolean immutable) {
+        return new NamedLocationIdentity(name, immutable);
+    }
+
+    @Override
+    public boolean isImmutable() {
+        return immutable;
+    }
+
+    @Override
+    public String toString() {
+        return name + (isImmutable() ? ":final" : "");
+    }
+
+    /**
+     * Returns the named location identity for an array of the given element kind. Array accesses of
+     * the same kind must have the same location identity unless an alias analysis guarantees that
+     * two distinct arrays are accessed.
+     */
+    public static LocationIdentity getArrayLocation(Kind elementKind) {
+        return ARRAY_LOCATIONS.get(elementKind);
+    }
+
+    private static final EnumMap<Kind, LocationIdentity> ARRAY_LOCATIONS = initArrayLocations();
+
+    private static EnumMap<Kind, LocationIdentity> initArrayLocations() {
+        EnumMap<Kind, LocationIdentity> result = new EnumMap<>(Kind.class);
+        for (Kind kind : Kind.values()) {
+            result.put(kind, NamedLocationIdentity.mutable("Array: " + kind.getJavaName()));
+        }
+        return result;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.function.*;
 
 import jdk.internal.jvmci.compiler.Compiler;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.meta.Assumptions.Assumption;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeCheckHints.java	Fri Jul 24 08:33:42 2015 +0200
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import java.util.*;
+
+import jdk.internal.jvmci.meta.*;
+import jdk.internal.jvmci.meta.Assumptions.*;
+import jdk.internal.jvmci.meta.JavaTypeProfile.*;
+
+/**
+ * Utility for deriving hint types for a type check instruction (e.g. checkcast or instanceof) based
+ * on the target type of the check and any profiling information available for the instruction.
+ */
+public class TypeCheckHints {
+
+    /**
+     * A receiver type profiled in a type check instruction.
+     */
+    public static class Hint {
+
+        /**
+         * A type seen while profiling a type check instruction.
+         */
+        public final ResolvedJavaType type;
+
+        /**
+         * Specifies if {@link #type} is a sub-type of the checked type.
+         */
+        public final boolean positive;
+
+        Hint(ResolvedJavaType type, boolean positive) {
+            this.type = type;
+            this.positive = positive;
+        }
+    }
+
+    private static final Hint[] NO_HINTS = {};
+
+    /**
+     * If non-null, then this is the only type that could pass the type check because the target of
+     * the type check is a final class or has been speculated to be a final class and this value is
+     * the only concrete subclass of the target type.
+     */
+    public final ResolvedJavaType exact;
+
+    /**
+     * The most likely types that the type check instruction will see.
+     */
+    public final Hint[] hints;
+
+    /**
+     * The profile from which this information was derived.
+     */
+    public final JavaTypeProfile profile;
+
+    /**
+     * The total probability that the type check will hit one of the types in {@link #hints}.
+     */
+    public final double hintHitProbability;
+
+    /**
+     * Derives hint information for use when generating the code for a type check instruction.
+     *
+     * @param targetType the target type of the type check
+     * @param profile the profiling information available for the instruction (if any)
+     * @param assumptions the object in which speculations are recorded. This is null if
+     *            speculations are not supported.
+     * @param minHintHitProbability if the probability that the type check will hit one of the
+     *            profiled types (up to {@code maxHints}) is below this value, then {@link #hints}
+     *            will be null
+     * @param maxHints the maximum length of {@link #hints}
+     */
+    public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) {
+        this.profile = profile;
+        if (targetType != null && targetType.isLeaf()) {
+            exact = targetType;
+        } else {
+            if (assumptions != null) {
+                AssumptionResult<ResolvedJavaType> leafConcreteSubtype = targetType == null ? null : targetType.findLeafConcreteSubtype();
+                if (leafConcreteSubtype != null) {
+                    assumptions.record(leafConcreteSubtype);
+                    exact = leafConcreteSubtype.getResult();
+                } else {
+                    exact = null;
+                }
+            } else {
+                exact = null;
+            }
+        }
+        Double[] hitProbability = {null};
+        this.hints = makeHints(targetType, profile, minHintHitProbability, maxHints, hitProbability);
+        this.hintHitProbability = hitProbability[0];
+    }
+
+    private static Hint[] makeHints(ResolvedJavaType targetType, JavaTypeProfile profile, double minHintHitProbability, int maxHints, Double[] hitProbability) {
+        double hitProb = 0.0d;
+        Hint[] hintsBuf = NO_HINTS;
+        if (profile != null) {
+            double notRecordedTypes = profile.getNotRecordedProbability();
+            ProfiledType[] ptypes = profile.getTypes();
+            if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) {
+                hintsBuf = new Hint[ptypes.length];
+                int hintCount = 0;
+                for (ProfiledType ptype : ptypes) {
+                    if (targetType != null) {
+                        ResolvedJavaType hintType = ptype.getType();
+                        hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType));
+                        hitProb += ptype.getProbability();
+                    }
+                    if (hintCount == maxHints) {
+                        break;
+                    }
+                }
+                if (hitProb >= minHintHitProbability) {
+                    if (hintsBuf.length != hintCount || hintCount > maxHints) {
+                        hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount));
+                    }
+                } else {
+                    hintsBuf = NO_HINTS;
+                    hitProb = 0.0d;
+                }
+            }
+        }
+        hitProbability[0] = hitProb;
+        return hintsBuf;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.calc;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.calc.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BytecodeExceptionNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,6 +25,7 @@
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,6 +27,7 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ForeignCallDescriptors.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ForeignCallDescriptors.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import jdk.internal.jvmci.meta.*;
+import com.oracle.graal.compiler.common.spi.*;
 
 /**
  * The foreign call descriptors used by nodes in this package.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,11 +23,11 @@
 package com.oracle.graal.nodes.java;
 
 import static com.oracle.graal.nodes.java.ForeignCallDescriptors.*;
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.meta.Assumptions.*;
 
 import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodeinfo.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.memory;
 
+import static com.oracle.graal.nodes.NamedLocationIdentity.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.meta.*;
 
@@ -126,7 +127,7 @@
                     return ConstantNode.forConstant(read.stamp(), constant, metaAccess);
                 }
             }
-            if (locationIdentity.equals(LocationIdentity.ARRAY_LENGTH_LOCATION)) {
+            if (locationIdentity.equals(ARRAY_LENGTH_LOCATION)) {
                 ValueNode length = GraphUtil.arrayLength(object);
                 if (length != null) {
                     // TODO Does this need a PiCastNode to the positive range?
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ArithmeticLIRLowerable.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,9 +22,8 @@
  */
 package com.oracle.graal.nodes.spi;
 
-import jdk.internal.jvmci.code.*;
-
 import com.oracle.graal.lir.gen.*;
+import com.oracle.graal.nodes.*;
 
 public interface ArithmeticLIRLowerable extends ArithmeticOperation {
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.phases.common;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.type.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 
 import java.util.function.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 import java.util.*;
 import java.util.function.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 import java.util.Map.Entry;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchorsPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PushThroughPiPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PushThroughPiPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.phases.common;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/UseTrappingNullChecksPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Fri Jul 24 08:33:42 2015 +0200
@@ -32,7 +32,10 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.Scope;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.phases.common.inlining.info;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.ResolvedJavaType;
 import jdk.internal.jvmci.meta.Kind;
 import jdk.internal.jvmci.meta.DeoptimizationReason;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.type.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/GreedyInliningPolicy.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.meta.Assumptions.*;
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import java.util.regex.*;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/LazyName.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/LazyName.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.phases;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 /**
  * A name whose {@link String} value is computed only when it is needed. This is useful in
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.*;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 import java.util.function.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.*;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.phases.verify;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Fri Jul 24 08:33:42 2015 +0200
@@ -31,7 +31,7 @@
 import java.util.*;
 import java.util.Map.Entry;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,6 +29,9 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.service.*;
 
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraalDebugConfigCustomizer.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraalDebugConfigCustomizer.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,6 +23,9 @@
 package com.oracle.graal.printer;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.debug.*;
 import jdk.internal.jvmci.service.*;
 
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.printer;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static jdk.internal.jvmci.debug.JVMCIDebugConfig.*;
+import static com.oracle.graal.debug.GraalDebugConfig.*;
 
 import java.io.*;
 import java.net.*;
@@ -32,8 +32,10 @@
 import java.text.*;
 import java.util.*;
 
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
+
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 import java.util.concurrent.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.options.*;
 
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.replacements.amd64;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,12 +23,12 @@
 package com.oracle.graal.replacements.amd64;
 
 import jdk.internal.jvmci.amd64.*;
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.compiler.target.Backend.*;
 import static com.oracle.graal.replacements.amd64.AMD64MathIntrinsicNode.Operation.*;
 import sun.misc.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.graphbuilderconf.InvocationPlugin.Receiver;
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64MathSubstitutions.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64MathSubstitutions.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.replacements.amd64;
 
-import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.compiler.target.Backend.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.extended.*;
--- a/graal/com.oracle.graal.replacements.sparc/src/com/oracle/graal/replacements/sparc/SPARCGraphBuilderPlugins.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.sparc/src/com/oracle/graal/replacements/sparc/SPARCGraphBuilderPlugins.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,10 +22,10 @@
  */
 package com.oracle.graal.replacements.sparc;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.compiler.target.Backend.*;
 
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.graphbuilderconf.InvocationPlugins.Registration;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DerivedOopTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DerivedOopTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -97,10 +97,13 @@
 
     @Test
     public void testFieldOffset() {
-        Result r = new Result();
-        test("fieldOffsetSnippet", r, 16L);
+        // Run a couple times to encourage objects to move
+        for (int i = 0; i < 4; i++) {
+            Result r = new Result();
+            test("fieldOffsetSnippet", r, 16L);
 
-        Assert.assertEquals(r.beforeGC.delta(), r.afterGC.delta());
+            Assert.assertEquals(r.beforeGC.delta(), r.afterGC.delta());
+        }
     }
 
     static long getRawPointer(Object obj) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,8 +25,8 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.CompilationResult.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,8 +25,8 @@
 import java.lang.reflect.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.replacements.test;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import org.junit.*;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CachingPEGraphDecoder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/CachingPEGraphDecoder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,7 +27,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graphbuilderconf.*;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,11 +22,11 @@
  */
 package com.oracle.graal.replacements;
 
+import static com.oracle.graal.nodes.NamedLocationIdentity.*;
 import static com.oracle.graal.nodes.java.ArrayLengthNode.*;
 import static jdk.internal.jvmci.code.MemoryBarriers.*;
 import static jdk.internal.jvmci.meta.DeoptimizationAction.*;
 import static jdk.internal.jvmci.meta.DeoptimizationReason.*;
-import static jdk.internal.jvmci.meta.LocationIdentity.*;
 
 import java.util.*;
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Log.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Log.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.compiler.common.spi.*;
 
 //JaCoCo Exclude
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -27,13 +27,15 @@
 import java.lang.reflect.*;
 import java.util.*;
 
-import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.internal.*;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
+
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPlugin.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPlugin.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,11 +28,11 @@
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.nodeinfo.*;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,7 +28,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri Jul 24 08:33:42 2015 +0200
@@ -36,8 +36,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 import jdk.internal.jvmci.options.OptionValue.*;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
 import static com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates.*;
 import static java.util.FormattableFlags.*;
-import static jdk.internal.jvmci.debug.Debug.*;
+import static com.oracle.graal.debug.Debug.*;
 import static jdk.internal.jvmci.meta.LocationIdentity.*;
 
 import java.lang.reflect.*;
@@ -38,7 +38,10 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.Scope;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicArrayCopyNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicArrayCopyNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.replacements.nodes;
 
 import static jdk.internal.jvmci.meta.LocationIdentity.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.type.*;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import static jdk.internal.jvmci.code.BytecodeFrame.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.api.replacements.*;
--- a/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64OptimizedCallTargetInstrumentationFactory.java	Fri Jul 24 08:33:42 2015 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.amd64.AMD64Assembler.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
--- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java	Fri Jul 24 08:33:42 2015 +0200
@@ -37,6 +37,7 @@
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.framemap.*;
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Fri Jul 24 08:33:42 2015 +0200
@@ -33,17 +33,18 @@
 import java.util.stream.*;
 
 import jdk.internal.jvmci.code.*;
-import jdk.internal.jvmci.code.CallingConvention.*;
+import jdk.internal.jvmci.code.CallingConvention.Type;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.compiler.*;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.service.*;
 
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graphbuilderconf.*;
 import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
 import com.oracle.graal.hotspot.*;
@@ -90,9 +91,9 @@
 
         // Create compilation queue.
         CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
-            public JVMCIDebugConfig getDebugConfig() {
+            public GraalDebugConfig getDebugConfig() {
                 if (Debug.isEnabled()) {
-                    JVMCIDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
+                    GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
                     debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
                     return debugConfig;
                 } else {
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,6 +30,7 @@
 import jdk.internal.jvmci.hotspot.*;
 
 import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.common.spi.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.asm.*;
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionHandle.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionHandle.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,8 +26,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.nfi.api.*;
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterface.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterface.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,8 +24,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.CallingConvention.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.hotspot.*;
 import jdk.internal.jvmci.meta.*;
 import static com.oracle.graal.truffle.hotspot.nfi.NativeCallStubGraphBuilder.*;
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.truffle.test;
 
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 
 import org.junit.*;
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Fri Jul 24 08:33:42 2015 +0200
@@ -30,7 +30,10 @@
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.stack.*;
 import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.Scope;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.service.*;
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,8 +29,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.options.*;
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java	Fri Jul 24 08:33:42 2015 +0200
@@ -29,8 +29,8 @@
 
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.code.CallingConvention.*;
-import jdk.internal.jvmci.debug.*;
-import jdk.internal.jvmci.debug.Debug.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
 import jdk.internal.jvmci.meta.*;
 import jdk.internal.jvmci.meta.Assumptions.Assumption;
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.truffle;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.truffle.api.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleTreeDumpHandler.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.truffle;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java	Fri Jul 24 08:33:42 2015 +0200
@@ -26,7 +26,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Fri Jul 24 08:33:42 2015 +0200
@@ -25,7 +25,7 @@
 import java.util.*;
 
 import jdk.internal.jvmci.common.*;
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.cfg.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Fri Jul 24 08:33:42 2015 +0200
@@ -23,11 +23,11 @@
 package com.oracle.graal.virtual.phases.ea;
 
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
-import static jdk.internal.jvmci.debug.Debug.*;
+import static com.oracle.graal.debug.Debug.*;
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.graph.Graph.NodeEventScope;
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Fri Jul 24 08:33:42 2015 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
-import static jdk.internal.jvmci.meta.LocationIdentity.*;
+import static com.oracle.graal.nodes.NamedLocationIdentity.*;
 
 import java.util.*;
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Jul 24 08:33:42 2015 +0200
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import jdk.internal.jvmci.debug.*;
+import com.oracle.graal.debug.*;
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.compiler.common.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Thu Jul 23 22:17:57 2015 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Fri Jul 24 08:33:42 2015 +0200
@@ -28,6 +28,9 @@
 
 import jdk.internal.jvmci.common.*;
 import jdk.internal.jvmci.debug.*;
+
+import com.oracle.graal.debug.*;
+
 import jdk.internal.jvmci.meta.*;
 
 import com.oracle.graal.graph.*;
--- a/mx.graal/mx_graal.py	Thu Jul 23 22:17:57 2015 +0200
+++ b/mx.graal/mx_graal.py	Fri Jul 24 08:33:42 2015 +0200
@@ -191,16 +191,15 @@
         with Task('BootstrapWithExceptionEdges:fastdebug', tasks) as t:
             if t: vm(['-esa', '-XX:-TieredCompilation', '-G:+StressInvokeWithExceptionNode', '-version'])
 
+    registers = 'o0,o1,o2,o3,f8,f9,d32,d34' if platform.processor() == 'sparc' else 'rbx,r11,r10,r14,xmm3,xmm11,xmm14'
     with VM('jvmci', 'product'):
         with Task('BootstrapWithRegisterPressure:product', tasks) as t:
             if t:
-                registers = 'o0,o1,o2,o3,f8,f9,d32,d34' if platform.processor() == 'sparc' else 'rbx,r11,r10,r14,xmm3,xmm11,xmm14'
                 vm(['-XX:-TieredCompilation', '-G:RegisterPressure=' + registers, '-esa', '-version'])
 
     with VM('jvmci', 'product'):
         with Task('BootstrapNonSSAWithRegisterPressure:product', tasks) as t:
             if t:
-                registers = 'o0,o1,o2,o3,f8,f9,d32,d34' if platform.processor() == 'sparc' else 'rbx,r11,r10,r14,xmm3,xmm11,xmm14'
                 vm(['-XX:-TieredCompilation', '-G:-SSA_LIR', '-G:RegisterPressure=' + registers, '-esa', '-version'])
 
     with VM('jvmci', 'product'):
--- a/mx.graal/suite.py	Thu Jul 23 22:17:57 2015 +0200
+++ b/mx.graal/suite.py	Fri Jul 24 08:33:42 2015 +0200
@@ -265,8 +265,10 @@
       "subDir" : "graal",
       "sourceDirs" : ["src"],
       "dependencies" : [
+        "com.oracle.graal.debug",
         "com.oracle.graal.nodeinfo",
         "com.oracle.graal.compiler.common",
+        "com.oracle.graal.debug",
         "com.oracle.graal.api.collections",
         "com.oracle.graal.api.runtime",
       ],
@@ -338,6 +340,7 @@
       "dependencies" : [
         "com.oracle.graal.code",
         "com.oracle.graal.test",
+        "jvmci:JVMCI_API",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.8",
@@ -361,6 +364,7 @@
       "sourceDirs" : ["src"],
       "dependencies" : [
         "com.oracle.graal.compiler.common",
+        "com.oracle.graal.debug",
         "com.oracle.graal.asm",
       ],
       "annotationProcessors" : ["jvmci:JVMCI_OPTIONS_PROCESSOR"],