changeset 13197:8569b9e047cd

change debug scopes implementation to prevent extra frames related to mechanism being added to call stack
author Doug Simon <doug.simon@oracle.com>
date Sat, 30 Nov 2013 01:16:55 +0100
parents e343d4623e47
children 9a971210a55a
files graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java
diffstat 46 files changed, 1298 insertions(+), 1425 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.hsail.*;
 import com.oracle.graal.hsail.*;
 import com.oracle.graal.nodes.*;
@@ -332,14 +333,13 @@
     }
 
     private void test(final String snippet) {
-        Debug.scope("HSAILTestCode", new Runnable() {
+        try (Scope s = Debug.scope("HSAILCodeGen")) {
             StructuredGraph graph = parse(snippet);
-
-            public void run() {
-                HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph);
-                Debug.log("HSAIL code generated for %s:%n%s", snippet, compResult.getHSAILCode());
-            }
-        });
+            HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph);
+            Debug.log("HSAIL code generated for %s:%n%s", snippet, compResult.getHSAILCode());
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     public static void nBodySpill(float[] inxyz, float[] outxyz, float[] invxyz, float[] outvxyz, int gid) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,7 +25,6 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.debug.*;
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -317,33 +316,27 @@
     }
 
     private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) {
-        Debug.scope("BoxingEliminationTest " + snippet, new DebugDumpScope(snippet), new Runnable() {
-
-            @Override
-            public void run() {
-                graph = parse(snippet);
+        graph = parse(snippet);
 
-                Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                if (loopPeeling) {
-                    new LoopTransformHighPhase().apply(graph);
-                }
-                new DeadCodeEliminationPhase().apply(graph);
-                canonicalizer.apply(graph, context);
-                new PartialEscapePhase(false, canonicalizer).apply(graph, context);
+        Assumptions assumptions = new Assumptions(false);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
+        new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
+        if (loopPeeling) {
+            new LoopTransformHighPhase().apply(graph);
+        }
+        new DeadCodeEliminationPhase().apply(graph);
+        canonicalizer.apply(graph, context);
+        new PartialEscapePhase(false, canonicalizer).apply(graph, context);
 
-                new DeadCodeEliminationPhase().apply(graph);
-                canonicalizer.apply(graph, context);
+        new DeadCodeEliminationPhase().apply(graph);
+        canonicalizer.apply(graph, context);
 
-                StructuredGraph referenceGraph = parse(referenceSnippet);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context);
-                new DeadCodeEliminationPhase().apply(referenceGraph);
-                new CanonicalizerPhase(true).apply(referenceGraph, context);
+        StructuredGraph referenceGraph = parse(referenceSnippet);
+        new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context);
+        new DeadCodeEliminationPhase().apply(referenceGraph);
+        new CanonicalizerPhase(true).apply(referenceGraph, context);
 
-                assertEquals(referenceGraph, graph, excludeVirtual);
-            }
-        });
+        assertEquals(referenceGraph, graph, excludeVirtual);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
@@ -78,18 +79,17 @@
     }
 
     private void test(final String snippet) {
-        Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet), new Runnable() {
-
-            public void run() {
-                StructuredGraph graph = parse(snippet);
-                HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                new CanonicalizerPhase(true).apply(graph, context);
-                Debug.dump(graph, "Graph");
-                StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
-                Debug.dump(referenceGraph, "ReferenceGraph");
-                assertEquals(referenceGraph, graph);
-            }
-        });
+        try (Scope s = Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet))) {
+            StructuredGraph graph = parse(snippet);
+            HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+            new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
+            new CanonicalizerPhase(true).apply(graph, context);
+            Debug.dump(graph, "Graph");
+            StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
+            Debug.dump(referenceGraph, "ReferenceGraph");
+            assertEquals(referenceGraph, graph);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -22,12 +22,11 @@
  */
 package com.oracle.graal.compiler.test;
 
-import java.util.concurrent.*;
-
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.common.*;
@@ -108,18 +107,16 @@
 
     private StructuredGraph compileSnippet(final String snippet, final int checkcasts, final int afterCanon) {
         final StructuredGraph graph = parse(snippet);
-        return Debug.scope("NestedCheckCastsTest", graph, new Callable<StructuredGraph>() {
+        try (Scope s = Debug.scope("NestedCheckCastsTest", graph)) {
+            Debug.dump(graph, "After parsing: " + snippet);
+            Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count());
+            new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
+            Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count());
+            return graph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-            @Override
-            public StructuredGraph call() throws Exception {
-                Debug.dump(graph, "After parsing: " + snippet);
-                Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count());
-                new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
-                Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count());
-                return graph;
-            }
-
-        });
     }
 
     public static class A1 {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,7 +25,6 @@
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
-import java.util.concurrent.*;
 
 import org.junit.*;
 
@@ -119,46 +118,40 @@
 
         @Override
         protected Class<?> findClass(final String name) throws ClassNotFoundException {
-            return Debug.scope("FinalizableSubclassTest", new Callable<Class<?>>() {
+            String nameReplaced = name.replaceAll("AAAA", replaceTo);
+            if (cache.containsKey(nameReplaced)) {
+                return cache.get(nameReplaced);
+            }
 
-                @Override
-                public Class<?> call() throws Exception {
-                    String nameReplaced = name.replaceAll("AAAA", replaceTo);
-                    if (cache.containsKey(nameReplaced)) {
-                        return cache.get(nameReplaced);
-                    }
-
-                    // copy classfile to byte array
-                    byte[] classData = null;
-                    try {
-                        InputStream is = FinalizableSubclassTest.class.getResourceAsStream("FinalizableSubclassTest$" + name + ".class");
-                        assert is != null;
-                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            // copy classfile to byte array
+            byte[] classData = null;
+            try {
+                InputStream is = FinalizableSubclassTest.class.getResourceAsStream("FinalizableSubclassTest$" + name + ".class");
+                assert is != null;
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
-                        byte[] buf = new byte[1024];
-                        int size;
-                        while ((size = is.read(buf, 0, buf.length)) != -1) {
-                            baos.write(buf, 0, size);
-                        }
-                        baos.flush();
-                        classData = baos.toByteArray();
-                    } catch (IOException e) {
-                        Assert.fail("can't access class: " + name);
-                    }
-                    dumpStringsInByteArray(classData);
+                byte[] buf = new byte[1024];
+                int size;
+                while ((size = is.read(buf, 0, buf.length)) != -1) {
+                    baos.write(buf, 0, size);
+                }
+                baos.flush();
+                classData = baos.toByteArray();
+            } catch (IOException e) {
+                Assert.fail("can't access class: " + name);
+            }
+            dumpStringsInByteArray(classData);
 
-                    // replace all occurrences of "AAAA" in classfile
-                    int index = -1;
-                    while ((index = indexOfAAAA(classData, index + 1)) != -1) {
-                        replaceAAAA(classData, index, replaceTo);
-                    }
-                    dumpStringsInByteArray(classData);
+            // replace all occurrences of "AAAA" in classfile
+            int index = -1;
+            while ((index = indexOfAAAA(classData, index + 1)) != -1) {
+                replaceAAAA(classData, index, replaceTo);
+            }
+            dumpStringsInByteArray(classData);
 
-                    Class c = defineClass(null, classData, 0, classData.length);
-                    cache.put(nameReplaced, c);
-                    return c;
-                }
-            });
+            Class c = defineClass(null, classData, 0, classData.length);
+            cache.put(nameReplaced, c);
+            return c;
         }
 
         private static int indexOfAAAA(byte[] b, int index) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -54,35 +55,35 @@
     }
 
     private void test(final String snippet) {
-        Debug.scope("FloatingReadTest", new DebugDumpScope(snippet), new Runnable() {
+        try (Scope s = Debug.scope("FloatingReadTest", new DebugDumpScope(snippet))) {
 
-            public void run() {
-                StructuredGraph graph = parse(snippet);
-                PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                new FloatingReadPhase().apply(graph);
+            StructuredGraph graph = parse(snippet);
+            PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
+            new FloatingReadPhase().apply(graph);
 
-                ReturnNode returnNode = null;
-                MonitorExit monitorexit = null;
+            ReturnNode returnNode = null;
+            MonitorExit monitorexit = null;
 
-                for (Node n : graph.getNodes()) {
-                    if (n instanceof ReturnNode) {
-                        returnNode = (ReturnNode) n;
-                    } else if (n instanceof MonitorExit) {
-                        monitorexit = (MonitorExit) n;
-                    }
+            for (Node n : graph.getNodes()) {
+                if (n instanceof ReturnNode) {
+                    returnNode = (ReturnNode) n;
+                } else if (n instanceof MonitorExit) {
+                    monitorexit = (MonitorExit) n;
                 }
+            }
 
-                Debug.dump(graph, "After lowering");
+            Debug.dump(graph, "After lowering");
 
-                Assert.assertNotNull(returnNode);
-                Assert.assertNotNull(monitorexit);
-                Assert.assertTrue(returnNode.result() instanceof FloatingReadNode);
+            Assert.assertNotNull(returnNode);
+            Assert.assertNotNull(monitorexit);
+            Assert.assertTrue(returnNode.result() instanceof FloatingReadNode);
 
-                FloatingReadNode read = (FloatingReadNode) returnNode.result();
+            FloatingReadNode read = (FloatingReadNode) returnNode.result();
 
-                assertOrderedAfterSchedule(graph, read, (Node) monitorexit);
-            }
-        });
+            assertOrderedAfterSchedule(graph, read, (Node) monitorexit);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -29,7 +29,6 @@
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
-import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
 import org.junit.*;
@@ -42,6 +41,7 @@
 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.graph.*;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.java.*;
@@ -113,6 +113,20 @@
         DebugEnvironment.initialize(System.out);
     }
 
+    private Scope debugScope;
+
+    @Before
+    public void beforeTest() {
+        assert debugScope == null;
+        debugScope = Debug.scope(getClass().getSimpleName());
+    }
+
+    @After
+    public void afterTest() {
+        debugScope.close();
+        debugScope = null;
+    }
+
     protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
         assertEquals(expected, graph, false);
     }
@@ -529,49 +543,48 @@
 
         final int id = compilationId.incrementAndGet();
 
-        InstalledCode installedCode = Debug.scope("Compiling", new Object[]{new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() {
-
-            public InstalledCode call() throws Exception {
-                final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
-                if (printCompilation) {
-                    TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature()));
-                }
-                long start = System.currentTimeMillis();
-                PhasePlan phasePlan = new PhasePlan();
-                GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
-                phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-                CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-                final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan,
-                                OptimisticOptimizations.ALL, new SpeculationLog(), getSuites(), new CompilationResult());
-                if (printCompilation) {
-                    TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
-                }
-                return Debug.scope("CodeInstall", new Object[]{getCodeCache(), method}, new Callable<InstalledCode>() {
+        InstalledCode installedCode = null;
+        try (Scope ds = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) {
+            final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
+            if (printCompilation) {
+                TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature()));
+            }
+            long start = System.currentTimeMillis();
+            PhasePlan phasePlan = new PhasePlan();
+            GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+            phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
+            CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
+            final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
+                            new SpeculationLog(), getSuites(), new CompilationResult());
+            if (printCompilation) {
+                TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
+            }
 
-                    @Override
-                    public InstalledCode call() throws Exception {
-                        InstalledCode code = addMethod(method, compResult);
-                        if (code == null) {
-                            throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", method));
-                        }
-                        if (Debug.isDumpEnabled()) {
-                            Debug.dump(new Object[]{compResult, code}, "After code installation");
+            try (Scope s = Debug.scope("CodeInstall", getCodeCache(), method)) {
+                InstalledCode code = addMethod(method, compResult);
+                if (code == null) {
+                    throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", method));
+                }
+                if (Debug.isDumpEnabled()) {
+                    Debug.dump(new Object[]{compResult, code}, "After code installation");
+                }
+                if (Debug.isLogEnabled()) {
+                    DisassemblerProvider dis = backend.getDisassembler();
+                    if (dis != null) {
+                        String text = dis.disassemble(code);
+                        if (text != null) {
+                            Debug.log("Code installed for %s%n%s", method, text);
                         }
-                        if (Debug.isLogEnabled()) {
-                            DisassemblerProvider dis = backend.getDisassembler();
-                            if (dis != null) {
-                                String text = dis.disassemble(code);
-                                if (text != null) {
-                                    Debug.log("Code installed for %s%n%s", method, text);
-                                }
-                            }
-                        }
+                    }
+                }
 
-                        return code;
-                    }
-                });
+                installedCode = code;
+            } catch (Throwable e) {
+                throw Debug.handle(e);
             }
-        });
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
         if (!forceCompile) {
             cache.put(method, installedCode);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.*;
@@ -136,12 +137,10 @@
         Assumptions assumptions = new Assumptions(false);
         new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
-        Debug.scope("Test", new DebugDumpScope("Test:" + snippet), new Runnable() {
-
-            @Override
-            public void run() {
-                assertEquals(referenceGraph, graph);
-            }
-        });
+        try (Scope s = Debug.scope("Test", new DebugDumpScope("Test:" + snippet))) {
+            assertEquals(referenceGraph, graph);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,12 +26,12 @@
 import static org.junit.Assert.*;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
@@ -579,47 +579,44 @@
 
     private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode, final MemoryScheduling memsched, final SchedulingStrategy schedulingStrategy) {
         final StructuredGraph graph = parse(snippet);
-        return Debug.scope("FloatingReadTest", graph, new Callable<SchedulePhase>() {
-
-            @Override
-            public SchedulePhase call() throws Exception {
-
-                try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS)) {
-                    Assumptions assumptions = new Assumptions(false);
-                    HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                    CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-                    canonicalizer.apply(graph, context);
-                    if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
-                        new InliningPhase(canonicalizer).apply(graph, context);
-                    }
-                    new LoweringPhase(canonicalizer).apply(graph, context);
-                    if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
-                        for (Node node : graph.getNodes()) {
-                            if (node instanceof StateSplit) {
-                                FrameState stateAfter = ((StateSplit) node).stateAfter();
-                                if (stateAfter != null) {
-                                    ((StateSplit) node).setStateAfter(null);
-                                    GraphUtil.killWithUnusedFloatingInputs(stateAfter);
-                                }
+        try (Scope d = Debug.scope("FloatingReadTest", graph)) {
+            try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS)) {
+                Assumptions assumptions = new Assumptions(false);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
+                canonicalizer.apply(graph, context);
+                if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
+                    new InliningPhase(canonicalizer).apply(graph, context);
+                }
+                new LoweringPhase(canonicalizer).apply(graph, context);
+                if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
+                    for (Node node : graph.getNodes()) {
+                        if (node instanceof StateSplit) {
+                            FrameState stateAfter = ((StateSplit) node).stateAfter();
+                            if (stateAfter != null) {
+                                ((StateSplit) node).setStateAfter(null);
+                                GraphUtil.killWithUnusedFloatingInputs(stateAfter);
                             }
                         }
                     }
-                    Debug.dump(graph, "after removal of framestates");
+                }
+                Debug.dump(graph, "after removal of framestates");
 
-                    new FloatingReadPhase().apply(graph);
-                    new RemoveValueProxyPhase().apply(graph);
+                new FloatingReadPhase().apply(graph);
+                new RemoveValueProxyPhase().apply(graph);
 
-                    MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL);
-                    new GuardLoweringPhase().apply(graph, midContext);
-                    new LoweringPhase(canonicalizer).apply(graph, midContext);
-                    new LoweringPhase(canonicalizer).apply(graph, midContext);
+                MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+                new GuardLoweringPhase().apply(graph, midContext);
+                new LoweringPhase(canonicalizer).apply(graph, midContext);
+                new LoweringPhase(canonicalizer).apply(graph, midContext);
 
-                    SchedulePhase schedule = new SchedulePhase(schedulingStrategy, memsched);
-                    schedule.apply(graph);
-                    assertEquals(1, graph.getNodes().filter(StartNode.class).count());
-                    return schedule;
-                }
+                SchedulePhase schedule = new SchedulePhase(schedulingStrategy, memsched);
+                schedule.apply(graph);
+                assertEquals(1, graph.getNodes().filter(StartNode.class).count());
+                return schedule;
             }
-        });
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
@@ -64,29 +65,27 @@
     @Test
     public void test1() {
         final String snippet = "test1Snippet";
-        Debug.scope("PushThroughPi", new DebugDumpScope(snippet), new Runnable() {
-
-            public void run() {
-                StructuredGraph graph = compileTestSnippet(snippet);
+        try (Scope s = Debug.scope("PushThroughPi", new DebugDumpScope(snippet))) {
+            StructuredGraph graph = compileTestSnippet(snippet);
+            for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) {
+                if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) {
+                    long disp = ((ConstantLocationNode) rn.location()).getDisplacement();
+                    ResolvedJavaType receiverType = ObjectStamp.typeOrNull(rn.object());
+                    ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp);
 
-                for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) {
-                    if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) {
-                        long disp = ((ConstantLocationNode) rn.location()).getDisplacement();
-                        ResolvedJavaType receiverType = ObjectStamp.typeOrNull(rn.object());
-                        ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp);
-
-                        assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type";
-                        if (field.getName().equals("x")) {
-                            Assert.assertTrue(rn.object() instanceof LocalNode);
-                        } else {
-                            Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode);
-                        }
+                    assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type";
+                    if (field.getName().equals("x")) {
+                        Assert.assertTrue(rn.object() instanceof LocalNode);
+                    } else {
+                        Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode);
                     }
                 }
+            }
 
-                Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1);
-            }
-        });
+            Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     private StructuredGraph compileTestSnippet(final String snippet) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.phases.common.*;
@@ -77,27 +78,26 @@
     }
 
     private void test(final String snippet) {
-        Debug.scope("FloatingReadTest", new DebugDumpScope(snippet), new Runnable() {
-
+        try (Scope s = Debug.scope("ReadAfterCheckCastTest", new DebugDumpScope(snippet))) {
             // check shape of graph, with lots of assumptions. will probably fail if graph
             // structure changes significantly
-            public void run() {
-                StructuredGraph graph = parse(snippet);
-                PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                new FloatingReadPhase().apply(graph);
-                new OptimizeGuardAnchors().apply(graph);
-                new ReadEliminationPhase().apply(graph);
-                new CanonicalizerPhase(true).apply(graph, context);
+            StructuredGraph graph = parse(snippet);
+            PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
+            new FloatingReadPhase().apply(graph);
+            new OptimizeGuardAnchors().apply(graph);
+            new ReadEliminationPhase().apply(graph);
+            new CanonicalizerPhase(true).apply(graph, context);
 
-                Debug.dump(graph, "After lowering");
+            Debug.dump(graph, "After lowering");
 
-                for (FloatingReadNode node : graph.getNodes(LocalNode.class).first().usages().filter(FloatingReadNode.class)) {
-                    // Checking that the parameter a is not directly used for the access to field
-                    // x10 (because x10 must be guarded by the checkcast).
-                    Assert.assertTrue(node.location().getLocationIdentity() == LocationIdentity.FINAL_LOCATION);
-                }
+            for (FloatingReadNode node : graph.getNodes(LocalNode.class).first().usages().filter(FloatingReadNode.class)) {
+                // Checking that the parameter a is not directly used for the access to field
+                // x10 (because x10 must be guarded by the checkcast).
+                Assert.assertTrue(node.location().getLocationIdentity() == LocationIdentity.FINAL_LOCATION);
             }
-        });
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -31,13 +31,7 @@
 public class SimpleCFGTest extends GraalCompilerTest {
 
     private static void dumpGraph(final StructuredGraph graph) {
-        Debug.scope("SimpleCFGTest", new Runnable() {
-
-            @Override
-            public void run() {
-                Debug.dump(graph, "Graph");
-            }
-        });
+        Debug.dump(graph, "Graph");
     }
 
     @Test
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,7 +26,6 @@
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import org.junit.*;
 
@@ -36,6 +35,7 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
 import com.oracle.graal.lir.StandardOp.MoveOp;
@@ -47,23 +47,18 @@
 
     protected void test(String snippet, final int expectedRegisters, final int expectedRegRegMoves, final int expectedSpillMoves) {
         final StructuredGraph graph = parse(snippet);
-        Debug.scope("AllocatorTest", new Object[]{graph, graph.method(), getCodeCache()}, new Runnable() {
-
-            @Override
-            public void run() {
-                final RegisterStats stats = getRegisterStats(graph);
-
-                Debug.scope("Assertions", stats.lir, new Runnable() {
-
-                    @Override
-                    public void run() {
-                        Assert.assertEquals("register count", expectedRegisters, stats.registers.size());
-                        Assert.assertEquals("reg-reg moves", expectedRegRegMoves, stats.regRegMoves);
-                        Assert.assertEquals("spill moves", expectedSpillMoves, stats.spillMoves);
-                    }
-                });
+        try (Scope s = Debug.scope("AllocatorTest", graph, graph.method(), getCodeCache())) {
+            final RegisterStats stats = getRegisterStats(graph);
+            try (Scope s2 = Debug.scope("Assertions", stats.lir)) {
+                Assert.assertEquals("register count", expectedRegisters, stats.registers.size());
+                Assert.assertEquals("reg-reg moves", expectedRegRegMoves, stats.regRegMoves);
+                Assert.assertEquals("spill moves", expectedSpillMoves, stats.spillMoves);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
             }
-        });
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     private class RegisterStats {
@@ -115,22 +110,19 @@
         final PhasePlan phasePlan = getDefaultPhasePlan();
         final Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
 
-        final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() {
-
-            @Override
-            public LIR call() {
-                return GraalCompiler.emitHIR(getProviders(), getBackend().getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), getSuites());
-            }
-        });
+        LIR lir = null;
+        try (Scope s = Debug.scope("FrontEnd")) {
+            lir = GraalCompiler.emitHIR(getProviders(), getBackend().getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), getSuites());
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-        return Debug.scope("BackEnd", lir, new Callable<RegisterStats>() {
-
-            @Override
-            public RegisterStats call() {
-                CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-                GraalCompiler.emitLIR(getBackend(), getBackend().getTarget(), lir, graph, cc);
-                return new RegisterStats(lir);
-            }
-        });
+        try (Scope s = Debug.scope("BackEnd", lir)) {
+            CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
+            GraalCompiler.emitLIR(getBackend(), getBackend().getTarget(), lir, graph, cc);
+            return new RegisterStats(lir);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java	Sat Nov 30 01:16:55 2013 +0100
@@ -28,6 +28,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
@@ -144,19 +145,18 @@
     protected void prepareGraph(String snippet, final boolean iterativeEscapeAnalysis) {
         ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(snippet));
         graph = new StructuredGraph(method);
-        Debug.scope(getClass().getSimpleName(), new Object[]{graph, method, getCodeCache()}, new Runnable() {
-
-            public void run() {
-                new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-                Assumptions assumptions = new Assumptions(false);
-                context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
-                new CanonicalizerPhase(true).apply(graph, context);
-                new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context);
-                Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count());
-                returnNode = graph.getNodes().filter(ReturnNode.class).first();
-            }
-        });
+        try (Scope s = Debug.scope(getClass().getSimpleName(), graph, method, getCodeCache())) {
+            new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+            Assumptions assumptions = new Assumptions(false);
+            context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+            new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph);
+            new CanonicalizerPhase(true).apply(graph, context);
+            new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context);
+            Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count());
+            returnNode = graph.getNodes().filter(ReturnNode.class).first();
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,13 +25,13 @@
 import static org.junit.Assert.*;
 
 import java.lang.reflect.*;
-import java.util.concurrent.*;
 
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -229,24 +229,22 @@
     }
 
     private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) {
-        return Debug.scope("InliningTest", new DebugDumpScope(snippet), new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() {
-                Method method = getMethod(snippet);
-                StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method);
-                PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode);
-                Assumptions assumptions = new Assumptions(true);
-                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
-                Debug.dump(graph, "Graph");
-                new CanonicalizerPhase(true).apply(graph, context);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                Debug.dump(graph, "Graph");
-                new CanonicalizerPhase(true).apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
-                return graph;
-            }
-        });
+        try (Scope s = Debug.scope("InliningTest", new DebugDumpScope(snippet))) {
+            Method method = getMethod(snippet);
+            StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method);
+            PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode);
+            Assumptions assumptions = new Assumptions(true);
+            HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
+            Debug.dump(graph, "Graph");
+            new CanonicalizerPhase(true).apply(graph, context);
+            new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
+            Debug.dump(graph, "Graph");
+            new CanonicalizerPhase(true).apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph);
+            return graph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     private static StructuredGraph assertInlined(StructuredGraph graph) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Sat Nov 30 01:16:55 2013 +0100
@@ -27,7 +27,6 @@
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.alloc.*;
 import com.oracle.graal.api.code.*;
@@ -36,6 +35,7 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -132,49 +132,44 @@
      *            argument can be null.
      * @return the result of the compilation
      */
-    public static <T extends CompilationResult> T compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers,
-                    final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts,
-                    final SpeculationLog speculationLog, final Suites suites, final T compilationResult) {
-        Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Runnable() {
-
-            public void run() {
-                compileGraphNoScope(graph, cc, installedCodeOwner, providers, backend, target, cache, plan, optimisticOpts, speculationLog, suites, compilationResult);
-            }
-        });
-
+    public static <T extends CompilationResult> T compileGraph(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
+                    TargetDescription target, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog, Suites suites, T compilationResult) {
+        try (Scope s = Debug.scope("GraalCompiler", graph, providers.getCodeCache())) {
+            compileGraphNoScope(graph, cc, installedCodeOwner, providers, backend, target, cache, plan, optimisticOpts, speculationLog, suites, compilationResult);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
         return compilationResult;
     }
 
     /**
      * Same as {@link #compileGraph} but without entering a
-     * {@linkplain Debug#scope(String, Object[], Runnable) debug scope}.
+     * {@linkplain Debug#scope(String, Object...) debug scope}.
      */
-    public static <T extends CompilationResult> T compileGraphNoScope(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers,
-                    final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts,
-                    final SpeculationLog speculationLog, final Suites suites, final T compilationResult) {
-        final Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
-        final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() {
+    public static <T extends CompilationResult> T compileGraphNoScope(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend,
+                    TargetDescription target, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog, Suites suites, T compilationResult) {
+        Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
 
-            public LIR call() {
-                try (TimerCloseable a = FrontEnd.start()) {
-                    return emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
-                }
+        LIR lir = null;
+        try (Scope s = Debug.scope("FrontEnd"); TimerCloseable a = FrontEnd.start()) {
+            lir = emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+        try (TimerCloseable a = BackEnd.start()) {
+            LIRGenerator lirGen = null;
+            try (Scope s = Debug.scope("BackEnd", lir)) {
+                lirGen = emitLIR(backend, target, lir, graph, cc);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
             }
-        });
-        try (TimerCloseable a = BackEnd.start()) {
-            final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable<LIRGenerator>() {
-
-                public LIRGenerator call() {
-                    return emitLIR(backend, target, lir, graph, cc);
-                }
-            });
-            Debug.scope("CodeGen", lirGen, new Runnable() {
-
-                public void run() {
-                    emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner);
-                }
-
-            });
+            try (Scope s = Debug.scope("CodeGen", lirGen)) {
+                emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
+        } catch (Throwable e) {
+            throw Debug.handle(e);
         }
 
         return compilationResult;
@@ -193,8 +188,8 @@
     /**
      * Builds the graph, optimizes it.
      */
-    public static LIR emitHIR(Providers providers, TargetDescription target, final StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan,
-                    OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) {
+    public static LIR emitHIR(Providers providers, TargetDescription target, StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts,
+                    SpeculationLog speculationLog, Suites suites) {
 
         if (speculationLog != null) {
             speculationLog.snapshot();
@@ -224,68 +219,63 @@
             InliningPhase.storeStatisticsAfterLowTier(graph);
         }
 
-        final SchedulePhase schedule = new SchedulePhase();
+        SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph);
         Debug.dump(schedule, "final schedule");
 
-        final Block[] blocks = schedule.getCFG().getBlocks();
-        final Block startBlock = schedule.getCFG().getStartBlock();
+        Block[] blocks = schedule.getCFG().getBlocks();
+        Block startBlock = schedule.getCFG().getStartBlock();
         assert startBlock != null;
         assert startBlock.getPredecessorCount() == 0;
 
-        return Debug.scope("ComputeLinearScanOrder", new Callable<LIR>() {
+        try (Scope s = Debug.scope("ComputeLinearScanOrder")) {
+            NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply();
+            List<Block> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, nodeProbabilities);
+            List<Block> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, nodeProbabilities);
 
-            @Override
-            public LIR call() {
-                NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply();
-                List<Block> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, nodeProbabilities);
-                List<Block> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, nodeProbabilities);
-
-                LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder);
-                Debug.dump(lir, "After linear scan order");
-                return lir;
-
-            }
-        });
+            LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder);
+            Debug.dump(lir, "After linear scan order");
+            return lir;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
     }
 
-    public static LIRGenerator emitLIR(final Backend backend, final TargetDescription target, final LIR lir, StructuredGraph graph, CallingConvention cc) {
-        final FrameMap frameMap = backend.newFrameMap();
-        final LIRGenerator lirGen = backend.newLIRGenerator(graph, frameMap, cc, lir);
-
-        Debug.scope("LIRGen", lirGen, new Runnable() {
+    private static void emitBlock(LIRGenerator lirGen, Block b) {
+        if (lirGen.lir.lir(b) == null) {
+            for (Block pred : b.getPredecessors()) {
+                if (!b.isLoopHeader() || !pred.isLoopEnd()) {
+                    emitBlock(lirGen, pred);
+                }
+            }
+            lirGen.doBlock(b);
+        }
+    }
 
-            public void run() {
-                for (Block b : lir.linearScanOrder()) {
-                    emitBlock(b);
-                }
+    public static LIRGenerator emitLIR(Backend backend, TargetDescription target, LIR lir, StructuredGraph graph, CallingConvention cc) {
+        FrameMap frameMap = backend.newFrameMap();
+        LIRGenerator lirGen = backend.newLIRGenerator(graph, frameMap, cc, lir);
 
-                Debug.dump(lir, "After LIR generation");
+        try (Scope s = Debug.scope("LIRGen", lirGen)) {
+            for (Block b : lir.linearScanOrder()) {
+                emitBlock(lirGen, b);
             }
 
-            private void emitBlock(Block b) {
-                if (lir.lir(b) == null) {
-                    for (Block pred : b.getPredecessors()) {
-                        if (!b.isLoopHeader() || !pred.isLoopEnd()) {
-                            emitBlock(pred);
-                        }
-                    }
-                    lirGen.doBlock(b);
-                }
-            }
-        });
+            Debug.dump(lir, "After LIR generation");
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
         lirGen.beforeRegisterAllocation();
 
-        Debug.scope("Allocator", new Runnable() {
-
-            public void run() {
-                if (backend.shouldAllocateRegisters()) {
-                    new LinearScan(target, lir, lirGen, frameMap).allocate();
-                }
+        try (Scope s = Debug.scope("Allocator")) {
+            if (backend.shouldAllocateRegisters()) {
+                new LinearScan(target, lir, lirGen, frameMap).allocate();
             }
-        });
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
         return lirGen;
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Sat Nov 30 01:16:55 2013 +0100
@@ -37,6 +37,7 @@
 import com.oracle.graal.compiler.alloc.Interval.SpillState;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
@@ -1818,66 +1819,61 @@
 
     public void allocate() {
 
-        Debug.scope("LifetimeAnalysis", new Runnable() {
-
-            public void run() {
-                numberInstructions();
-                printLir("Before register allocation", true);
-                computeLocalLiveSets();
-                computeGlobalLiveSets();
-                buildIntervals();
-                sortIntervalsBeforeAllocation();
-            }
-        });
-
-        Debug.scope("RegisterAllocation", new Runnable() {
+        try (Scope s = Debug.scope("LifetimeAnalysis")) {
+            numberInstructions();
+            printLir("Before register allocation", true);
+            computeLocalLiveSets();
+            computeGlobalLiveSets();
+            buildIntervals();
+            sortIntervalsBeforeAllocation();
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-            public void run() {
-                printIntervals("Before register allocation");
-                allocateRegisters();
-            }
-        });
+        try (Scope s = Debug.scope("RegisterAllocation")) {
+            printIntervals("Before register allocation");
+            allocateRegisters();
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-        Debug.scope("ResolveDataFlow", new Runnable() {
+        try (Scope s = Debug.scope("ResolveDataFlow")) {
+            resolveDataFlow();
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-            public void run() {
-                resolveDataFlow();
-            }
-        });
-
-        Debug.scope("DebugInfo", new Runnable() {
+        try (Scope s = Debug.scope("DebugInfo")) {
+            frameMap.finish();
 
-            public void run() {
-                frameMap.finish();
+            printIntervals("After register allocation");
+            printLir("After register allocation", true);
 
-                printIntervals("After register allocation");
-                printLir("After register allocation", true);
+            sortIntervalsAfterAllocation();
 
-                sortIntervalsAfterAllocation();
+            if (DetailedAsserts.getValue()) {
+                verify();
+            }
 
-                if (DetailedAsserts.getValue()) {
-                    verify();
-                }
-
-                eliminateSpillMoves();
-                assignLocations();
+            eliminateSpillMoves();
+            assignLocations();
 
-                if (DetailedAsserts.getValue()) {
-                    verifyIntervals();
-                }
+            if (DetailedAsserts.getValue()) {
+                verifyIntervals();
             }
-        });
-
-        Debug.scope("ControlFlowOptimizations", new Runnable() {
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-            public void run() {
-                printLir("After register number assignment", true);
-                EdgeMoveOptimizer.optimize(ir);
-                ControlFlowOptimizer.optimize(ir);
-                NullCheckOptimizer.optimize(ir, target.implicitNullCheckLimit);
-                printLir("After control flow optimization", false);
-            }
-        });
+        try (Scope s = Debug.scope("ControlFlowOptimizations")) {
+            printLir("After register number assignment", true);
+            EdgeMoveOptimizer.optimize(ir);
+            ControlFlowOptimizer.optimize(ir);
+            NullCheckOptimizer.optimize(ir, target.implicitNullCheckLimit);
+            printLir("After control flow optimization", false);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     void printIntervals(String label) {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Sat Nov 30 01:16:55 2013 +0100
@@ -105,71 +105,10 @@
         return callable;
     }
 
-    public static void sandbox(String name, DebugConfig config, Runnable runnable) {
-        if (ENABLED) {
-            DebugConfig sandboxConfig = config == null ? silentConfig() : config;
-            DebugScope.getInstance().scope(name, runnable, null, sandboxConfig, new Object[0]);
-        } else {
-            runnable.run();
-        }
-    }
-
     /**
-     * Creates a new debug scope that is unrelated to the current scope and runs a given task in the
-     * new scope.
-     * 
-     * @param name new scope name
-     * @param context the context objects of the new scope
-     * @param config the debug configuration to use for the new scope
-     * @param runnable the task to run in the new scope
+     * Gets a string composed of the names in the current nesting of debug
+     * {@linkplain #scope(String, Object...) scopes} separated by {@code '.'}.
      */
-    public static void sandbox(String name, Object[] context, DebugConfig config, Runnable runnable) {
-        if (ENABLED) {
-            DebugConfig sandboxConfig = config == null ? silentConfig() : config;
-            DebugScope.getInstance().scope(name, runnable, null, sandboxConfig, context);
-        } else {
-            runnable.run();
-        }
-    }
-
-    /**
-     * Creates a new debug scope that is unrelated to the current scope and runs a given task in the
-     * new scope.
-     * 
-     * @param name new scope name
-     * @param context the context objects of the new scope
-     * @param config the debug configuration to use for the new scope
-     * @param callable the task to run in the new scope
-     */
-    public static <T> T sandbox(String name, Object[] context, DebugConfig config, Callable<T> callable) {
-        if (ENABLED) {
-            DebugConfig sandboxConfig = config == null ? silentConfig() : config;
-            return DebugScope.getInstance().scope(name, null, callable, sandboxConfig, context);
-        } else {
-            return DebugScope.call(callable);
-        }
-    }
-
-    public static void scope(String name, Runnable runnable) {
-        scope(name, new Object[0], runnable);
-    }
-
-    public static <T> T scope(String name, Callable<T> callable) {
-        return scope(name, new Object[0], callable);
-    }
-
-    public static void scope(String name, Object context, Runnable runnable) {
-        scope(name, new Object[]{context}, runnable);
-    }
-
-    public static void scope(String name, Object[] context, Runnable runnable) {
-        if (ENABLED) {
-            DebugScope.getInstance().scope(name, runnable, null, null, context);
-        } else {
-            runnable.run();
-        }
-    }
-
     public static String currentScope() {
         if (ENABLED) {
             return DebugScope.getInstance().getQualifiedName();
@@ -178,20 +117,97 @@
         }
     }
 
-    public static <T> T scope(String name, Object context, Callable<T> callable) {
-        return scope(name, new Object[]{context}, callable);
+    /**
+     * Represents a debug scope entered by {@link Debug#scope(String, Object...)} or
+     * {@link Debug#sandbox(String, DebugConfig, Object...)}. Leaving the scope is achieved via
+     * {@link #close()}.
+     */
+    public interface Scope extends AutoCloseable {
+        void close();
     }
 
-    public static <T> T scope(String name, Object[] context, Callable<T> callable) {
+    /**
+     * 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>
+     * 
+     * @param name the name of 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 scope(String name, Object... context) {
         if (ENABLED) {
-            return DebugScope.getInstance().scope(name, null, callable, null, context);
+            return DebugScope.getInstance().scope(name, false, null, context);
         } else {
-            return DebugScope.call(callable);
+            return null;
         }
     }
 
     /**
-     * Prints an indented message to the current DebugLevel's logging stream if logging is enabled.
+     * 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(String name, DebugConfig config, Object... context) {
+        if (ENABLED) {
+            DebugConfig sandboxConfig = config == null ? silentConfig() : config;
+            return DebugScope.getInstance().scope(name, true, sandboxConfig, context);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 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(String, Object...)} and
+     * {@link #sandbox(String, DebugConfig, Object...)} is used
+     * 
+     * @see #scope(String, Object...)
+     * @see #sandbox(String, 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);
+        }
+    }
+
+    /**
+     * Prints an indented message to the current debug scopes's logging stream if logging is enabled
+     * in the scope.
      * 
      * @param msg The format string of the log message
      * @param args The arguments referenced by the log message string
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Sat Nov 30 01:16:55 2013 +0100
@@ -28,7 +28,7 @@
 
 import com.oracle.graal.debug.*;
 
-public final class DebugScope implements AutoCloseable {
+public final class DebugScope implements Debug.Scope {
 
     private final class IndentImpl implements Indent {
 
@@ -95,6 +95,7 @@
     }
 
     private static ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>();
+    private static ThreadLocal<DebugScope> lastClosedTL = new ThreadLocal<>();
     private static ThreadLocal<DebugConfig> configTL = new ThreadLocal<>();
     private static ThreadLocal<Throwable> lastExceptionThrownTL = new ThreadLocal<>();
 
@@ -104,7 +105,7 @@
     private IndentImpl lastUsedIndent;
     private boolean logScopeName;
 
-    private Object[] context;
+    private final Object[] context;
 
     private final DebugValueMap valueMap;
     private final String qualifiedName;
@@ -167,9 +168,9 @@
     }
 
     public void close() {
-        context = null;
         instanceTL.set(parent);
         setConfig(parentConfig);
+        lastClosedTL.set(this);
     }
 
     public boolean isDumpEnabled() {
@@ -231,29 +232,24 @@
     }
 
     /**
-     * Runs a task in a new debug scope which is either a child of the current scope or a disjoint
-     * top level scope.
+     * Creates and enters a new debug scope which is either a child of the current scope or a
+     * disjoint top level scope.
      * 
-     * @param newName the name of the new scope
-     * @param runnable the task to run (must be null iff {@code callable} is not null)
-     * @param callable the task to run (must be null iff {@code runnable} is not null)
-     * @param sandboxConfig if non-null, a new top level scope is entered with this configuration
-     * @param newContext context objects of the new scope
-     * @return the value returned by the task
+     * @param name the name of the new scope
+     * @param sandbox specifies if the scope is a child of the current scope or a top level scope
+     * @param sandboxConfig the configuration to use for a new top level scope (ignored if
+     *            {@code sandbox == false})
+     * @param context objects to be appended to the debug context
+     * @return the new scope which will be exited when its {@link #close()} method is called
      */
-    public <T> T scope(String newName, Runnable runnable, Callable<T> callable, DebugConfig sandboxConfig, Object[] newContext) {
-        try (DebugScope s = openScope(newName, sandboxConfig, newContext)) {
-            return executeScope(runnable, callable);
-        }
-    }
-
-    public DebugScope openScope(String newName, DebugConfig sandboxConfig, Object... newContext) {
+    @SuppressWarnings("hiding")
+    public DebugScope scope(String name, boolean sandbox, DebugConfig sandboxConfig, Object... context) {
         DebugScope newScope = null;
-        if (sandboxConfig != null) {
-            newScope = new DebugScope(newName, newName, this, true, newContext);
+        if (sandbox) {
+            newScope = new DebugScope(name, name, this, true, context);
             setConfig(sandboxConfig);
         } else {
-            newScope = this.createChild(newName, newContext);
+            newScope = this.createChild(name, context);
         }
         instanceTL.set(newScope);
         newScope.setLogEnabled(this.isLogEnabled());
@@ -261,30 +257,31 @@
         return newScope;
     }
 
-    private <T> T executeScope(Runnable runnable, Callable<T> callable) {
-
-        try {
-            if (runnable != null) {
-                runnable.run();
-            }
-            if (callable != null) {
-                return call(callable);
+    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);
             }
-        } catch (Throwable e) {
-            if (e == lastExceptionThrownTL.get()) {
-                throw e;
+            assert instanceTL.get() == this;
+            assert lastClosed == lastClosedTL.get();
+            if (newException == null) {
+                lastExceptionThrownTL.set(e);
             } else {
-                RuntimeException newException = interceptException(e);
-                if (newException == null) {
-                    lastExceptionThrownTL.set(e);
-                    throw e;
-                } else {
-                    lastExceptionThrownTL.set(newException);
-                    throw newException;
-                }
+                lastExceptionThrownTL.set(newException);
+                throw newException;
             }
         }
-        return null;
+        if (e instanceof Error) {
+            throw (Error) e;
+        }
+        if (e instanceof RuntimeException) {
+            throw (RuntimeException) e;
+        }
+        throw new RuntimeException(e);
     }
 
     private void updateFlags() {
@@ -311,17 +308,11 @@
     private RuntimeException interceptException(final Throwable e) {
         final DebugConfig config = getConfig();
         if (config != null) {
-            return scope("InterceptException", null, new Callable<RuntimeException>() {
-
-                @Override
-                public RuntimeException call() throws Exception {
-                    try {
-                        return config.interceptException(e);
-                    } catch (Throwable t) {
-                        return new RuntimeException("Exception while intercepting exception", t);
-                    }
-                }
-            }, null, new Object[]{e});
+            try (DebugScope s = scope("InterceptException", false, null, e)) {
+                return config.interceptException(e);
+            } catch (Throwable t) {
+                return new RuntimeException("Exception while intercepting exception", t);
+            }
         }
         return null;
     }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -34,6 +34,7 @@
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.phases.*;
@@ -243,54 +244,53 @@
     }
 
     private void test(final String snippet, final int expectedBarriers) throws Exception, SecurityException {
-        Debug.scope("WriteBarrierAditionTest", new DebugDumpScope(snippet), new Runnable() {
+        try (Scope s = Debug.scope("WriteBarrierAdditionTest", new DebugDumpScope(snippet))) {
+            StructuredGraph graph = parse(snippet);
+            HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+            MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+            new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext);
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext);
+            new GuardLoweringPhase().apply(graph, midContext);
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext);
+            new WriteBarrierAdditionPhase().apply(graph);
+            Debug.dump(graph, "After Write Barrier Addition");
 
-            public void run() {
-                StructuredGraph graph = parse(snippet);
-                HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
-                new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext);
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext);
-                new GuardLoweringPhase().apply(graph, midContext);
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext);
-                new WriteBarrierAdditionPhase().apply(graph);
-                Debug.dump(graph, "After Write Barrier Addition");
-
-                int barriers = 0;
+            int barriers = 0;
+            if (useG1GC()) {
+                barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() +
+                                graph.getNodes().filter(G1PostWriteBarrier.class).count();
+            } else {
+                barriers = graph.getNodes().filter(SerialWriteBarrier.class).count();
+            }
+            Assert.assertEquals(expectedBarriers, barriers);
+            for (WriteNode write : graph.getNodes().filter(WriteNode.class)) {
                 if (useG1GC()) {
-                    barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() +
-                                    graph.getNodes().filter(G1PostWriteBarrier.class).count();
+                    if (write.getBarrierType() != BarrierType.NONE) {
+                        Assert.assertEquals(1, write.successors().count());
+                        Assert.assertTrue(write.next() instanceof G1PostWriteBarrier);
+                        Assert.assertTrue(write.predecessor() instanceof G1PreWriteBarrier);
+                    }
                 } else {
-                    barriers = graph.getNodes().filter(SerialWriteBarrier.class).count();
-                }
-                Assert.assertEquals(expectedBarriers, barriers);
-                for (WriteNode write : graph.getNodes().filter(WriteNode.class)) {
-                    if (useG1GC()) {
-                        if (write.getBarrierType() != BarrierType.NONE) {
-                            Assert.assertEquals(1, write.successors().count());
-                            Assert.assertTrue(write.next() instanceof G1PostWriteBarrier);
-                            Assert.assertTrue(write.predecessor() instanceof G1PreWriteBarrier);
-                        }
-                    } else {
-                        if (write.getBarrierType() != BarrierType.NONE) {
-                            Assert.assertEquals(1, write.successors().count());
-                            Assert.assertTrue(write.next() instanceof SerialWriteBarrier);
-                        }
-                    }
-                }
-
-                for (ReadNode read : graph.getNodes().filter(ReadNode.class)) {
-                    if (read.getBarrierType() != BarrierType.NONE) {
-                        if (read.location() instanceof ConstantLocationNode) {
-                            Assert.assertEquals(referentOffset(), ((ConstantLocationNode) (read.location())).getDisplacement());
-                        }
-                        Assert.assertTrue(useG1GC());
-                        Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType());
-                        Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier);
+                    if (write.getBarrierType() != BarrierType.NONE) {
+                        Assert.assertEquals(1, write.successors().count());
+                        Assert.assertTrue(write.next() instanceof SerialWriteBarrier);
                     }
                 }
             }
-        });
+
+            for (ReadNode read : graph.getNodes().filter(ReadNode.class)) {
+                if (read.getBarrierType() != BarrierType.NONE) {
+                    if (read.location() instanceof ConstantLocationNode) {
+                        Assert.assertEquals(referentOffset(), ((ConstantLocationNode) (read.location())).getDisplacement());
+                    }
+                    Assert.assertTrue(useG1GC());
+                    Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType());
+                    Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier);
+                }
+            }
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     private void test2(final String snippet, Object a, Object b, Object c) throws Exception {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot.test;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import org.junit.*;
 
@@ -31,6 +30,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.nodes.*;
@@ -610,106 +610,100 @@
     }
 
     private void test(final String snippet, final int expectedBarriers, final int... removedBarrierIndices) {
-
-        AssertionError expectedError = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet), new Callable<AssertionError>() {
+        try (Scope d = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) {
+            final StructuredGraph graph = parse(snippet);
+            HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+            new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
 
-            public AssertionError call() {
-                final StructuredGraph graph = parse(snippet);
-                HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
+            MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
 
-                MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
+            new GuardLoweringPhase().apply(graph, midTierContext);
+            new LoopSafepointInsertionPhase().apply(graph);
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
 
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
-                new GuardLoweringPhase().apply(graph, midTierContext);
-                new LoopSafepointInsertionPhase().apply(graph);
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
-
-                new WriteBarrierAdditionPhase().apply(graph);
+            new WriteBarrierAdditionPhase().apply(graph);
 
-                int barriers = 0;
-                // First, the total number of expected barriers is checked.
-                HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
-                if (config.useG1GC) {
-                    barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() +
-                                    graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count();
-                    Assert.assertTrue(expectedBarriers * 2 == barriers);
-                } else {
-                    barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count();
-                    Assert.assertTrue(expectedBarriers == barriers);
-                }
-                // Iterate over all write nodes and remove barriers according to input indices.
-                NodeIteratorClosure<Boolean> closure = new NodeIteratorClosure<Boolean>() {
+            int barriers = 0;
+            // First, the total number of expected barriers is checked.
+            HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
+            if (config.useG1GC) {
+                barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() +
+                                graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count();
+                Assert.assertTrue(expectedBarriers * 2 == barriers);
+            } else {
+                barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count();
+                Assert.assertTrue(expectedBarriers == barriers);
+            }
+            // Iterate over all write nodes and remove barriers according to input indices.
+            NodeIteratorClosure<Boolean> closure = new NodeIteratorClosure<Boolean>() {
 
-                    @Override
-                    protected Boolean processNode(FixedNode node, Boolean currentState) {
-                        if (node instanceof WriteNode) {
-                            WriteNode write = (WriteNode) node;
-                            LocationIdentity obj = write.getLocationIdentity();
-                            if (obj instanceof ResolvedJavaField) {
-                                if (((ResolvedJavaField) obj).getName().equals("barrierIndex")) {
-                                    /*
-                                     * A "barrierIndex" variable was found and is checked against
-                                     * the input barrier array.
-                                     */
-                                    if (eliminateBarrier(write.value().asConstant().asInt(), removedBarrierIndices)) {
-                                        return true;
-                                    }
+                @Override
+                protected Boolean processNode(FixedNode node, Boolean currentState) {
+                    if (node instanceof WriteNode) {
+                        WriteNode write = (WriteNode) node;
+                        LocationIdentity obj = write.getLocationIdentity();
+                        if (obj instanceof ResolvedJavaField) {
+                            if (((ResolvedJavaField) obj).getName().equals("barrierIndex")) {
+                                /*
+                                 * A "barrierIndex" variable was found and is checked against the
+                                 * input barrier array.
+                                 */
+                                if (eliminateBarrier(write.value().asConstant().asInt(), removedBarrierIndices)) {
+                                    return true;
                                 }
                             }
-                        } else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) {
-                            // Remove flagged write barriers.
-                            if (currentState) {
-                                graph.removeFixed(((FixedWithNextNode) node));
-                                return false;
-                            }
                         }
-                        return currentState;
+                    } else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) {
+                        // Remove flagged write barriers.
+                        if (currentState) {
+                            graph.removeFixed(((FixedWithNextNode) node));
+                            return false;
+                        }
                     }
+                    return currentState;
+                }
 
-                    private boolean eliminateBarrier(int index, int[] map) {
-                        for (int i = 0; i < map.length; i++) {
-                            if (map[i] == index) {
-                                return true;
-                            }
+                private boolean eliminateBarrier(int index, int[] map) {
+                    for (int i = 0; i < map.length; i++) {
+                        if (map[i] == index) {
+                            return true;
                         }
-                        return false;
                     }
+                    return false;
+                }
 
-                    @Override
-                    protected Map<LoopExitNode, Boolean> processLoop(LoopBeginNode loop, Boolean initialState) {
-                        return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates;
-                    }
+                @Override
+                protected Map<LoopExitNode, Boolean> processLoop(LoopBeginNode loop, Boolean initialState) {
+                    return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates;
+                }
 
-                    @Override
-                    protected Boolean merge(MergeNode merge, List<Boolean> states) {
-                        return false;
-                    }
+                @Override
+                protected Boolean merge(MergeNode merge, List<Boolean> states) {
+                    return false;
+                }
 
-                    @Override
-                    protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) {
-                        return false;
-                    }
-                };
+                @Override
+                protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) {
+                    return false;
+                }
+            };
 
-                DebugConfig debugConfig = DebugScope.getConfig();
-                DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output());
-                try (DebugConfigScope s = Debug.setConfig(fixedConfig)) {
-                    ReentrantNodeIterator.apply(closure, graph.start(), false, null);
-                    new WriteBarrierVerificationPhase().apply(graph);
-                } catch (AssertionError error) {
-                    /*
-                     * Catch assertion, test for expected one and re-throw in order to validate unit
-                     * test.
-                     */
-                    Assert.assertTrue(error.getMessage().contains("Write barrier must be present"));
-                    return error;
-                }
-                return null;
+            DebugConfig debugConfig = DebugScope.getConfig();
+            DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output());
+            try (DebugConfigScope s = Debug.setConfig(fixedConfig)) {
+                ReentrantNodeIterator.apply(closure, graph.start(), false, null);
+                new WriteBarrierVerificationPhase().apply(graph);
+            } catch (AssertionError error) {
+                /*
+                 * Catch assertion, test for expected one and re-throw in order to validate unit
+                 * test.
+                 */
+                Assert.assertTrue(error.getMessage().contains("Write barrier must be present"));
+                throw error;
             }
-        });
-        if (expectedError != null) {
-            throw expectedError;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Sat Nov 30 01:16:55 2013 +0100
@@ -37,6 +37,7 @@
 import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -142,32 +143,29 @@
             CompilationResult result = null;
             TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method);
             long start = System.currentTimeMillis();
-            try {
-                result = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true), new Callable<CompilationResult>() {
-
-                    @Override
-                    public CompilationResult call() throws Exception {
-                        GraphCache graphCache = backend.getRuntime().getGraphCache();
-                        if (graphCache != null) {
-                            graphCache.removeStaleGraphs();
-                        }
+            try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) {
+                GraphCache graphCache = backend.getRuntime().getGraphCache();
+                if (graphCache != null) {
+                    graphCache.removeStaleGraphs();
+                }
 
-                        HotSpotProviders providers = backend.getProviders();
-                        Replacements replacements = providers.getReplacements();
-                        graph = replacements.getMethodSubstitution(method);
-                        if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) {
-                            graph = new StructuredGraph(method, entryBCI);
-                        } else {
-                            // Compiling method substitution - must clone the graph
-                            graph = graph.copy();
-                        }
-                        InlinedBytecodes.add(method.getCodeSize());
-                        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
-                        Suites suites = providers.getSuites().getDefaultSuites();
-                        return GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, method.getSpeculationLog(), suites,
-                                        new CompilationResult());
-                    }
-                });
+                HotSpotProviders providers = backend.getProviders();
+                Replacements replacements = providers.getReplacements();
+                graph = replacements.getMethodSubstitution(method);
+                if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) {
+                    graph = new StructuredGraph(method, entryBCI);
+                } else {
+                    // Compiling method substitution - must clone the graph
+                    graph = graph.copy();
+                }
+                InlinedBytecodes.add(method.getCodeSize());
+                CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
+                Suites suites = providers.getSuites().getDefaultSuites();
+                result = GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, method.getSpeculationLog(), suites,
+                                new CompilationResult());
+
+            } catch (Throwable e) {
+                throw Debug.handle(e);
             } finally {
                 filter.remove();
                 final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed();
@@ -231,21 +229,19 @@
 
     private HotSpotInstalledCode installMethod(final CompilationResult compResult) {
         final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache();
-        return Debug.scope("CodeInstall", new Object[]{new DebugDumpScope(String.valueOf(id), true), codeCache, method}, new Callable<HotSpotInstalledCode>() {
-
-            @Override
-            public HotSpotInstalledCode call() {
-                HotSpotInstalledCode installedCode = codeCache.installMethod(method, entryBCI, compResult);
-                if (Debug.isDumpEnabled()) {
-                    Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
-                }
-                if (Debug.isLogEnabled()) {
-                    Debug.log("%s", backend.getProviders().getDisassembler().disassemble(installedCode));
-                }
-                return installedCode;
+        HotSpotInstalledCode installedCode = null;
+        try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) {
+            installedCode = codeCache.installMethod(method, entryBCI, compResult);
+            if (Debug.isDumpEnabled()) {
+                Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
             }
-
-        });
+            if (Debug.isLogEnabled()) {
+                Debug.log("%s", backend.getProviders().getDisassembler().disassemble(installedCode));
+            }
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+        return installedCode;
     }
 
     private boolean tryToChangeStatus(CompilationStatus from, CompilationStatus to) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Sat Nov 30 01:16:55 2013 +0100
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -51,24 +52,21 @@
 
         // Install intrinsics.
         if (Intrinsify.getValue()) {
-            Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() {
-
-                @Override
-                public void run() {
-
-                    Replacements replacements = providers.getReplacements();
-                    ServiceLoader<ReplacementsProvider> sl = ServiceLoader.loadInstalled(ReplacementsProvider.class);
-                    for (ReplacementsProvider replacementsProvider : sl) {
-                        replacementsProvider.registerReplacements(providers.getMetaAccess(), lowerer, replacements, providers.getCodeCache().getTarget());
-                    }
-                    if (BootstrapReplacements.getValue()) {
-                        for (ResolvedJavaMethod method : replacements.getAllReplacements()) {
-                            replacements.getMacroSubstitution(method);
-                            replacements.getMethodSubstitution(method);
-                        }
+            try (Scope s = Debug.scope("RegisterReplacements", new DebugDumpScope("RegisterReplacements"))) {
+                Replacements replacements = providers.getReplacements();
+                ServiceLoader<ReplacementsProvider> sl = ServiceLoader.loadInstalled(ReplacementsProvider.class);
+                for (ReplacementsProvider replacementsProvider : sl) {
+                    replacementsProvider.registerReplacements(providers.getMetaAccess(), lowerer, replacements, providers.getCodeCache().getTarget());
+                }
+                if (BootstrapReplacements.getValue()) {
+                    for (ResolvedJavaMethod method : replacements.getAllReplacements()) {
+                        replacements.getMacroSubstitution(method);
+                        replacements.getMethodSubstitution(method);
                     }
                 }
-            });
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Sat Nov 30 01:16:55 2013 +0100
@@ -24,10 +24,9 @@
 
 import static com.oracle.graal.compiler.GraalCompiler.*;
 
-import java.util.concurrent.*;
-
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -76,14 +75,11 @@
         }
         Kind componentKind = srcType.getComponentType().getKind();
         final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind));
-        return Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() throws Exception {
-                return replacements.getSnippet(snippetMethod);
-            }
-        });
-
+        try (Scope s = Debug.scope("ArrayCopySnippet", snippetMethod)) {
+            return replacements.getSnippet(snippetMethod);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     private static void unrollFixedLengthLoop(StructuredGraph snippetGraph, int length, LoweringTool tool) {
@@ -109,26 +105,23 @@
         StructuredGraph snippetGraph = selectSnippet(tool, replacements);
         if (snippetGraph == null) {
             final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet);
-            snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() {
-
-                @Override
-                public StructuredGraph call() throws Exception {
-                    return replacements.getSnippet(snippetMethod).copy();
-                }
-            });
+            snippetGraph = null;
+            try (Scope s = Debug.scope("ArrayCopySnippet", snippetMethod)) {
+                snippetGraph = replacements.getSnippet(snippetMethod).copy();
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
             replaceSnippetInvokes(snippetGraph);
         } else {
             assert snippetGraph != null : "ArrayCopySnippets should be installed";
             snippetGraph = snippetGraph.copy();
             if (getLength().isConstant() && getLength().asConstant().asInt() <= GraalOptions.MaximumEscapeAnalysisArrayLength.getValue()) {
                 final StructuredGraph copy = snippetGraph;
-                Debug.scope("ArrayCopySnippetSpecialization", snippetGraph.method(), new Runnable() {
-
-                    @Override
-                    public void run() {
-                        unrollFixedLengthLoop(copy, getLength().asConstant().asInt(), tool);
-                    }
-                });
+                try (Scope s = Debug.scope("ArrayCopySnippetSpecialization", snippetGraph.method())) {
+                    unrollFixedLengthLoop(copy, getLength().asConstant().asInt(), tool);
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
             }
         }
         return lowerReplacement(snippetGraph, tool);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,11 +25,11 @@
 import static com.oracle.graal.compiler.GraalCompiler.*;
 
 import java.lang.reflect.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
@@ -65,13 +65,12 @@
                 if (method != null) {
                     final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method);
                     final Replacements replacements = tool.getReplacements();
-                    StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() {
-
-                        @Override
-                        public StructuredGraph call() throws Exception {
-                            return replacements.getSnippet(snippetMethod);
-                        }
-                    });
+                    StructuredGraph snippetGraph = null;
+                    try (Scope s = Debug.scope("ArrayCopySnippet", snippetMethod)) {
+                        snippetGraph = replacements.getSnippet(snippetMethod);
+                    } catch (Throwable e) {
+                        throw Debug.handle(e);
+                    }
 
                     assert snippetGraph != null : "ObjectCloneSnippets should be installed";
                     return lowerReplacement(snippetGraph.copy(), tool);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,13 +25,13 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
@@ -135,53 +135,47 @@
      */
     public synchronized InstalledCode getCode(final Backend backend) {
         if (code == null) {
-            Debug.sandbox("CompilingStub", new Object[]{providers.getCodeCache(), debugScopeContext()}, DebugScope.getConfig(), new Runnable() {
-
-                @Override
-                public void run() {
+            try (Scope d = Debug.sandbox("CompilingStub", DebugScope.getConfig(), providers.getCodeCache(), debugScopeContext())) {
+                final StructuredGraph graph = getGraph();
+                if (!(graph.start() instanceof StubStartNode)) {
+                    StubStartNode newStart = graph.add(new StubStartNode(Stub.this));
+                    newStart.setStateAfter(graph.start().stateAfter());
+                    graph.replaceFixed(graph.start(), newStart);
+                }
 
-                    final StructuredGraph graph = getGraph();
-                    if (!(graph.start() instanceof StubStartNode)) {
-                        StubStartNode newStart = graph.add(new StubStartNode(Stub.this));
-                        newStart.setStateAfter(graph.start().stateAfter());
-                        graph.replaceFixed(graph.start(), newStart);
-                    }
-
-                    PhasePlan phasePlan = new PhasePlan();
-                    ForeignCallsProvider foreignCalls = providers.getForeignCalls();
-                    MetaAccessProvider metaAccess = providers.getMetaAccess();
-                    CodeCacheProvider codeCache = providers.getCodeCache();
-                    GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
-                    phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-                    // The stub itself needs the incoming calling convention.
-                    CallingConvention incomingCc = linkage.getIncomingCallingConvention();
-                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null, phasePlan,
-                                    OptimisticOptimizations.ALL, new SpeculationLog(), providers.getSuites().getDefaultSuites(), new CompilationResult());
+                PhasePlan phasePlan = new PhasePlan();
+                ForeignCallsProvider foreignCalls = providers.getForeignCalls();
+                MetaAccessProvider metaAccess = providers.getMetaAccess();
+                CodeCacheProvider codeCache = providers.getCodeCache();
+                GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+                phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
+                // The stub itself needs the incoming calling convention.
+                CallingConvention incomingCc = linkage.getIncomingCallingConvention();
+                final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null, phasePlan,
+                                OptimisticOptimizations.ALL, new SpeculationLog(), providers.getSuites().getDefaultSuites(), new CompilationResult());
 
-                    assert destroyedRegisters != null;
-                    code = Debug.scope("CodeInstall", new Callable<InstalledCode>() {
-
-                        @Override
-                        public InstalledCode call() {
-                            Stub stub = Stub.this;
-                            HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub);
-                            HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult);
-                            CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
-                            if (result != CodeInstallResult.OK) {
-                                throw new GraalInternalError("Error installing stub %s: %s", Stub.this, result);
-                            }
-                            if (Debug.isDumpEnabled()) {
-                                Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
-                            }
-                            if (Debug.isLogEnabled()) {
-                                Debug.log("%s", providers.getDisassembler().disassemble(installedCode));
-                            }
-                            return installedCode;
-                        }
-                    });
-
+                assert destroyedRegisters != null;
+                try (Scope s = Debug.scope("CodeInstall")) {
+                    Stub stub = Stub.this;
+                    HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub);
+                    HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult);
+                    CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
+                    if (result != CodeInstallResult.OK) {
+                        throw new GraalInternalError("Error installing stub %s: %s", Stub.this, result);
+                    }
+                    if (Debug.isDumpEnabled()) {
+                        Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
+                    }
+                    if (Debug.isLogEnabled()) {
+                        Debug.log("%s", providers.getDisassembler().disassemble(installedCode));
+                    }
+                    code = installedCode;
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
                 }
-            });
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
             assert code != null : "error installing stub " + this;
         }
         return code;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Sat Nov 30 01:16:55 2013 +0100
@@ -31,6 +31,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.bytecode.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -210,13 +211,11 @@
             this.log("Before LivenessAnalysis");
         }
         if (OptLivenessAnalysis.getValue()) {
-            Debug.scope("LivenessAnalysis", new Runnable() {
-
-                @Override
-                public void run() {
-                    computeLiveness();
-                }
-            });
+            try (Scope s = Debug.scope("LivenessAnalysis")) {
+                computeLiveness();
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
         }
     }
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Sat Nov 30 01:16:55 2013 +0100
@@ -23,9 +23,9 @@
 package com.oracle.graal.loop;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 
@@ -36,13 +36,12 @@
     private ControlFlowGraph cfg;
 
     public LoopsData(final StructuredGraph graph) {
-        cfg = Debug.scope("ControlFlowGraph", new Callable<ControlFlowGraph>() {
+        try (Scope s = Debug.scope("ControlFlowGraph")) {
+            cfg = ControlFlowGraph.compute(graph, true, true, true, true);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-            @Override
-            public ControlFlowGraph call() throws Exception {
-                return ControlFlowGraph.compute(graph, true, true, true, true);
-            }
-        });
         for (Loop lirLoop : cfg.getLoops()) {
             LoopEx ex = new LoopEx(lirLoop, this);
             lirLoopToEx.put(lirLoop, ex);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,6 +25,7 @@
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
@@ -39,15 +40,13 @@
         if (graph.hasLoops()) {
             if (ReassociateInvariants.getValue()) {
                 final LoopsData dataReassociate = new LoopsData(graph);
-                Debug.scope("ReassociateInvariants", new Runnable() {
-
-                    @Override
-                    public void run() {
-                        for (LoopEx loop : dataReassociate.loops()) {
-                            loop.reassociateInvariants();
-                        }
+                try (Scope s = Debug.scope("ReassociateInvariants")) {
+                    for (LoopEx loop : dataReassociate.loops()) {
+                        loop.reassociateInvariants();
                     }
-                });
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
             }
             if (LoopUnswitch.getValue()) {
                 boolean unswitched;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Sat Nov 30 01:16:55 2013 +0100
@@ -22,11 +22,10 @@
  */
 package com.oracle.graal.phases.common;
 
-import java.util.concurrent.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.Graph.NodeChangedListener;
@@ -243,22 +242,20 @@
             if (nodeClass.isCanonicalizable()) {
                 assert !nodeClass.isSimplifiable();
                 METRIC_CANONICALIZATION_CONSIDERED_NODES.increment();
-                return Debug.scope("CanonicalizeNode", node, new Callable<Boolean>() {
-
-                    public Boolean call() {
-                        Node canonical = node.canonical(tool);
-                        return performReplacement(node, canonical);
-                    }
-                });
+                try (Scope s = Debug.scope("CanonicalizeNode", node)) {
+                    Node canonical = node.canonical(tool);
+                    return performReplacement(node, canonical);
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
             } else if (nodeClass.isSimplifiable()) {
                 Debug.log("Canonicalizer: simplifying %s", node);
                 METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment();
-                Debug.scope("SimplifyNode", node, new Runnable() {
-
-                    public void run() {
-                        node.simplify(tool);
-                    }
-                });
+                try (Scope s = Debug.scope("SimplifyNode", node)) {
+                    node.simplify(tool);
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
             }
             return node.isDeleted();
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,11 +26,11 @@
 import static com.oracle.graal.phases.common.InliningPhase.Options.*;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.nodes.*;
@@ -124,14 +124,11 @@
                     if (currentInvocation.processedGraphs() == currentInvocation.totalGraphs()) {
                         data.popInvocation();
                         final MethodInvocation parentInvoke = data.currentInvocation();
-                        Debug.scope("Inlining", data.inliningContext(), new Runnable() {
-
-                            @Override
-                            public void run() {
-                                tryToInline(data.currentGraph(), currentInvocation, parentInvoke, data.inliningDepth() + 1, context);
-                            }
-                        });
-
+                        try (Scope s = Debug.scope("Inlining", data.inliningContext())) {
+                            tryToInline(data.currentGraph(), currentInvocation, parentInvoke, data.inliningDepth() + 1, context);
+                        } catch (Throwable e) {
+                            throw Debug.handle(e);
+                        }
                     }
                 }
             }
@@ -246,44 +243,42 @@
             }
         }
 
-        return Debug.scope("InlineGraph", newGraph, new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() throws Exception {
-                if (parseBytecodes) {
-                    parseBytecodes(newGraph, context);
-                }
+        try (Scope s = Debug.scope("InlineGraph", newGraph)) {
+            if (parseBytecodes) {
+                parseBytecodes(newGraph, context);
+            }
 
-                boolean callerHasMoreInformationAboutArguments = false;
-                NodeInputList<ValueNode> args = invoke.callTarget().arguments();
-                for (LocalNode localNode : newGraph.getNodes(LocalNode.class).snapshot()) {
-                    ValueNode arg = args.get(localNode.index());
-                    if (arg.isConstant()) {
-                        Constant constant = arg.asConstant();
-                        newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph));
+            boolean callerHasMoreInformationAboutArguments = false;
+            NodeInputList<ValueNode> args = invoke.callTarget().arguments();
+            for (LocalNode localNode : newGraph.getNodes(LocalNode.class).snapshot()) {
+                ValueNode arg = args.get(localNode.index());
+                if (arg.isConstant()) {
+                    Constant constant = arg.asConstant();
+                    newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph));
+                    callerHasMoreInformationAboutArguments = true;
+                } else {
+                    Stamp joinedStamp = localNode.stamp().join(arg.stamp());
+                    if (joinedStamp != null && !joinedStamp.equals(localNode.stamp())) {
+                        localNode.setStamp(joinedStamp);
                         callerHasMoreInformationAboutArguments = true;
-                    } else {
-                        Stamp joinedStamp = localNode.stamp().join(arg.stamp());
-                        if (joinedStamp != null && !joinedStamp.equals(localNode.stamp())) {
-                            localNode.setStamp(joinedStamp);
-                            callerHasMoreInformationAboutArguments = true;
-                        }
                     }
                 }
+            }
 
-                if (!callerHasMoreInformationAboutArguments) {
-                    // TODO (chaeubl): if args are not more concrete, inlining should be avoided
-                    // in most cases or we could at least use the previous graph size + invoke
-                    // probability to check the inlining
-                }
+            if (!callerHasMoreInformationAboutArguments) {
+                // TODO (chaeubl): if args are not more concrete, inlining should be avoided
+                // in most cases or we could at least use the previous graph size + invoke
+                // probability to check the inlining
+            }
 
-                if (OptCanonicalizer.getValue()) {
-                    canonicalizer.apply(newGraph, context);
-                }
+            if (OptCanonicalizer.getValue()) {
+                canonicalizer.apply(newGraph, context);
+            }
 
-                return newGraph;
-            }
-        });
+            return newGraph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     private static StructuredGraph getCachedGraph(ResolvedJavaMethod method, HighTierContext context) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sat Nov 30 01:16:55 2013 +0100
@@ -30,7 +30,6 @@
 
 import java.lang.reflect.*;
 import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.Assumptions.Assumption;
@@ -38,6 +37,7 @@
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
 import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Graph.DuplicationReplacement;
 import com.oracle.graal.graph.Node.ValueNumberable;
@@ -173,12 +173,9 @@
     }
 
     public static void logInliningDecision(final String msg, final Object... args) {
-        Debug.scope(inliningDecisionsScopeString, new Runnable() {
-
-            public void run() {
-                Debug.log(msg, args);
-            }
-        });
+        try (Scope s = Debug.scope(inliningDecisionsScopeString)) {
+            Debug.log(msg, args);
+        }
     }
 
     private static boolean logNotInlinedMethod(Invoke invoke, String msg) {
@@ -220,12 +217,9 @@
     }
 
     public static boolean shouldLogInliningDecision() {
-        return Debug.scope(inliningDecisionsScopeString, new Callable<Boolean>() {
-
-            public Boolean call() {
-                return Debug.isLogEnabled();
-            }
-        });
+        try (Scope s = Debug.scope(inliningDecisionsScopeString)) {
+            return Debug.isLogEnabled();
+        }
     }
 
     private static String methodName(ResolvedJavaMethod method, Invoke invoke) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,6 +25,7 @@
 import java.util.regex.*;
 
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.nodes.*;
 
@@ -75,19 +76,15 @@
     }
 
     public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) {
-        try (TimerCloseable a = phaseTimer.start()) {
-
-            Debug.scope(name, this, new Runnable() {
-
-                public void run() {
-                    BasePhase.this.run(graph, context);
-                    phaseMetric.increment();
-                    if (dumpGraph) {
-                        Debug.dump(graph, "After phase %s", name);
-                    }
-                    assert graph.verify();
-                }
-            });
+        try (TimerCloseable a = phaseTimer.start(); Scope s = Debug.scope(name, this)) {
+            BasePhase.this.run(graph, context);
+            phaseMetric.increment();
+            if (dumpGraph) {
+                Debug.dump(graph, "After phase %s", name);
+            }
+            assert graph.verify();
+        } catch (Throwable t) {
+            throw Debug.handle(t);
         }
     }
 
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java	Sat Nov 30 01:16:55 2013 +0100
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.printer;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.io.*;
 import java.util.concurrent.atomic.*;
 
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.java.decompiler.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.schedule.*;
@@ -69,18 +70,15 @@
             final String currentScope = Debug.currentScope();
             if (currentScope.endsWith(filter) && graph.method() != null) {
                 final String methodName = graph.method().getName();
-                Debug.sandbox("Printing Decompiler Output", null, new Runnable() {
-
-                    @Override
-                    public void run() {
-                        printStream.println();
-                        printStream.println("Object: " + methodName);
-                        printStream.println("Message: " + message);
-                        new Decompiler(graph, getPredefinedSchedule(), printStream, infoPrintStream, currentScope).decompile();
-                        printStream.flush();
-                    }
-                });
-
+                try (Scope s = Debug.sandbox("Printing Decompiler Output", null)) {
+                    printStream.println();
+                    printStream.println("Object: " + methodName);
+                    printStream.println("Message: " + message);
+                    new Decompiler(graph, getPredefinedSchedule(), printStream, infoPrintStream, currentScope).decompile();
+                    printStream.flush();
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
             }
         }
     }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Sat Nov 30 01:16:55 2013 +0100
@@ -34,6 +34,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.phases.schedule.*;
 
@@ -176,19 +177,15 @@
                 previousInlineContext = inlineContext;
 
                 final SchedulePhase predefinedSchedule = getPredefinedSchedule();
-                Debug.sandbox("PrintingGraph", null, new Runnable() {
-
-                    @Override
-                    public void run() {
-                        // Finally, output the graph.
-                        try {
-                            printer.print(graph, nextDumpId() + ":" + message, predefinedSchedule);
-                        } catch (IOException e) {
-                            failuresCount++;
-                            printer = null;
-                        }
-                    }
-                });
+                try (Scope s = Debug.sandbox("PrintingGraph", null)) {
+                    // Finally, output the graph.
+                    printer.print(graph, nextDumpId() + ":" + message, predefinedSchedule);
+                } catch (IOException e) {
+                    failuresCount++;
+                    printer = null;
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
             }
         }
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -24,12 +24,11 @@
 
 import static org.junit.Assert.*;
 
-import java.util.concurrent.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
@@ -44,24 +43,22 @@
 public abstract class MethodSubstitutionTest extends GraalCompilerTest {
 
     protected StructuredGraph test(final String snippet) {
-        return Debug.scope("MethodSubstitutionTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)), new Callable<StructuredGraph>() {
+        try (Scope s = Debug.scope("MethodSubstitutionTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)))) {
+            StructuredGraph graph = parse(snippet);
+            PhasePlan phasePlan = getDefaultPhasePlan();
+            Assumptions assumptions = new Assumptions(true);
+            HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
+            Debug.dump(graph, "Graph");
+            new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
+            Debug.dump(graph, "Graph");
+            new CanonicalizerPhase(true).apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph);
 
-            @Override
-            public StructuredGraph call() {
-                StructuredGraph graph = parse(snippet);
-                PhasePlan phasePlan = getDefaultPhasePlan();
-                Assumptions assumptions = new Assumptions(true);
-                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
-                Debug.dump(graph, "Graph");
-                new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                Debug.dump(graph, "Graph");
-                new CanonicalizerPhase(true).apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
-
-                assertNotInGraph(graph, Invoke.class);
-                return graph;
-            }
-        });
+            assertNotInGraph(graph, Invoke.class);
+            return graph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 
     protected static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sat Nov 30 01:16:55 2013 +0100
@@ -36,6 +36,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.java.*;
@@ -298,22 +299,20 @@
         }
 
         public StructuredGraph makeGraph(final SnippetInliningPolicy policy, final boolean removeAllFrameStates) {
-            return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable<StructuredGraph>() {
+            try (Scope s = Debug.scope("BuildSnippetGraph", method)) {
+                StructuredGraph graph = parseGraph(method, policy);
 
-                @Override
-                public StructuredGraph call() throws Exception {
-                    StructuredGraph graph = parseGraph(method, policy);
+                // Cannot have a finalized version of a graph in the cache
+                graph = graph.copy();
 
-                    // Cannot have a finalized version of a graph in the cache
-                    graph = graph.copy();
+                finalizeGraph(graph, removeAllFrameStates);
 
-                    finalizeGraph(graph, removeAllFrameStates);
+                Debug.dump(graph, "%s: Final", method.getName());
 
-                    Debug.dump(graph, "%s: Final", method.getName());
-
-                    return graph;
-                }
-            });
+                return graph;
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
         }
 
         /**
@@ -343,12 +342,12 @@
         private StructuredGraph parseGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) {
             StructuredGraph graph = graphCache.get(methodToParse);
             if (graph == null) {
-                StructuredGraph newGraph = Debug.scope("ParseGraph", new Object[]{methodToParse}, new Callable<StructuredGraph>() {
-
-                    public StructuredGraph call() throws Exception {
-                        return buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy);
-                    }
-                });
+                StructuredGraph newGraph = null;
+                try (Scope s = Debug.scope("ParseGraph", methodToParse)) {
+                    newGraph = buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy);
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
 
                 graphCache.putIfAbsent(methodToParse, newGraph);
                 graph = graphCache.get(methodToParse);
@@ -362,21 +361,19 @@
          */
         protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod methodToParse) {
             final StructuredGraph graph = new StructuredGraph(methodToParse);
-            Debug.scope("buildInitialGraph", graph, new Runnable() {
+            try (Scope s = Debug.scope("buildInitialGraph", graph)) {
+                MetaAccessProvider metaAccess = providers.getMetaAccess();
+                ForeignCallsProvider foreignCalls = providers.getForeignCalls();
+                new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
+                new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
+                new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
 
-                @Override
-                public void run() {
-                    MetaAccessProvider metaAccess = providers.getMetaAccess();
-                    ForeignCallsProvider foreignCalls = providers.getForeignCalls();
-                    new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
-                    new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
-                    new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
-
-                    if (OptCanonicalizer.getValue()) {
-                        new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
-                    }
+                if (OptCanonicalizer.getValue()) {
+                    new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
                 }
-            });
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
             return graph;
         }
 
@@ -411,57 +408,56 @@
         private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) {
             assert !Modifier.isAbstract(methodToParse.getModifiers()) && !Modifier.isNative(methodToParse.getModifiers()) : methodToParse;
             final StructuredGraph graph = buildInitialGraph(methodToParse);
-            Debug.scope("buildGraph", graph, new Runnable() {
+            try (Scope s = Debug.scope("buildGraph", graph)) {
+
+                for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) {
+                    ResolvedJavaMethod callee = callTarget.targetMethod();
+                    if (callee == method) {
+                        final StructuredGraph originalGraph = new StructuredGraph(original);
+                        MetaAccessProvider metaAccess = providers.getMetaAccess();
+                        ForeignCallsProvider foreignCalls = providers.getForeignCalls();
+                        new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph);
+                        new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
+                        new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
+
+                        InliningUtil.inline(callTarget.invoke(), originalGraph, true);
 
-                @Override
-                public void run() {
-                    for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) {
-                        ResolvedJavaMethod callee = callTarget.targetMethod();
-                        if (callee == method) {
-                            final StructuredGraph originalGraph = new StructuredGraph(original);
-                            MetaAccessProvider metaAccess = providers.getMetaAccess();
-                            ForeignCallsProvider foreignCalls = providers.getForeignCalls();
-                            new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph);
-                            new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
-                            new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
-
-                            InliningUtil.inline(callTarget.invoke(), originalGraph, true);
-
+                        Debug.dump(graph, "after inlining %s", callee);
+                        afterInline(graph, originalGraph, null);
+                        substituteCallsOriginal = true;
+                    } else {
+                        StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee);
+                        if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) &&
+                                        (policy.shouldInline(callee, methodToParse) || (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)))) {
+                            StructuredGraph targetGraph;
+                            if (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)) {
+                                targetGraph = intrinsicGraph;
+                            } else {
+                                if (callee.getName().startsWith("$jacoco")) {
+                                    throw new GraalInternalError("Parsing call to JaCoCo instrumentation method " + format("%H.%n(%p)", callee) + " from " + format("%H.%n(%p)", methodToParse) +
+                                                    " while preparing replacement " + format("%H.%n(%p)", method) + ". Placing \"//JaCoCo Exclude\" anywhere in " +
+                                                    methodToParse.getDeclaringClass().getSourceFileName() + " should fix this.");
+                                }
+                                targetGraph = parseGraph(callee, policy);
+                            }
+                            Object beforeInlineData = beforeInline(callTarget, targetGraph);
+                            InliningUtil.inline(callTarget.invoke(), targetGraph, true);
                             Debug.dump(graph, "after inlining %s", callee);
-                            afterInline(graph, originalGraph, null);
-                            substituteCallsOriginal = true;
-                        } else {
-                            StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee);
-                            if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) &&
-                                            (policy.shouldInline(callee, methodToParse) || (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)))) {
-                                StructuredGraph targetGraph;
-                                if (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)) {
-                                    targetGraph = intrinsicGraph;
-                                } else {
-                                    if (callee.getName().startsWith("$jacoco")) {
-                                        throw new GraalInternalError("Parsing call to JaCoCo instrumentation method " + format("%H.%n(%p)", callee) + " from " + format("%H.%n(%p)", methodToParse) +
-                                                        " while preparing replacement " + format("%H.%n(%p)", method) + ". Placing \"//JaCoCo Exclude\" anywhere in " +
-                                                        methodToParse.getDeclaringClass().getSourceFileName() + " should fix this.");
-                                    }
-                                    targetGraph = parseGraph(callee, policy);
-                                }
-                                Object beforeInlineData = beforeInline(callTarget, targetGraph);
-                                InliningUtil.inline(callTarget.invoke(), targetGraph, true);
-                                Debug.dump(graph, "after inlining %s", callee);
-                                afterInline(graph, targetGraph, beforeInlineData);
-                            }
+                            afterInline(graph, targetGraph, beforeInlineData);
                         }
                     }
+                }
 
-                    afterInlining(graph);
+                afterInlining(graph);
 
-                    for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
-                        end.disableSafepoint();
-                    }
+                for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
+                    end.disableSafepoint();
+                }
 
-                    new DeadCodeEliminationPhase().apply(graph);
-                }
-            });
+                new DeadCodeEliminationPhase().apply(graph);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
             return graph;
         }
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sat Nov 30 01:16:55 2013 +0100
@@ -34,6 +34,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.*;
@@ -410,17 +411,13 @@
             SnippetTemplate template = UseSnippetTemplateCache ? templates.get(args.cacheKey) : null;
             if (template == null) {
                 SnippetTemplates.increment();
-                try (TimerCloseable a = SnippetTemplateCreationTime.start()) {
-                    template = Debug.scope("SnippetSpecialization", args.info.method, new Callable<SnippetTemplate>() {
-
-                        @Override
-                        public SnippetTemplate call() throws Exception {
-                            return new SnippetTemplate(providers, args);
-                        }
-                    });
+                try (TimerCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) {
+                    template = new SnippetTemplate(providers, args);
                     if (UseSnippetTemplateCache) {
                         templates.put(args.cacheKey, template);
                     }
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
                 }
             }
             return template;
@@ -583,13 +580,12 @@
 
         // Perform lowering on the snippet
         snippetCopy.setGuardsStage(args.cacheKey.guardsStage);
-        Debug.scope("LoweringSnippetTemplate", snippetCopy, new Runnable() {
-
-            public void run() {
-                PhaseContext c = new PhaseContext(providers, new Assumptions(false));
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(snippetCopy, c);
-            }
-        });
+        try (Scope s = Debug.scope("LoweringSnippetTemplate", snippetCopy)) {
+            PhaseContext c = new PhaseContext(providers, new Assumptions(false));
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(snippetCopy, c);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
         // Remove all frame states from snippet graph. Snippets must be atomic (i.e. free
         // of side-effects that prevent deoptimizing to a point before the snippet).
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Sat Nov 30 01:16:55 2013 +0100
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -97,12 +98,11 @@
     protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
         replacementGraph.setGuardsStage(graph().getGuardsStage());
         final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.assumptions());
-        Debug.scope("LoweringReplacement", replacementGraph, new Runnable() {
-
-            public void run() {
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(replacementGraph, c);
-            }
-        });
+        try (Scope s = Debug.scope("LoweringReplacement", replacementGraph)) {
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(replacementGraph, c);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
         return replacementGraph;
     }
 
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Sat Nov 30 01:16:55 2013 +0100
@@ -23,7 +23,6 @@
 package com.oracle.graal.truffle.test;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import org.junit.*;
 
@@ -31,6 +30,7 @@
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.java.*;
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
@@ -102,56 +102,53 @@
             compilable.call(null, arguments);
         } while (compilable.inline());
 
-        StructuredGraph graph = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable), new Callable<StructuredGraph>() {
+        try (Scope s = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable))) {
+
+            StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions);
+            CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads);
+            PhaseContext context = new PhaseContext(getProviders(), assumptions);
+
+            if (resultGraph.hasLoops()) {
+                boolean unrolled;
+                do {
+                    unrolled = false;
+                    LoopsData loopsData = new LoopsData(resultGraph);
+                    loopsData.detectedCountedLoops();
+                    for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) {
+                        if (ex.counted().isConstantMaxTripCount()) {
+                            long constant = ex.counted().constantMaxTripCount();
+                            if (constant <= UNROLL_LIMIT) {
+                                LoopTransformations.fullUnroll(ex, context, canonicalizer);
+                                Debug.dump(resultGraph, "After loop unrolling %d times", constant);
+
+                                canonicalizer.apply(resultGraph, context);
+                                unrolled = true;
+                                break;
+                            }
+                        }
+                    }
+                } while (unrolled);
+            }
+
+            new DeadCodeEliminationPhase().apply(resultGraph);
+            new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context);
+
+            return resultGraph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+    }
+
+    private static List<LoopEx> innerLoopsFirst(Collection<LoopEx> loops) {
+        ArrayList<LoopEx> sortedLoops = new ArrayList<>(loops);
+        Collections.sort(sortedLoops, new Comparator<LoopEx>() {
 
             @Override
-            public StructuredGraph call() {
-                StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions);
-                CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads);
-                PhaseContext context = new PhaseContext(getProviders(), assumptions);
-
-                if (resultGraph.hasLoops()) {
-                    boolean unrolled;
-                    do {
-                        unrolled = false;
-                        LoopsData loopsData = new LoopsData(resultGraph);
-                        loopsData.detectedCountedLoops();
-                        for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) {
-                            if (ex.counted().isConstantMaxTripCount()) {
-                                long constant = ex.counted().constantMaxTripCount();
-                                if (constant <= UNROLL_LIMIT) {
-                                    LoopTransformations.fullUnroll(ex, context, canonicalizer);
-                                    Debug.dump(resultGraph, "After loop unrolling %d times", constant);
-
-                                    canonicalizer.apply(resultGraph, context);
-                                    unrolled = true;
-                                    break;
-                                }
-                            }
-                        }
-                    } while (unrolled);
-                }
-
-                new DeadCodeEliminationPhase().apply(resultGraph);
-                new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context);
-
-                return resultGraph;
-            }
-
-            private List<LoopEx> innerLoopsFirst(Collection<LoopEx> loops) {
-                ArrayList<LoopEx> sortedLoops = new ArrayList<>(loops);
-                Collections.sort(sortedLoops, new Comparator<LoopEx>() {
-
-                    @Override
-                    public int compare(LoopEx o1, LoopEx o2) {
-                        return o2.lirLoop().depth - o1.lirLoop().depth;
-                    }
-                });
-                return sortedLoops;
+            public int compare(LoopEx o1, LoopEx o2) {
+                return o2.lirLoop().depth - o1.lirLoop().depth;
             }
         });
-
-        return graph;
+        return sortedLoops;
     }
 
     protected void removeFrameStates(StructuredGraph graph) {
@@ -163,44 +160,42 @@
         new DeadCodeEliminationPhase().apply(graph);
     }
 
+    @SuppressWarnings("deprecation")
     protected StructuredGraph parseForComparison(final String methodName) {
 
-        StructuredGraph graphResult = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName), new Callable<StructuredGraph>() {
+        try (Scope s = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName))) {
+            Assumptions assumptions = new Assumptions(false);
+            StructuredGraph graph = parse(methodName);
+            PhaseContext context = new PhaseContext(getProviders(), assumptions);
+            CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
+            canonicalizer.apply(graph, context);
 
-            @SuppressWarnings("deprecation")
-            public StructuredGraph call() {
-                Assumptions assumptions = new Assumptions(false);
-                StructuredGraph graph = parse(methodName);
-                PhaseContext context = new PhaseContext(getProviders(), assumptions);
-                CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-                canonicalizer.apply(graph, context);
-
-                // Additional inlining.
-                final PhasePlan plan = new PhasePlan();
-                GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations);
-                plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-                canonicalizer.addToPhasePlan(plan, context);
-                plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase());
+            // Additional inlining.
+            final PhasePlan plan = new PhasePlan();
+            GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations);
+            plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
+            canonicalizer.addToPhasePlan(plan, context);
+            plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase());
 
-                new ConvertDeoptimizeToGuardPhase().apply(graph);
-                canonicalizer.apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
+            new ConvertDeoptimizeToGuardPhase().apply(graph);
+            canonicalizer.apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph);
 
-                HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, plan, OptimisticOptimizations.NONE);
-                InliningPhase inliningPhase = new InliningPhase(canonicalizer);
-                inliningPhase.apply(graph, highTierContext);
-                removeFrameStates(graph);
+            HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, plan, OptimisticOptimizations.NONE);
+            InliningPhase inliningPhase = new InliningPhase(canonicalizer);
+            inliningPhase.apply(graph, highTierContext);
+            removeFrameStates(graph);
 
-                new ConvertDeoptimizeToGuardPhase().apply(graph);
-                canonicalizer.apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
+            new ConvertDeoptimizeToGuardPhase().apply(graph);
+            canonicalizer.apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph);
 
-                new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
-                canonicalizer.apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph);
-                return graph;
-            }
-        });
-        return graphResult;
+            new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
+            canonicalizer.apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph);
+            return graph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Sat Nov 30 01:16:55 2013 +0100
@@ -32,6 +32,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Graph.Mark;
@@ -105,78 +106,76 @@
 
         final StructuredGraph graph = new StructuredGraph(executeHelperMethod);
 
-        Debug.scope("createGraph", graph, new Runnable() {
+        try (Scope s = Debug.scope("createGraph", graph)) {
+            new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), config, TruffleCompilerImpl.Optimizations).apply(graph);
 
-            @Override
-            public void run() {
-                new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), config, TruffleCompilerImpl.Optimizations).apply(graph);
+            // Replace thisNode with constant.
+            LocalNode thisNode = graph.getLocal(0);
+            thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph));
 
-                // Replace thisNode with constant.
-                LocalNode thisNode = graph.getLocal(0);
-                thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph));
+            // Canonicalize / constant propagate.
+            PhaseContext baseContext = new PhaseContext(providers, assumptions);
+            canonicalizer.apply(graph, baseContext);
 
-                // Canonicalize / constant propagate.
-                PhaseContext baseContext = new PhaseContext(providers, assumptions);
-                canonicalizer.apply(graph, baseContext);
+            // Intrinsify methods.
+            new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
 
-                // Intrinsify methods.
-                new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
+            NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first();
+            if (newFrameNode == null) {
+                throw GraalInternalError.shouldNotReachHere("frame not found");
+            }
 
-                NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first();
-                if (newFrameNode == null) {
-                    throw GraalInternalError.shouldNotReachHere("frame not found");
-                }
+            Debug.dump(graph, "Before inlining");
 
-                Debug.dump(graph, "Before inlining");
-
-                // Make sure frame does not escape.
-                expandTree(graph, assumptions);
+            // Make sure frame does not escape.
+            expandTree(graph, assumptions);
 
-                if (Thread.interrupted()) {
-                    return;
-                }
+            if (Thread.interrupted()) {
+                return graph;
+            }
 
-                new VerifyFrameDoesNotEscapePhase().apply(graph, false);
+            new VerifyFrameDoesNotEscapePhase().apply(graph, false);
 
-                if (TraceTruffleCompilationDetails.getValue() && constantReceivers != null) {
-                    DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes");
-                    for (Constant c : constantReceivers) {
-                        histogram.add(c.asObject().getClass().getSimpleName());
-                    }
-                    new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram);
+            if (TraceTruffleCompilationDetails.getValue() && constantReceivers != null) {
+                DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes");
+                for (Constant c : constantReceivers) {
+                    histogram.add(c.asObject().getClass().getSimpleName());
                 }
+                new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram);
+            }
 
-                // Additional inlining.
-                final PhasePlan plan = new PhasePlan();
-                canonicalizer.apply(graph, baseContext);
-                HighTierContext tierContext = new HighTierContext(providers, assumptions, cache, plan, OptimisticOptimizations.NONE);
-
-                for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) {
-                    Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage());
-                    throw GraphUtil.approxSourceException(neverPartOfCompilationNode, exception);
-                }
+            // Additional inlining.
+            final PhasePlan plan = new PhasePlan();
+            canonicalizer.apply(graph, baseContext);
+            HighTierContext tierContext = new HighTierContext(providers, assumptions, cache, plan, OptimisticOptimizations.NONE);
 
-                // EA frame and clean up.
-                new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext);
-                new VerifyNoIntrinsicsLeftPhase().apply(graph, false);
-                for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) {
-                    materializeNode.replaceAtUsages(materializeNode.getFrame());
-                    graph.removeFixed(materializeNode);
-                }
-                for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.class)) {
-                    if (virtualObjectNode instanceof VirtualOnlyInstanceNode) {
-                        VirtualOnlyInstanceNode virtualOnlyInstanceNode = (VirtualOnlyInstanceNode) virtualObjectNode;
-                        virtualOnlyInstanceNode.setAllowMaterialization(true);
-                    } else if (virtualObjectNode instanceof VirtualInstanceNode) {
-                        VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode;
-                        ResolvedJavaType type = virtualInstanceNode.type();
-                        if (type.getAnnotation(CompilerDirectives.ValueType.class) != null) {
-                            virtualInstanceNode.setIdentity(false);
-                        }
+            for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) {
+                Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage());
+                throw GraphUtil.approxSourceException(neverPartOfCompilationNode, exception);
+            }
+
+            // EA frame and clean up.
+            new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext);
+            new VerifyNoIntrinsicsLeftPhase().apply(graph, false);
+            for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) {
+                materializeNode.replaceAtUsages(materializeNode.getFrame());
+                graph.removeFixed(materializeNode);
+            }
+            for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.class)) {
+                if (virtualObjectNode instanceof VirtualOnlyInstanceNode) {
+                    VirtualOnlyInstanceNode virtualOnlyInstanceNode = (VirtualOnlyInstanceNode) virtualObjectNode;
+                    virtualOnlyInstanceNode.setAllowMaterialization(true);
+                } else if (virtualObjectNode instanceof VirtualInstanceNode) {
+                    VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode;
+                    ResolvedJavaType type = virtualInstanceNode.type();
+                    if (type.getAnnotation(CompilerDirectives.ValueType.class) != null) {
+                        virtualInstanceNode.setIdentity(false);
                     }
                 }
             }
-        });
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
         return graph;
     }
@@ -254,44 +253,44 @@
                     local.replaceAndDelete(ConstantNode.forConstant(constant, phaseContext.getMetaAccess(), graphCopy));
                 }
             }
-            Debug.scope("TruffleUnrollLoop", targetMethod, new Runnable() {
-
-                @Override
-                public void run() {
+            try (Scope s = Debug.scope("TruffleUnrollLoop", targetMethod)) {
 
-                    canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes);
-                    boolean unrolled;
-                    do {
-                        unrolled = false;
-                        LoopsData loopsData = new LoopsData(graphCopy);
-                        loopsData.detectedCountedLoops();
-                        for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) {
-                            if (ex.counted().isConstantMaxTripCount()) {
-                                long constant = ex.counted().constantMaxTripCount();
-                                LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer);
-                                Debug.dump(graphCopy, "After loop unrolling %d times", constant);
-                                unrolled = true;
-                                break;
-                            }
+                canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes);
+                boolean unrolled;
+                do {
+                    unrolled = false;
+                    LoopsData loopsData = new LoopsData(graphCopy);
+                    loopsData.detectedCountedLoops();
+                    for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) {
+                        if (ex.counted().isConstantMaxTripCount()) {
+                            long constant = ex.counted().constantMaxTripCount();
+                            LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer);
+                            Debug.dump(graphCopy, "After loop unrolling %d times", constant);
+                            unrolled = true;
+                            break;
                         }
-                    } while (unrolled);
-                }
-
-                private List<LoopEx> innerLoopsFirst(Collection<LoopEx> loops) {
-                    ArrayList<LoopEx> sortedLoops = new ArrayList<>(loops);
-                    Collections.sort(sortedLoops, new Comparator<LoopEx>() {
+                    }
+                } while (unrolled);
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
 
-                        @Override
-                        public int compare(LoopEx o1, LoopEx o2) {
-                            return o2.lirLoop().depth - o1.lirLoop().depth;
-                        }
-                    });
-                    return sortedLoops;
-                }
-            });
             return graphCopy;
         } else {
             return graph;
         }
     }
+
+    private static List<LoopEx> innerLoopsFirst(Collection<LoopEx> loops) {
+        ArrayList<LoopEx> sortedLoops = new ArrayList<>(loops);
+        Collections.sort(sortedLoops, new Comparator<LoopEx>() {
+
+            @Override
+            public int compare(LoopEx o1, LoopEx o2) {
+                return o2.lirLoop().depth - o1.lirLoop().depth;
+            }
+        });
+        return sortedLoops;
+    }
+
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Sat Nov 30 01:16:55 2013 +0100
@@ -26,13 +26,13 @@
 
 import java.lang.reflect.*;
 import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.Node;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.java.*;
@@ -91,102 +91,101 @@
         }
 
         cache.put(key, markerGraph);
-        resultGraph = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method}, new Callable<StructuredGraph>() {
+        try (Scope s = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method})) {
+
+            final StructuredGraph graph = new StructuredGraph(method);
+            PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
+            new GraphBuilderPhase(phaseContext.getMetaAccess(), providers.getForeignCalls(), config, optimisticOptimizations).apply(graph);
+
+            for (LocalNode l : graph.getNodes(LocalNode.class)) {
+                if (l.kind() == Kind.Object) {
+                    ValueNode actualArgument = arguments.get(l.index());
+                    l.setStamp(l.stamp().join(actualArgument.stamp()));
+                }
+            }
+
+            // Intrinsify methods.
+            new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
 
-            public StructuredGraph call() {
+            // Convert deopt to guards.
+            new ConvertDeoptimizeToGuardPhase().apply(graph);
+
+            CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!AOTCompilation.getValue());
+            PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizerPhase);
+
+            Mark mark = null;
+            while (true) {
+
+                partialEscapePhase.apply(graph, phaseContext);
+
+                // Conditional elimination.
+                ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(phaseContext.getMetaAccess());
+                conditionalEliminationPhase.apply(graph);
+
+                // Canonicalize / constant propagate.
+                canonicalizerPhase.apply(graph, phaseContext);
 
-                final StructuredGraph graph = new StructuredGraph(method);
-                PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
-                new GraphBuilderPhase(phaseContext.getMetaAccess(), providers.getForeignCalls(), config, optimisticOptimizations).apply(graph);
-
-                for (LocalNode l : graph.getNodes(LocalNode.class)) {
-                    if (l.kind() == Kind.Object) {
-                        ValueNode actualArgument = arguments.get(l.index());
-                        l.setStamp(l.stamp().join(actualArgument.stamp()));
+                boolean inliningProgress = false;
+                for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) {
+                    if (graph.getMark().equals(mark)) {
+                        // Make sure macro substitutions such as
+                        // CompilerDirectives.transferToInterpreter get processed first.
+                        for (Node newNode : graph.getNewNodes(mark)) {
+                            if (newNode instanceof MethodCallTargetNode) {
+                                MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode;
+                                Class<? extends FixedWithNextNode> macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod());
+                                if (macroSubstitution != null) {
+                                    InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution);
+                                } else {
+                                    tryCutOffRuntimeExceptions(methodCallTargetNode);
+                                }
+                            }
+                        }
+                        mark = graph.getMark();
+                    }
+                    if (methodCallTarget.isAlive() && methodCallTarget.invoke() != null && shouldInline(methodCallTarget)) {
+                        inliningProgress = true;
+                        List<Node> canonicalizerUsages = new ArrayList<Node>();
+                        for (Node n : methodCallTarget.invoke().asNode().usages()) {
+                            if (n instanceof Canonicalizable) {
+                                canonicalizerUsages.add(n);
+                            }
+                        }
+                        List<ValueNode> argumentSnapshot = methodCallTarget.arguments().snapshot();
+                        Mark beforeInvokeMark = graph.getMark();
+                        expandInvoke(methodCallTarget);
+                        for (Node arg : argumentSnapshot) {
+                            if (arg != null && arg.recordsUsages()) {
+                                for (Node argUsage : arg.usages()) {
+                                    if (graph.isNew(beforeInvokeMark, argUsage) && argUsage instanceof Canonicalizable) {
+                                        canonicalizerUsages.add(argUsage);
+                                    }
+                                }
+                            }
+                        }
+                        canonicalizerPhase.applyIncremental(graph, phaseContext, canonicalizerUsages);
                     }
                 }
 
-                // Intrinsify methods.
-                new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
-
                 // Convert deopt to guards.
                 new ConvertDeoptimizeToGuardPhase().apply(graph);
 
-                CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!AOTCompilation.getValue());
-                PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizerPhase);
-
-                Mark mark = null;
-                while (true) {
+                new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, phaseContext);
 
-                    partialEscapePhase.apply(graph, phaseContext);
-
-                    // Conditional elimination.
-                    ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(phaseContext.getMetaAccess());
-                    conditionalEliminationPhase.apply(graph);
-
-                    // Canonicalize / constant propagate.
-                    canonicalizerPhase.apply(graph, phaseContext);
+                if (!inliningProgress) {
+                    break;
+                }
+            }
 
-                    boolean inliningProgress = false;
-                    for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) {
-                        if (graph.getMark().equals(mark)) {
-                            // Make sure macro substitutions such as
-                            // CompilerDirectives.transferToInterpreter get processed first.
-                            for (Node newNode : graph.getNewNodes(mark)) {
-                                if (newNode instanceof MethodCallTargetNode) {
-                                    MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode;
-                                    Class<? extends FixedWithNextNode> macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod());
-                                    if (macroSubstitution != null) {
-                                        InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution);
-                                    } else {
-                                        tryCutOffRuntimeExceptions(methodCallTargetNode);
-                                    }
-                                }
-                            }
-                            mark = graph.getMark();
-                        }
-                        if (methodCallTarget.isAlive() && methodCallTarget.invoke() != null && shouldInline(methodCallTarget)) {
-                            inliningProgress = true;
-                            List<Node> canonicalizerUsages = new ArrayList<Node>();
-                            for (Node n : methodCallTarget.invoke().asNode().usages()) {
-                                if (n instanceof Canonicalizable) {
-                                    canonicalizerUsages.add(n);
-                                }
-                            }
-                            List<ValueNode> argumentSnapshot = methodCallTarget.arguments().snapshot();
-                            Mark beforeInvokeMark = graph.getMark();
-                            expandInvoke(methodCallTarget);
-                            for (Node arg : argumentSnapshot) {
-                                if (arg != null && arg.recordsUsages()) {
-                                    for (Node argUsage : arg.usages()) {
-                                        if (graph.isNew(beforeInvokeMark, argUsage) && argUsage instanceof Canonicalizable) {
-                                            canonicalizerUsages.add(argUsage);
-                                        }
-                                    }
-                                }
-                            }
-                            canonicalizerPhase.applyIncremental(graph, phaseContext, canonicalizerUsages);
-                        }
-                    }
+            cache.put(key, graph);
+            if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) {
+                TTY.println(String.format("[truffle] added to graph cache method %s with %d nodes.", method, graph.getNodeCount()));
+            }
+            return graph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-                    // Convert deopt to guards.
-                    new ConvertDeoptimizeToGuardPhase().apply(graph);
-
-                    new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, phaseContext);
-
-                    if (!inliningProgress) {
-                        break;
-                    }
-                }
-
-                if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) {
-                    TTY.println(String.format("[truffle] added to graph cache method %s with %d nodes.", method, graph.getNodeCount()));
-                }
-                return graph;
-            }
-        });
-        cache.put(key, resultGraph);
-        return resultGraph;
     }
 
     private void expandInvoke(MethodCallTargetNode methodCallTargetNode) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Sat Nov 30 01:16:55 2013 +0100
@@ -38,6 +38,7 @@
 import com.oracle.graal.compiler.CompilerThreadFactory.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
@@ -109,21 +110,16 @@
     }
 
     public Future<InstalledCode> compile(final OptimizedCallTarget compilable) {
-        Future<InstalledCode> future = compileQueue.submit(new Callable<InstalledCode>() {
-
+        return compileQueue.submit(new Callable<InstalledCode>() {
             @Override
             public InstalledCode call() throws Exception {
-                Object[] debug = new Object[]{new TruffleDebugJavaMethod(compilable)};
-                return Debug.scope("Truffle", debug, new Callable<InstalledCode>() {
-
-                    @Override
-                    public InstalledCode call() throws Exception {
-                        return compileMethodImpl(compilable);
-                    }
-                });
+                try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(compilable))) {
+                    return compileMethodImpl(compilable);
+                } catch (Throwable e) {
+                    throw Debug.handle(e);
+                }
             }
         });
-        return future;
     }
 
     public static final DebugTimer PartialEvaluationTime = Debug.timer("PartialEvaluationTime");
@@ -208,31 +204,22 @@
     public InstalledCode compileMethodHelper(final StructuredGraph graph, final GraphBuilderConfiguration config, final Assumptions assumptions) {
         final PhasePlan plan = createPhasePlan(config);
 
-        Debug.scope("TruffleFinal", new Runnable() {
-
-            @Override
-            public void run() {
-                Debug.dump(graph, "After TruffleTier");
-            }
-        });
-
-        final CompilationResult result = Debug.scope("TruffleGraal", new Callable<CompilationResult>() {
+        try (Scope s = Debug.scope("TruffleFinal")) {
+            Debug.dump(graph, "After TruffleTier");
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
-            @Override
-            public CompilationResult call() {
-                try (TimerCloseable a = CompilationTime.start()) {
-                    return Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Callable<CompilationResult>() {
-                        public CompilationResult call() {
-                            CodeCacheProvider codeCache = providers.getCodeCache();
-                            CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
-                            CompilationResult compilationResult = new CompilationResult(graph.method().toString());
-                            return GraalCompiler.compileGraphNoScope(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL,
-                                            new SpeculationLog(), suites, compilationResult);
-                        }
-                    });
-                }
-            }
-        });
+        CompilationResult result = null;
+        try (TimerCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache())) {
+            CodeCacheProvider codeCache = providers.getCodeCache();
+            CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
+            CompilationResult compilationResult = new CompilationResult(graph.method().toString());
+            result = GraalCompiler.compileGraphNoScope(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), suites,
+                            compilationResult);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
         List<AssumptionValidAssumption> validAssumptions = new ArrayList<>();
         Assumptions newAssumptions = new Assumptions(true);
@@ -250,19 +237,16 @@
 
         result.setAssumptions(newAssumptions);
 
-        InstalledCode compiledMethod = Debug.scope("CodeInstall", new Object[]{providers.getCodeCache()}, new Callable<InstalledCode>() {
-
-            @Override
-            public InstalledCode call() throws Exception {
-                try (TimerCloseable a = CodeInstallationTime.start()) {
-                    InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result);
-                    if (installedCode != null) {
-                        Debug.dump(new Object[]{result, installedCode}, "After code installation");
-                    }
-                    return installedCode;
-                }
+        InstalledCode compiledMethod = null;
+        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start()) {
+            InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result);
+            if (installedCode != null) {
+                Debug.dump(new Object[]{result, installedCode}, "After code installation");
             }
-        });
+            compiledMethod = installedCode;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
 
         for (AssumptionValidAssumption a : validAssumptions) {
             a.getAssumption().registerInstalledCode(compiledMethod);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Sat Nov 30 01:16:55 2013 +0100
@@ -30,7 +30,7 @@
 
 /**
  * Enables a Truffle compilable to masquerade as a {@link JavaMethod} for use as a context value in
- * {@linkplain Debug#scope(String, Object[], Runnable) debug scopes}.
+ * {@linkplain Debug#scope(String, Object...) debug scopes}.
  */
 public class TruffleDebugJavaMethod implements JavaMethod {
     private final DefaultCallTarget compilable;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Sat Nov 30 01:16:55 2013 +0100
@@ -22,9 +22,8 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
-import java.util.concurrent.*;
-
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
@@ -60,45 +59,37 @@
     public boolean runAnalysis(final StructuredGraph graph, final PhaseContextT context) {
         boolean changed = false;
         for (int iteration = 0; iteration < maxIterations; iteration++) {
-            boolean currentChanged = Debug.scope("iteration " + iteration, new Callable<Boolean>() {
 
-                @Override
-                public Boolean call() {
-                    SchedulePhase schedule = new SchedulePhase();
-                    schedule.apply(graph, false);
-                    Closure<?> closure = createEffectsClosure(context, schedule);
-                    ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
+            try (Scope s = Debug.scope("iteration " + iteration)) {
+                SchedulePhase schedule = new SchedulePhase();
+                schedule.apply(graph, false);
+                Closure<?> closure = createEffectsClosure(context, schedule);
+                ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock());
 
-                    if (!closure.hasChanged()) {
-                        return false;
-                    }
+                if (!closure.hasChanged()) {
+                    break;
+                }
 
-                    // apply the effects collected during this iteration
-                    HashSetNodeChangeListener listener = new HashSetNodeChangeListener();
-                    graph.trackInputChange(listener);
-                    graph.trackUsagesDroppedZero(listener);
-                    closure.applyEffects();
-                    graph.stopTrackingInputChange();
-                    graph.stopTrackingUsagesDroppedZero();
+                // apply the effects collected during this iteration
+                HashSetNodeChangeListener listener = new HashSetNodeChangeListener();
+                graph.trackInputChange(listener);
+                graph.trackUsagesDroppedZero(listener);
+                closure.applyEffects();
+                graph.stopTrackingInputChange();
+                graph.stopTrackingUsagesDroppedZero();
 
-                    Debug.dump(graph, "after " + getName() + " iteration");
-
-                    new DeadCodeEliminationPhase().apply(graph);
+                Debug.dump(graph, "after " + getName() + " iteration");
 
-                    for (Node node : graph.getNodes()) {
-                        if (node instanceof Simplifiable) {
-                            listener.getChangedNodes().add(node);
-                        }
-                    }
-                    canonicalizer.applyIncremental(graph, context, listener.getChangedNodes());
+                new DeadCodeEliminationPhase().apply(graph);
 
-                    return true;
+                for (Node node : graph.getNodes()) {
+                    if (node instanceof Simplifiable) {
+                        listener.getChangedNodes().add(node);
+                    }
                 }
-            });
-            if (!currentChanged) {
-                break;
+                canonicalizer.applyIncremental(graph, context, listener.getChangedNodes());
             }
-            changed |= currentChanged;
+            changed = true;
         }
         return changed;
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Fri Nov 29 20:46:54 2013 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java	Sat Nov 30 01:16:55 2013 +0100
@@ -25,9 +25,9 @@
 import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
@@ -53,34 +53,32 @@
     }
 
     private void runIterations(final StructuredGraph graph, final boolean simple, final HighTierContext context) {
-        Boolean continueIteration = true;
-        for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) {
-            continueIteration = Debug.scope("iteration " + iteration, new Callable<Boolean>() {
+        for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue(); iteration++) {
+            try (Scope s = Debug.scope("iteration " + iteration)) {
+                boolean progress = false;
+                PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer);
+                boolean eaResult = ea.runAnalysis(graph, context);
+                progress |= eaResult;
 
-                @Override
-                public Boolean call() {
-                    boolean progress = false;
-                    PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer);
-                    boolean eaResult = ea.runAnalysis(graph, context);
-                    progress |= eaResult;
-
-                    Map<Invoke, Double> hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null;
+                Map<Invoke, Double> hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null;
 
-                    InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase(true));
-                    inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE);
-                    inlining.apply(graph, context);
-                    progress |= inlining.getInliningCount() > 0;
+                InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase(true));
+                inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE);
+                inlining.apply(graph, context);
+                progress |= inlining.getInliningCount() > 0;
 
-                    new DeadCodeEliminationPhase().apply(graph);
+                new DeadCodeEliminationPhase().apply(graph);
 
-                    if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
-                        canonicalizer.apply(graph, context);
-                        new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context);
-                    }
-
-                    return progress;
+                if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) {
+                    canonicalizer.apply(graph, context);
+                    new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context);
                 }
-            });
+                if (!progress) {
+                    break;
+                }
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
         }
     }
 }