changeset 4370:44e2e5cb37f3

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 27 Jan 2012 16:39:32 +0100
parents efc430d943c0 (diff) b801d2f9e2b0 (current diff)
children 87c11dbb58c4
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FindInductionVariablesPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/RemoveInductionVariablesPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/BasicInductionVariableNode.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/DerivedInductionVariableNode.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/InductionVariableNode.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/LinearInductionVariableNode.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/loop/LoopCounterNode.java graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/NestedLoopTest.java
diffstat 65 files changed, 1634 insertions(+), 1569 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiResult.java	Fri Jan 27 00:40:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.cri.ci;
-
-/**
- * Represents the result of compiling a method. The result can include a target method with machine code and metadata,
- * and/or statistics. If the compiler bailed out due to malformed bytecode, an internal error, or other cause, it will
- * supply the bailout object.
- */
-public class CiResult {
-    private final CiTargetMethod targetMethod;
-    private final CiBailout bailout;
-
-    /**
-     * Creates a new compilation result.
-     * @param targetMethod the method that was produced, if any
-     * @param bailout the bailout condition that occurred
-     * @param stats statistics about the compilation
-     */
-    public CiResult(CiTargetMethod targetMethod, CiBailout bailout) {
-        this.targetMethod = targetMethod;
-        this.bailout = bailout;
-    }
-
-    /**
-     * Gets the target method that was produced by this compilation. If no target method was
-     * produced, but a bailout occured, then the bailout exception will be thrown at this point.
-     * @return the target method produced
-     * @throws {@link CiBailout} if a bailout occurred
-     */
-    public CiTargetMethod targetMethod() {
-        if (bailout != null) {
-            throw bailout;
-        }
-        return targetMethod;
-    }
-
-    /**
-     * Returns the bailout condition that occurred for this compilation, if any.
-     * @return the bailout
-     */
-    public CiBailout bailout() {
-        return bailout;
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/LinearScanAllocator.java	Fri Jan 27 16:39:32 2012 +0100
@@ -39,16 +39,15 @@
 import com.oracle.max.graal.compiler.lir.LIRPhiMapping.PhiValueProcedure;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
 
 public class LinearScanAllocator {
-    private final GraalContext context;
     private final LIR lir;
     private final FrameMap frameMap;
 
     private final DataFlowAnalysis dataFlow;
 
-    public LinearScanAllocator(GraalContext context, LIR lir, FrameMap frameMap) {
-        this.context = context;
+    public LinearScanAllocator(LIR lir, FrameMap frameMap) {
         this.lir = lir;
         this.frameMap = frameMap;
 
@@ -159,23 +158,23 @@
         assert LIRVerifier.verify(true, lir, frameMap);
 
         dataFlow.execute();
-        IntervalPrinter.printBeforeAllocation("Before register allocation", context, lir, frameMap.registerConfig, dataFlow);
+        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
 
         allocate();
 
-        IntervalPrinter.printAfterAllocation("After linear scan allocation", context, lir, frameMap.registerConfig, dataFlow, blockEndLocations);
+        IntervalPrinter.printAfterAllocation("After linear scan allocation", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
 
         ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
         resolveDataFlow.execute();
         frameMap.finish();
 
-        IntervalPrinter.printAfterAllocation("After resolve data flow", context, lir, frameMap.registerConfig, dataFlow, blockEndLocations);
+        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockEndLocations);
         assert RegisterVerifier.verify(lir, frameMap);
 
         AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
         assignRegisters.execute();
 
-        context.observable.fireCompilationEvent("After register asignment", lir);
+        Debug.dump(lir, "After register asignment");
         assert LIRVerifier.verify(false, lir, frameMap);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Fri Jan 27 16:39:32 2012 +0100
@@ -39,16 +39,15 @@
 import com.oracle.max.graal.compiler.lir.LIRPhiMapping.PhiValueProcedure;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
 
 public class SpillAllAllocator {
-    private final GraalContext context;
     private final LIR lir;
     private final FrameMap frameMap;
 
     private final DataFlowAnalysis dataFlow;
 
-    public SpillAllAllocator(GraalContext context, LIR lir, FrameMap frameMap) {
-        this.context = context;
+    public SpillAllAllocator(LIR lir, FrameMap frameMap) {
         this.lir = lir;
         this.frameMap = frameMap;
 
@@ -134,23 +133,23 @@
         assert LIRVerifier.verify(true, lir, frameMap);
 
         dataFlow.execute();
-        IntervalPrinter.printBeforeAllocation("Before register allocation", context, lir, frameMap.registerConfig, dataFlow);
+        IntervalPrinter.printBeforeAllocation("Before register allocation", lir, frameMap.registerConfig, dataFlow);
 
         allocate();
 
-        IntervalPrinter.printAfterAllocation("After spill all allocation", context, lir, frameMap.registerConfig, dataFlow, blockLocations);
+        IntervalPrinter.printAfterAllocation("After spill all allocation", lir, frameMap.registerConfig, dataFlow, blockLocations);
 
         ResolveDataFlow resolveDataFlow = new ResolveDataFlowImpl(lir, moveResolver, dataFlow);
         resolveDataFlow.execute();
         frameMap.finish();
 
-        IntervalPrinter.printAfterAllocation("After resolve data flow", context, lir, frameMap.registerConfig, dataFlow, blockLocations);
+        IntervalPrinter.printAfterAllocation("After resolve data flow", lir, frameMap.registerConfig, dataFlow, blockLocations);
         assert RegisterVerifier.verify(lir, frameMap);
 
         AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
         assignRegisters.execute();
 
-        context.observable.fireCompilationEvent("After register asignment", lir);
+        Debug.dump(lir, "After register asignment");
         assert LIRVerifier.verify(false, lir, frameMap);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/IntervalPrinter.java	Fri Jan 27 16:39:32 2012 +0100
@@ -30,7 +30,6 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.graal.alloc.simple.*;
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag;
 import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode;
@@ -39,18 +38,18 @@
 
 public final class IntervalPrinter {
 
-    public static void printBeforeAllocation(String label, GraalContext context, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow) {
-        if (context.isObserved()) {
-            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, null);
-            context.observable.fireCompilationEvent(label, lir, printer.execute());
-        }
+    public static void printBeforeAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow) {
+//        if (context.isObserved()) {
+//            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, null);
+//            context.observable.fireCompilationEvent(label, lir, printer.execute());
+//        }
     }
 
-    public static void printAfterAllocation(String label, GraalContext context, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
-        if (context.isObserved()) {
-            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, blockEndLocations);
-            context.observable.fireCompilationEvent(label, lir, printer.execute());
-        }
+    public static void printAfterAllocation(String label, LIR lir, RiRegisterConfig registerConfig, DataFlowAnalysis dataFlow, LocationMap[] blockEndLocations) {
+//        if (context.isObserved()) {
+//            IntervalPrinter printer = new IntervalPrinter(lir, registerConfig, dataFlow, blockEndLocations);
+//            context.observable.fireCompilationEvent(label, lir, printer.execute());
+//        }
     }
 
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Fri Jan 27 16:39:32 2012 +0100
@@ -23,6 +23,7 @@
 package com.oracle.max.graal.compiler;
 
 import java.util.*;
+import java.util.concurrent.*;
 
 import com.oracle.max.asm.*;
 import com.oracle.max.cri.ci.*;
@@ -34,19 +35,17 @@
 import com.oracle.max.graal.compiler.asm.*;
 import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.target.*;
 import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 
 public class GraalCompiler {
 
-    public final GraalContext context;
-
     /**
      * The target that this compiler has been configured for.
      */
@@ -67,8 +66,7 @@
      */
     public final Backend backend;
 
-    public GraalCompiler(GraalContext context, GraalRuntime runtime, CiTarget target, Backend backend, RiXirGenerator xirGen) {
-        this.context = context;
+    public GraalCompiler(GraalRuntime runtime, CiTarget target, Backend backend, RiXirGenerator xirGen) {
         this.runtime = runtime;
         this.target = target;
         this.xir = xirGen;
@@ -79,169 +77,143 @@
         return compileMethod(method, new StructuredGraph(method), osrBCI, plan);
     }
 
-    public CiTargetMethod compileMethod(RiResolvedMethod method, StructuredGraph graph, int osrBCI, PhasePlan plan) {
+    public CiTargetMethod compileMethod(final RiResolvedMethod method, final StructuredGraph graph, int osrBCI, final PhasePlan plan) {
         if (osrBCI != -1) {
             throw new CiBailout("No OSR supported");
         }
-        context.timers.startScope(getClass());
-        try {
-            long startTime = 0;
-            int index = context.metrics.CompiledMethods++;
-            final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed();
-            if (printCompilation) {
-                TTY.println(String.format("Graal %4d %-70s %-45s %-50s ...",
-                                index,
-                                method.holder().name(),
-                                method.name(),
-                                method.signature().asString()));
-                startTime = System.nanoTime();
-            }
-            TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
-
-            CiTargetMethod result = null;
-            context.observable.fireCompilationStarted(runtime, target, method);
-            try {
-                try {
-                    CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null;
-                    LIR lir = emitHIR(graph, assumptions, plan);
-                    FrameMap frameMap = emitLIR(lir, graph, method);
-                    result = emitCode(assumptions, method, lir, frameMap);
-
-                    if (GraalOptions.Meter) {
-                        context.metrics.BytecodesCompiled += method.codeSize();
+        return Debug.scope(createScopeName(method), method, new Callable<CiTargetMethod>() {
+            public CiTargetMethod call() {
+                final CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null;
+                final LIR lir = Debug.scope("FrontEnd", graph, new Callable<LIR>() {
+                    public LIR call() {
+                        return emitHIR(graph, assumptions, plan);
+                    }
+                });
+                final FrameMap frameMap = Debug.scope("BackEnd", lir, new Callable<FrameMap>() {
+                    public FrameMap call() {
+                        return emitLIR(lir, graph, method);
+                    }
+                });
+                return Debug.scope("CodeGen", frameMap, new Callable<CiTargetMethod>() {
+                    public CiTargetMethod call() {
+                        return emitCode(assumptions, method, lir, frameMap);
                     }
-                } catch (CiBailout | GraalInternalError exception) {
-                    throw exception;
-                } catch (Throwable t) {
-                    throw new GraalInternalError(t);
-                }
-            } catch (GraalInternalError error) {
-                error.addContext("method", CiUtil.format("%H.%n(%p):%r", method));
-                if (context.isObserved()) {
-                    if (error.node() != null) {
-                        context.observable.fireCompilationEvent("VerificationError on Node " + error.node(), CompilationEvent.ERROR, this, error.node().graph());
-                    } else if (error.graph() != null) {
-                        context.observable.fireCompilationEvent("VerificationError on Graph " + error.graph(), CompilationEvent.ERROR, this, error.graph());
-                    }
-                }
-                throw error;
-            } finally {
-                context.observable.fireCompilationFinished(runtime, target, method);
-                filter.remove();
-                if (printCompilation) {
-                    long time = (System.nanoTime() - startTime) / 100000;
-                    TTY.println(String.format("Graal %4d %-70s %-45s %-50s | %3d.%dms %4dnodes %5dB",
-                                    index,
-                                    "",
-                                    "",
-                                    "",
-                                    time / 10,
-                                    time % 10,
-                                    graph.getNodeCount(),
-                                    (result != null ? result.targetCodeSize() : -1)));
-                }
+                });
             }
+        });
+    }
 
-            return result;
-        } finally {
-            context.timers.endScope();
+    private static String createScopeName(RiResolvedMethod method) {
+        if (Debug.isEnabled()) {
+            return String.format("[%s::%s]", createSimpleName(method.holder()), method.name());
+        } else {
+            return null;
         }
     }
 
+    private static String createSimpleName(RiResolvedType holder) {
+        String base = holder.name();
+        int slashIndex = base.lastIndexOf('/');
+        if (slashIndex == -1) {
+            slashIndex = 0;
+        }
+        return base.substring(slashIndex + 1, base.length() - 1);
+    }
+
     /**
      * Builds the graph, optimizes it.
      */
     public LIR emitHIR(StructuredGraph graph, CiAssumptions assumptions, PhasePlan plan) {
-        try {
-            context.timers.startScope("HIR");
+
+        if (graph.start().next() == null) {
+            plan.runPhases(PhasePosition.AFTER_PARSING, graph);
+            new DeadCodeEliminationPhase().apply(graph);
+        } else {
+            Debug.dump(graph, "initial state");
+        }
+
+        new PhiStampPhase().apply(graph);
+
+        if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) {
+            new ComputeProbabilityPhase().apply(graph);
+        }
 
-            if (graph.start().next() == null) {
-                plan.runPhases(PhasePosition.AFTER_PARSING, graph, context);
-                new DeadCodeEliminationPhase().apply(graph, context);
-            } else {
-                if (context.isObserved()) {
-                    context.observable.fireCompilationEvent("initial state", graph);
-                }
-            }
+        if (GraalOptions.Intrinsify) {
+            new IntrinsificationPhase(runtime).apply(graph);
+        }
 
+        if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
+            new InliningPhase(target, runtime, null, assumptions, plan).apply(graph);
+            new DeadCodeEliminationPhase().apply(graph);
             new PhiStampPhase().apply(graph);
+        }
 
-            if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) {
-                new ComputeProbabilityPhase().apply(graph, context);
-            }
-
-            if (GraalOptions.Intrinsify) {
-                new IntrinsificationPhase(runtime).apply(graph, context);
-            }
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+        }
 
-            if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
-                new InliningPhase(target, runtime, null, assumptions, plan).apply(graph, context);
-                new DeadCodeEliminationPhase().apply(graph, context);
-                new PhiStampPhase().apply(graph);
-            }
+        plan.runPhases(PhasePosition.HIGH_LEVEL, graph);
+
+        if (GraalOptions.OptLoops) {
+            new SafepointPollingEliminationPhase().apply(graph);
+        }
 
-            if (GraalOptions.OptCanonicalizer) {
-                new CanonicalizerPhase(target, runtime, assumptions).apply(graph, context);
-            }
+        if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) {
+            new EscapeAnalysisPhase(target, runtime, assumptions, plan).apply(graph);
+            new PhiStampPhase().apply(graph);
+            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+        }
 
-            plan.runPhases(PhasePosition.HIGH_LEVEL, graph, context);
+        if (GraalOptions.OptGVN) {
+            new GlobalValueNumberingPhase().apply(graph);
+        }
 
-            if (GraalOptions.OptLoops) {
-                new SafepointPollingEliminationPhase().apply(graph, context);
-            }
+        graph.mark();
+        new LoweringPhase(runtime).apply(graph);
+        new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph);
 
-            if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) {
-                new EscapeAnalysisPhase(target, runtime, assumptions, plan).apply(graph, context);
-                new PhiStampPhase().apply(graph);
-                new CanonicalizerPhase(target, runtime, assumptions).apply(graph, context);
+        if (GraalOptions.OptLoops) {
+            graph.mark();
+            new RemoveInductionVariablesPhase().apply(graph);
+            if (GraalOptions.OptCanonicalizer) {
+                new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph);
             }
+        }
 
+        if (GraalOptions.Lower) {
+            new FloatingReadPhase().apply(graph);
             if (GraalOptions.OptGVN) {
-                new GlobalValueNumberingPhase().apply(graph, context);
+                new GlobalValueNumberingPhase().apply(graph);
             }
-
-            graph.mark();
-            new LoweringPhase(runtime).apply(graph, context);
-            new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context);
-
-            if (GraalOptions.Lower) {
-                new FloatingReadPhase().apply(graph, context);
+            if (GraalOptions.OptReadElimination) {
+                new ReadEliminationPhase().apply(graph);
+            }
+        }
+        new RemovePlaceholderPhase().apply(graph);
+        new DeadCodeEliminationPhase().apply(graph);
 
-                if (GraalOptions.OptGVN) {
-                    new GlobalValueNumberingPhase().apply(graph, context);
-                }
+        plan.runPhases(PhasePosition.MID_LEVEL, graph);
 
-                if (GraalOptions.OptReadElimination) {
-                    new ReadEliminationPhase().apply(graph, context);
-                }
-            }
-            new RemovePlaceholderPhase().apply(graph, context);
-            new DeadCodeEliminationPhase().apply(graph, context);
+        plan.runPhases(PhasePosition.LOW_LEVEL, graph);
 
-            plan.runPhases(PhasePosition.MID_LEVEL, graph, context);
+        final IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY);
+        schedule.apply(graph);
 
-            plan.runPhases(PhasePosition.LOW_LEVEL, graph, context);
-
-            IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY);
-            schedule.apply(graph, context);
-
-            if (context.isObserved()) {
-                context.observable.fireCompilationEvent("After IdentifyBlocksPhase", graph, schedule);
+        final List<Block> blocks = schedule.getBlocks();
+        final NodeMap<LIRBlock> valueToBlock = new NodeMap<>(graph);
+        for (Block b : blocks) {
+            for (Node i : b.getInstructions()) {
+                valueToBlock.set(i, (LIRBlock) b);
             }
+        }
+        final LIRBlock startBlock = valueToBlock.get(graph.start());
+        assert startBlock != null;
+        assert startBlock.numberOfPreds() == 0;
 
-            List<Block> blocks = schedule.getBlocks();
-            NodeMap<LIRBlock> valueToBlock = new NodeMap<>(graph);
-            for (Block b : blocks) {
-                for (Node i : b.getInstructions()) {
-                    valueToBlock.set(i, (LIRBlock) b);
-                }
-            }
-            LIRBlock startBlock = valueToBlock.get(graph.start());
-            assert startBlock != null;
-            assert startBlock.numberOfPreds() == 0;
+        return Debug.scope("Compute Linear Scan Order", new Callable<LIR>() {
 
-            context.timers.startScope("Compute Linear Scan Order");
-            try {
+            @Override
+            public LIR call() {
                 ComputeLinearScanOrder clso = new ComputeLinearScanOrder(blocks.size(), schedule.loopCount(), startBlock);
                 List<LIRBlock> linearScanOrder = clso.linearScanOrder();
                 List<LIRBlock> codeEmittingOrder = clso.codeEmittingOrder();
@@ -252,111 +224,67 @@
                 }
 
                 LIR lir = new LIR(startBlock, linearScanOrder, codeEmittingOrder, valueToBlock, schedule.loopCount());
-
-                if (context.isObserved()) {
-                    context.observable.fireCompilationEvent("After linear scan order", graph, lir);
-                }
+                Debug.dump(lir, "After linear scan order");
                 return lir;
-            } catch (AssertionError t) {
-                    context.observable.fireCompilationEvent("AssertionError in ComputeLinearScanOrder", CompilationEvent.ERROR, graph);
-                throw t;
-            } catch (RuntimeException t) {
-                    context.observable.fireCompilationEvent("RuntimeException in ComputeLinearScanOrder", CompilationEvent.ERROR, graph);
-                throw t;
-            } finally {
-                context.timers.endScope();
+
             }
-        } finally {
-            context.timers.endScope();
-        }
+        });
     }
 
-    public FrameMap emitLIR(LIR lir, StructuredGraph graph, RiResolvedMethod method) {
-        context.timers.startScope("LIR");
-        try {
-            if (GraalOptions.GenLIR) {
-                context.timers.startScope("Create LIR");
-                LIRGenerator lirGenerator = null;
-                FrameMap frameMap;
-                try {
-                    frameMap = backend.newFrameMap(runtime.getRegisterConfig(method));
-
-                    lirGenerator = backend.newLIRGenerator(context, graph, frameMap, method, lir, xir);
+    public FrameMap emitLIR(final LIR lir, StructuredGraph graph, final RiResolvedMethod method) {
+        final FrameMap frameMap = backend.newFrameMap(runtime.getRegisterConfig(method));
+        final LIRGenerator lirGenerator = backend.newLIRGenerator(graph, frameMap, method, lir, xir);
 
-                    for (LIRBlock b : lir.linearScanOrder()) {
-                        lirGenerator.doBlock(b);
-                    }
-
-                    for (LIRBlock b : lir.linearScanOrder()) {
-                        if (b.phis != null) {
-                            b.phis.fillInputs(lirGenerator);
-                        }
-                    }
-                } finally {
-                    context.timers.endScope();
+        Debug.scope("LIRGen", new Runnable() {
+            public void run() {
+                for (LIRBlock b : lir.linearScanOrder()) {
+                    lirGenerator.doBlock(b);
                 }
 
-                if (context.isObserved()) {
-                    context.observable.fireCompilationEvent("After LIR generation", graph, lir, lirGenerator);
+                for (LIRBlock b : lir.linearScanOrder()) {
+                    if (b.phis != null) {
+                        b.phis.fillInputs(lirGenerator);
+                    }
                 }
+
+                Debug.dump(lirGenerator, "After LIR generation");
                 if (GraalOptions.PrintLIR && !TTY.isSuppressed()) {
                     LIR.printLIR(lir.linearScanOrder());
                 }
-
-                if (GraalOptions.AllocSSA) {
-                    new LinearScanAllocator(context, lir, frameMap).execute();
-//                    new SpillAllAllocator(context, lir, frameMap).execute();
-                } else {
-                    new LinearScan(context, target, method, graph, lir, lirGenerator, frameMap).allocate();
-                }
-                return frameMap;
-            } else {
-                return null;
             }
-        } catch (Error e) {
-            if (context.isObserved() && GraalOptions.PlotOnError) {
-                context.observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, graph);
+        });
+
+        Debug.scope("Allocator", new Runnable() {
+            public void run() {
+                if (GraalOptions.AllocSSA) {
+                    new LinearScanAllocator(lir, frameMap).execute();
+                    // new SpillAllAllocator(context, lir, frameMap).execute();
+                } else {
+                    new LinearScan(target, method, lir, lirGenerator, frameMap).allocate();
+                }
             }
-            throw e;
-        } catch (RuntimeException e) {
-            if (context.isObserved() && GraalOptions.PlotOnError) {
-                context.observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, graph);
-            }
-            throw e;
-        } finally {
-            context.timers.endScope();
-        }
+        });
+        return frameMap;
     }
 
     private TargetMethodAssembler createAssembler(FrameMap frameMap, LIR lir) {
         AbstractAssembler masm = backend.newAssembler(frameMap.registerConfig);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(context, target, runtime, frameMap, lir.slowPaths, masm);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime, frameMap, lir.slowPaths, masm);
         tasm.setFrameSize(frameMap.frameSize());
         tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
         return tasm;
     }
 
     public CiTargetMethod emitCode(CiAssumptions assumptions, RiResolvedMethod method, LIR lir, FrameMap frameMap) {
-        if (GraalOptions.GenLIR && GraalOptions.GenCode) {
-            context.timers.startScope("Create Code");
-            try {
-                TargetMethodAssembler tasm = createAssembler(frameMap, lir);
-                lir.emitCode(tasm);
+        TargetMethodAssembler tasm = createAssembler(frameMap, lir);
+        lir.emitCode(tasm);
 
-                CiTargetMethod targetMethod = tasm.finishTargetMethod(method, false);
-                if (assumptions != null && !assumptions.isEmpty()) {
-                    targetMethod.setAssumptions(assumptions);
-                }
-
-                if (context.isObserved()) {
-                    context.observable.fireCompilationEvent("After code generation", lir, targetMethod);
-                }
-                return targetMethod;
-            } finally {
-                context.timers.endScope();
-            }
+        CiTargetMethod targetMethod = tasm.finishTargetMethod(method, false);
+        if (assumptions != null && !assumptions.isEmpty()) {
+            targetMethod.setAssumptions(assumptions);
         }
 
-        return null;
+        Debug.dump(targetMethod, "After code generation");
+        return targetMethod;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalContext.java	Fri Jan 27 00:40:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.graal.compiler;
-
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.observer.*;
-
-/**
- * This class is intended for non-essential stuff like statistics, observing, etc. It should not be used for anything
- * that has a direct influence on the result of a compilation!
- */
-public class GraalContext {
-
-    public static final GraalContext EMPTY_CONTEXT = new GraalContext("silent context");
-
-    public final ObservableContext observable = new ObservableContext();
-    public final GraalTimers timers = new GraalTimers();
-    public final GraalMetrics metrics = new GraalMetrics();
-
-    private final String name;
-
-    public GraalContext(String name) {
-        this.name = name;
-    }
-
-    public boolean isObserved() {
-        return observable.isObserved();
-    }
-
-    public void addCompilationObserver(CompilationObserver observer) {
-        observable.addCompilationObserver(observer);
-    }
-
-    public void print() {
-        if (GraalOptions.Meter || GraalOptions.Time) {
-            for (int i = 0; i < 22 + name.length(); i++) {
-                TTY.print('=');
-            }
-            TTY.println("\n========== " + name + " ==========");
-            if (GraalOptions.Meter) {
-                metrics.print();
-            }
-            if (GraalOptions.Time) {
-                timers.print();
-            }
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java	Fri Jan 27 00:40:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.graal.compiler;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.Map.Entry;
-
-import com.oracle.max.criutils.*;
-
-
-/**
- * This class contains a number of fields that collect metrics about compilation, particularly
- * the number of times certain optimizations are performed.
- */
-public final class GraalMetrics {
-    // Checkstyle: stop
-    public int CompiledMethods;
-    public int TargetMethods;
-    public int LocalValueNumberHits;
-    public int ValueMapResizes;
-    public int InlinedFinalizerChecks;
-    public int InlineForcedMethods;
-    public int InlineForbiddenMethods;
-    public int InlineConsidered;
-    public int InlinePerformed;
-    public int InlineUncompiledConsidered;
-    public int InlineUncompiledPerformed;
-    public int BlocksDeleted;
-    public int BytecodesCompiled;
-    public int CodeBytesEmitted;
-    public int SafepointsEmitted;
-    public int ExceptionHandlersEmitted;
-    public int DataPatches;
-    public int DirectCallSitesEmitted;
-    public int IndirectCallSitesEmitted;
-    public int LiveHIRInstructions;
-    public int LIRInstructions;
-    public int LIRVariables;
-    public int LIRXIRInstructions;
-    public int LIRMoveInstructions;
-    public int LSRAIntervalsCreated;
-    public int LSRASpills;
-    public int LoadConstantIterations;
-    public int CodeBufferCopies;
-    public int UniqueValueIdsAssigned;
-    public int FrameStatesCreated;
-    public int FrameStateValuesCreated;
-    public int LoopsPeeled;
-    public int LoopsInverted;
-    public int PartialUsageProbability;
-    public int FullUsageProbability;
-    public int Rematerializations;
-    public int GlobalValueNumberingHits;
-    public int ExplicitExceptions;
-    public int GuardsHoisted;
-
-
-
-    /**
-     * The total number of bytes of bytecode parsed during this compilation, including any inlined methods.
-     */
-    public int bytecodeCount;
-
-    /**
-     * The number of internal graph nodes created during this compilation.
-     */
-    public int nodeCount;
-
-    /**
-     * The number of basic blocks created during this compilation.
-     */
-    public int blockCount;
-
-    /**
-     * The number of loops in the compiled method.
-     */
-    public int loopCount;
-
-    /**
-     * The number of methods inlined.
-     */
-    public int inlineCount;
-
-    /**
-     * The number of methods folded (i.e. evaluated).
-     */
-    public int foldCount;
-
-    /**
-     * The number of intrinsics inlined in this compilation.
-     */
-    public int intrinsicCount;
-
-
-    // Checkstyle: resume
-
-    public void print() {
-        for (Entry<String, MetricsEntry> m : map.entrySet()) {
-            printField(m.getKey(), m.getValue().value);
-        }
-        printFields(GraalMetrics.class);
-    }
-
-    public static class MetricsEntry {
-        public int value;
-
-        public void increment() {
-            increment(1);
-        }
-
-        public void increment(int val) {
-            value += val;
-        }
-    }
-
-    private LinkedHashMap<String, MetricsEntry> map = new LinkedHashMap<>();
-
-    public MetricsEntry get(String name) {
-        if (!map.containsKey(name)) {
-            map.put(name, new MetricsEntry());
-        }
-        return map.get(name);
-    }
-
-    public void printFields(Class<?> javaClass) {
-        final String className = javaClass.getSimpleName();
-        TTY.println(className + " {");
-        for (final Field field : javaClass.getFields()) {
-            printField(field, false);
-        }
-        TTY.println("}");
-    }
-
-    public void printField(final Field field, boolean tabbed) {
-        final String fieldName = String.format("%35s", field.getName());
-        try {
-            String prefix = tabbed ? "" : "    " + fieldName + " = ";
-            String postfix = tabbed ? "\t" : "\n";
-            if (field.getType() == int.class) {
-                TTY.print(prefix + field.getInt(this) + postfix);
-            } else if (field.getType() == boolean.class) {
-                TTY.print(prefix + field.getBoolean(this) + postfix);
-            } else if (field.getType() == float.class) {
-                TTY.print(prefix + field.getFloat(this) + postfix);
-            } else if (field.getType() == String.class) {
-                TTY.print(prefix + field.get(this) + postfix);
-            } else if (field.getType() == Map.class) {
-                Map<?, ?> m = (Map<?, ?>) field.get(this);
-                TTY.print(prefix + printMap(m) + postfix);
-            } else {
-                TTY.print(prefix + field.get(this) + postfix);
-            }
-        } catch (IllegalAccessException e) {
-            // do nothing.
-        }
-    }
-
-    private static String printMap(Map<?, ?> m) {
-        StringBuilder sb = new StringBuilder();
-
-        List<String> keys = new ArrayList<>();
-        for (Object key : m.keySet()) {
-            keys.add((String) key);
-        }
-        Collections.sort(keys);
-
-        for (String key : keys) {
-            sb.append(key);
-            sb.append("\t");
-            sb.append(m.get(key));
-            sb.append("\n");
-        }
-
-        return sb.toString();
-    }
-
-    private static void printField(String fieldName, long value) {
-        TTY.print("    " + fieldName + " = " + value + "\n");
-    }
-}
-
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Fri Jan 27 16:39:32 2012 +0100
@@ -82,21 +82,24 @@
     public static boolean PrintLIR                           = ____;
     public static boolean PrintCFGToFile                     = ____;
 
+    // Debug settings:
+    public static boolean Debug                              = true;
+    public static String Dump                                = null;
+    public static String Meter                               = null;
+    public static String Time                                = null;
+    public static String Log                                 = null;
+    public static String MethodFilter                        = null;
+
     // Ideal graph visualizer output settings
-    public static boolean Plot                               = ____;
-    public static boolean PlotVerbose                        = ____;
     public static boolean PlotOnError                        = ____;
     public static int     PlotLevel                          = 3;
     public static boolean PlotSnippets                       = ____;
-    public static boolean PrintIdealGraphBytecodes           = true;
     public static int     PrintIdealGraphLevel               = 0;
     public static boolean PrintIdealGraphFile                = ____;
     public static String  PrintIdealGraphAddress             = "127.0.0.1";
     public static int     PrintIdealGraphPort                = 4444;
 
     // Other printing settings
-    public static boolean Meter                              = ____;
-    public static boolean Time                               = ____;
     public static boolean PrintQueue                         = ____;
     public static boolean PrintCompilation                   = ____;
     public static boolean PrintXirTemplates                  = ____;
@@ -114,7 +117,6 @@
     public static boolean TraceDeadCodeElimination           = ____;
     public static boolean TraceEscapeAnalysis                = ____;
     public static boolean TraceCanonicalizer                 = ____;
-    public static boolean TraceMemoryMaps                    = ____;
     public static boolean TraceProbability                   = ____;
     public static boolean TraceReadElimination               = ____;
     public static boolean TraceGVN                           = ____;
@@ -126,8 +128,6 @@
     public static boolean AssumeVerifiedBytecode             = true;
 
     // Code generator settings
-    public static boolean GenLIR                             = true;
-    public static boolean GenCode                            = true;
     public static boolean UseBranchPrediction                = true;
     public static boolean UseExceptionProbability            = ____;
     public static boolean AllowExplicitExceptionChecks       = true;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalTimers.java	Fri Jan 27 00:40:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.graal.compiler;
-
-import java.util.*;
-
-import com.oracle.max.criutils.*;
-
-/**
- * This class contains timers that record the amount of time spent in various parts of the compiler. It builds a
- * hierarchical and a flat representation of the timing. In order to reliably create the hierarchy the following code
- * pattern should be used:
- *
- * <pre>
- * GraalTimers.startScope("name");
- * try {
- *      ...
- * } finally {
- *      GraalTimers.endScope();
- * }
- * </pre>
- */
-public final class GraalTimers {
-
-    private static class TimingScope {
-
-        public final TimingScope parent;
-        public final int level;
-        public long time;
-        public long count;
-        public long subTime;
-        public long startTime;
-
-        public final ArrayList<String> subNames = new ArrayList<>();
-        public final ArrayList<TimingScope> subScopes = new ArrayList<>();
-
-        public TimingScope(TimingScope parent) {
-            this.parent = parent;
-            this.level = parent == null ? 0 : parent.level + 1;
-        }
-
-        private static final String PREFIX = "       |       |       |       |       |       |       |       |       |       +";
-
-        public static void treeIndent(int i) {
-            assert i < PREFIX.length() / 8;
-            TTY.print(PREFIX.substring(PREFIX.length() - i * 8));
-        }
-
-        private void printScope(int indent) {
-            TTY.println("%3.0f%% %6.2fs %5d", time * 100.0 / parent.time, time / 1000000000.0, count);
-            if (!subNames.isEmpty() && (time - subTime) > 0) {
-                treeIndent(indent + 1);
-                TTY.print("%-40s", "self:");
-                TTY.println("%3.0f%% %6.2fs %5d", (time - subTime) * 100.0 / time, (time - subTime) / 1000000000.0, count);
-            }
-            printSub(indent + 1);
-        }
-
-        public void printSub(int indent) {
-            for (int i = 0; i < subNames.size(); i++) {
-                String name = subNames.get(i);
-                TimingScope scope = subScopes.get(i);
-                treeIndent(indent);
-                TTY.print("%-40s", name + ":");
-                scope.printScope(indent);
-            }
-        }
-
-        public long accumulateSub(Map<String, Long> times, Map<String, Long> counts) {
-            long result = 0;
-            for (int i = 0; i < subNames.size(); i++) {
-                String name = subNames.get(i);
-                TimingScope scope = subScopes.get(i);
-                long totalTime = times.containsKey(name) ? times.get(name) : 0;
-                long totalCount = counts.containsKey(name) ? counts.get(name) : 0;
-                long myTime = scope.time - scope.subTime;
-                times.put(name, totalTime + myTime);
-                counts.put(name, totalCount + scope.count);
-                result += myTime + scope.accumulateSub(times, counts);
-            }
-            return result;
-        }
-    }
-
-    private final TimingScope rootScope = new TimingScope(null);
-
-    private ThreadLocal<TimingScope> currentScope = new ThreadLocal<TimingScope>() {
-
-        @Override
-        protected TimingScope initialValue() {
-            TimingScope scope = new TimingScope(rootScope);
-            rootScope.subNames.add(Thread.currentThread().getName());
-            rootScope.subScopes.add(scope);
-            return scope;
-        }
-    };
-
-    private ThreadLocal<Integer> currentLevel = new ThreadLocal<Integer>() {
-        @Override
-        protected Integer initialValue() {
-            return 0;
-        }
-    };
-
-    public void startScope(Class< ? > clazz) {
-        if (GraalOptions.Time) {
-            startScope(clazz.getSimpleName());
-        } else {
-            currentLevel.set(currentLevel.get() + 1);
-        }
-    }
-
-    public int currentLevel() {
-        if (GraalOptions.Time) {
-            return currentScope.get().level;
-        } else {
-            return currentLevel.get();
-        }
-    }
-
-    public void startScope(String name) {
-        if (GraalOptions.Time) {
-            TimingScope current = currentScope.get();
-            int index = current.subNames.indexOf(name);
-            TimingScope sub;
-            if (index == -1) {
-                sub = new TimingScope(current);
-                current.subNames.add(name);
-                current.subScopes.add(sub);
-            } else {
-                sub = current.subScopes.get(index);
-            }
-            currentScope.set(sub);
-            sub.startTime = System.nanoTime();
-            sub.count++;
-        } else {
-            currentLevel.set(currentLevel.get() + 1);
-        }
-    }
-
-    public void endScope() {
-        if (GraalOptions.Time) {
-            TimingScope current = currentScope.get();
-            long time = System.nanoTime() - current.startTime;
-            current.time += time;
-            current.parent.subTime += time;
-            currentScope.set(current.parent);
-        } else {
-            currentLevel.set(currentLevel.get() - 1);
-        }
-    }
-
-    public void print() {
-        if (GraalOptions.Time) {
-            rootScope.time = 0;
-            for (TimingScope scope : rootScope.subScopes) {
-                scope.time = scope.subTime;
-                rootScope.time += scope.subTime;
-            }
-
-            TTY.println("===============================");
-            TTY.println("Total Compilation Time: %6.2fs", rootScope.time / 1000000000.0);
-            TTY.println();
-
-            rootScope.printSub(0);
-
-            TreeMap<String, Long> times = new TreeMap<>();
-            TreeMap<String, Long> counts = new TreeMap<>();
-            long total = rootScope.accumulateSub(times, counts);
-
-            TTY.println();
-            for (String name : times.keySet()) {
-                if (times.get(name) > 0) {
-                    TTY.println("%-30s: %7.4f s (%5.2f%%) %5d", name, times.get(name) / 1000000000.0, times.get(name) * 100.0 / total, counts.get(name));
-                }
-            }
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java	Fri Jan 27 16:39:32 2012 +0100
@@ -24,10 +24,10 @@
 
 import java.util.*;
 
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
 
 /**
  * This class performs basic optimizations on the control flow graph after LIR generation.
@@ -38,8 +38,8 @@
      * Performs control flow optimizations on the given LIR graph.
      * @param ir the LIR graph that should be optimized
      */
-    public static void optimize(LIR ir, GraalContext context) {
-        ControlFlowOptimizer optimizer = new ControlFlowOptimizer(ir, context);
+    public static void optimize(LIR ir) {
+        ControlFlowOptimizer optimizer = new ControlFlowOptimizer(ir);
         List<LIRBlock> code = ir.codeEmittingOrder();
         //optimizer.reorderShortLoops(code);
         optimizer.deleteEmptyBlocks(code);
@@ -48,11 +48,9 @@
     }
 
     private final LIR ir;
-    private final GraalContext context;
 
-    private ControlFlowOptimizer(LIR ir, GraalContext context) {
+    private ControlFlowOptimizer(LIR ir) {
         this.ir = ir;
-        this.context = context;
     }
 /*
     private void reorderShortLoop(List<LIRBlock> code, LIRBlock headerBlock, int headerIdx) {
@@ -123,7 +121,7 @@
             if (canDeleteBlock(block)) {
                 // adjust successor and predecessor lists
                 block.replaceWith(block.suxAt(0));
-                context.metrics.BlocksDeleted++;
+                Debug.metric("BlocksDeleted").increment();
             } else {
                 // adjust position of this block in the block list if blocks before
                 // have been deleted
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java	Fri Jan 27 16:39:32 2012 +0100
@@ -657,12 +657,9 @@
     /**
      * Sentinel interval to denote the end of an interval list.
      */
-    static final Interval EndMarker = new Interval(null, CiValue.IllegalValue, -1);
+    static final Interval EndMarker = new Interval(CiValue.IllegalValue, -1);
 
-    Interval(GraalContext context, CiValue operand, int operandNumber) {
-        if (GraalOptions.Meter && context != null) {
-            context.metrics.LSRAIntervalsCreated++;
-        }
+    Interval(CiValue operand, int operandNumber) {
         assert operand != null;
         this.operand = operand;
         this.operandNumber = operandNumber;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Fri Jan 27 16:39:32 2012 +0100
@@ -41,6 +41,7 @@
 import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode;
 import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.compiler.lir.StandardOp.*;
@@ -52,7 +53,6 @@
  */
 public final class LinearScan {
 
-    final GraalContext context;
     final CiTarget target;
     final RiMethod method;
     final LIR ir;
@@ -120,14 +120,10 @@
      */
     private final int firstVariableNumber;
 
-    private final StructuredGraph graph;
 
-
-    public LinearScan(GraalContext context, CiTarget target, RiResolvedMethod method, StructuredGraph graph, LIR ir, LIRGenerator gen, FrameMap frameMap) {
-        this.context = context;
+    public LinearScan(CiTarget target, RiResolvedMethod method, LIR ir, LIRGenerator gen, FrameMap frameMap) {
         this.target = target;
         this.method = method;
-        this.graph = graph;
         this.ir = ir;
         this.gen = gen;
         this.frameMap = frameMap;
@@ -238,7 +234,7 @@
         assert isProcessed(operand);
         assert isLegal(operand);
         int operandNumber = operandNumber(operand);
-        Interval interval = new Interval(context, operand, operandNumber);
+        Interval interval = new Interval(operand, operandNumber);
         assert operandNumber < intervalsSize;
         assert intervals[operandNumber] == null;
         intervals[operandNumber] = interval;
@@ -289,7 +285,7 @@
     }
 
     int numLoops() {
-        return ir.loopCount();
+        return ir.numLoops();
     }
 
     boolean isIntervalInLoop(int interval, int loop) {
@@ -1617,7 +1613,7 @@
         // intervals that have no oops inside need not to be processed.
         // to ensure a walking until the last instruction id, add a dummy interval
         // with a high operation id
-        nonOopIntervals = new Interval(context, CiValue.IllegalValue, -1);
+        nonOopIntervals = new Interval(CiValue.IllegalValue, -1);
         nonOopIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
 
         return new IntervalWalker(this, oopIntervals, nonOopIntervals);
@@ -1785,70 +1781,65 @@
     }
 
     public void allocate() {
-        context.timers.startScope("Lifetime Analysis");
-        try {
-            numberInstructions();
 
-            printLir("Before register allocation", true);
+        Debug.scope("LifetimeAnalysis", new Runnable() {
 
-            computeLocalLiveSets();
-            computeGlobalLiveSets();
-
-            buildIntervals();
-            sortIntervalsBeforeAllocation();
-        } finally {
-            context.timers.endScope();
-        }
+            public void run() {
+                numberInstructions();
+                printLir("Before register allocation", true);
+                computeLocalLiveSets();
+                computeGlobalLiveSets();
+                buildIntervals();
+                sortIntervalsBeforeAllocation();
+            }
+        });
 
-        context.timers.startScope("Linear Scan");
-        try {
-            printIntervals("Before register allocation");
+        Debug.scope("RegisterAllocation", new Runnable() {
 
-            allocateRegisters();
+            public void run() {
+                printIntervals("Before register allocation");
+                allocateRegisters();
+            }
+        });
 
-        } finally {
-            context.timers.endScope();
-        }
+        Debug.scope("ResolveDataFlow", new Runnable() {
+            public void run() {
+                resolveDataFlow();
+            }
+        });
 
-        context.timers.startScope("Resolution");
-        try {
-            resolveDataFlow();
-        } finally {
-            context.timers.endScope();
-        }
+        Debug.scope("DebugInfo", new Runnable() {
 
-        context.timers.startScope("Create Debug Info");
-        try {
-            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 (GraalOptions.DetailedAsserts) {
-                verify();
-            }
+                if (GraalOptions.DetailedAsserts) {
+                    verify();
+                }
 
-            eliminateSpillMoves();
-            assignLocations();
+                eliminateSpillMoves();
+                assignLocations();
 
-            if (GraalOptions.DetailedAsserts) {
-                verifyIntervals();
+                if (GraalOptions.DetailedAsserts) {
+                    verifyIntervals();
+                }
             }
-        } finally {
-            context.timers.endScope();
-        }
+        });
+
+        Debug.scope("ControlFlowOptimizations", new Runnable() {
 
-        context.timers.startScope("Control Flow Optimizations");
-        try {
-            printLir("After register number assignment", true);
-            EdgeMoveOptimizer.optimize(ir.linearScanOrder());
-            ControlFlowOptimizer.optimize(ir, context);
-            printLir("After control flow optimization", false);
-        } finally {
-            context.timers.endScope();
-        }
+            public void run() {
+                printLir("After register number assignment", true);
+                EdgeMoveOptimizer.optimize(ir.linearScanOrder());
+                ControlFlowOptimizer.optimize(ir);
+                printLir("After control flow optimization", false);
+            }
+        });
     }
 
     void printIntervals(String label) {
@@ -1873,9 +1864,7 @@
             TTY.println();
         }
 
-        if (context.isObserved()) {
-            context.observable.fireCompilationEvent(label, graph, this, Arrays.copyOf(intervals, intervalsSize));
-        }
+        Debug.dump(Arrays.copyOf(intervals, intervalsSize), label);
     }
 
     void printLir(String label, boolean hirValid) {
@@ -1886,9 +1875,7 @@
             TTY.println();
         }
 
-        if (context.isObserved()) {
-            context.observable.fireCompilationEvent(label, hirValid ? graph : null, ir);
-        }
+        Debug.dump(ir, label);
     }
 
     boolean verify() {
@@ -2025,7 +2012,7 @@
         fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first;
         // to ensure a walking until the last instruction id, add a dummy interval
         // with a high operation id
-        otherIntervals = new Interval(context, CiValue.IllegalValue, -1);
+        otherIntervals = new Interval(CiValue.IllegalValue, -1);
         otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1);
         IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals);
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java	Fri Jan 27 16:39:32 2012 +0100
@@ -34,6 +34,7 @@
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.lir.LIR.SlowPath;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
 
 public class TargetMethodAssembler {
 
@@ -46,10 +47,7 @@
 
     private List<ExceptionInfo> exceptionInfoList;
     private int lastSafepointPos;
-    private final GraalContext context;
-
-    public TargetMethodAssembler(GraalContext context, CiTarget target, RiRuntime runtime, FrameMap frameMap, List<SlowPath> slowPaths, AbstractAssembler asm) {
-        this.context = context;
+    public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, List<SlowPath> slowPaths, AbstractAssembler asm) {
         this.target = target;
         this.runtime = runtime;
         this.frameMap = frameMap;
@@ -84,13 +82,11 @@
             }
         }
 
-        if (GraalOptions.Meter) {
-            context.metrics.TargetMethods++;
-            context.metrics.CodeBytesEmitted += targetMethod.targetCodeSize();
-            context.metrics.SafepointsEmitted += targetMethod.safepoints.size();
-            context.metrics.DataPatches += targetMethod.dataReferences.size();
-            context.metrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size();
-        }
+        Debug.metric("TargetMethods").increment();
+        Debug.metric("CodeBytesEmitted").add(targetMethod.targetCodeSize());
+        Debug.metric("SafepointsEmitted").add(targetMethod.safepoints.size());
+        Debug.metric("DataPatches").add(targetMethod.dataReferences.size());
+        Debug.metric("ExceptionHandlersEmitted").add(targetMethod.exceptionHandlers.size());
 
         if (GraalOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) {
             Util.printSection("Target Method", Util.SECTION_CHARACTER);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Fri Jan 27 16:39:32 2012 +0100
@@ -50,6 +50,7 @@
 import com.oracle.max.graal.compiler.lir.StandardOp.ParametersOp;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
@@ -64,8 +65,6 @@
  * This class traverses the HIR instructions and generates LIR instructions from them.
  */
 public abstract class LIRGenerator extends LIRGeneratorTool {
-    public final GraalContext context;
-
     protected final Graph graph;
     protected final RiRuntime runtime;
     protected final CiTarget target;
@@ -139,8 +138,7 @@
     private LockScope curLocks;
 
 
-    public LIRGenerator(GraalContext context, Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
-        this.context = context;
+    public LIRGenerator(Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
         this.graph = graph;
         this.runtime = runtime;
         this.target = target;
@@ -1304,9 +1302,7 @@
                     inputOperandArray, tempOperandArray, inputOperandIndicesArray, tempOperandIndicesArray,
                     (allocatedResultOperand == IllegalValue) ? -1 : resultOperand.index,
                     info, infoAfter, trueSuccessor, falseSuccessor);
-            if (GraalOptions.Meter) {
-                context.metrics.LIRXIRInstructions++;
-            }
+            Debug.metric("LIRXIRInstructions").increment();
         }
 
         return operandsArray[resultOperand.index];
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java	Fri Jan 27 16:39:32 2012 +0100
@@ -65,8 +65,7 @@
     public SlowPath methodEndMarker;
 
     private int numVariables;
-
-    private final int loopCount;
+    private final int numLoops;
 
     public SpillMoveFactory spillMoveFactory;
 
@@ -81,15 +80,15 @@
 
     /**
      * Creates a new LIR instance for the specified compilation.
-     * @param loopCount number of loops
+     * @param numLoops number of loops
      * @param compilation the compilation
      */
-    public LIR(LIRBlock startBlock, List<LIRBlock> linearScanOrder, List<LIRBlock> codeEmittingOrder, NodeMap<LIRBlock> valueToBlock, int loopCount) {
+    public LIR(LIRBlock startBlock, List<LIRBlock> linearScanOrder, List<LIRBlock> codeEmittingOrder, NodeMap<LIRBlock> valueToBlock, int numLoops) {
         this.codeEmittingOrder = codeEmittingOrder;
         this.linearScanOrder = linearScanOrder;
         this.startBlock = startBlock;
         this.valueToBlock = valueToBlock;
-        this.loopCount = loopCount;
+        this.numLoops = numLoops;
 
         slowPaths = new ArrayList<>();
         deoptimizationStubs = new ArrayList<>();
@@ -115,10 +114,6 @@
         return valueToBlock;
     }
 
-    public int loopCount() {
-        return loopCount;
-    }
-
     public int numVariables() {
         return numVariables;
     }
@@ -263,4 +258,8 @@
             TTY.println();
         }
     }
+
+    public int numLoops() {
+        return numLoops;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -27,6 +27,7 @@
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.graph.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 
@@ -50,13 +51,9 @@
     @Override
     protected void run(StructuredGraph graph) {
         new PropagateProbability(graph.start()).apply();
-        if (currentContext.isObserved() && GraalOptions.TraceProbability) {
-            currentContext.observable.fireCompilationEvent("After PropagateProbability", graph);
-        }
+        Debug.dump(graph, "After PropagateProbability");
         computeLoopFactors();
-        if (currentContext.isObserved() && GraalOptions.TraceProbability) {
-            currentContext.observable.fireCompilationEvent("After computeLoopFactors", graph);
-        }
+        Debug.dump(graph, "After computeLoopFactors");
         new PropagateLoopFrequency(graph.start()).apply();
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -29,6 +29,7 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.graph.*;
 import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.PhiNode.PhiType;
@@ -428,21 +429,10 @@
             }
             if (invokes.size() == 0) {
 
-                if (currentContext.isObserved()) {
-                    currentContext.observable.fireCompilationEvent("Before escape " + node, graph);
-                }
-                if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
-                    TTY.println("%n!!!!!!!! non-escaping object: %s (%s)", node, node.exactType());
-                }
-                try {
-                    currentContext.timers.startScope("Escape Analysis Fixup");
-                    removeAllocation(node, op);
-                } finally {
-                    currentContext.timers.endScope();
-                }
-                if (currentContext.isObserved()) {
-                    currentContext.observable.fireCompilationEvent("After escape", graph);
-                }
+                Debug.dump(graph, "Before escape %s", node);
+                Debug.log("!!!!!!!! non-escaping object: %s (%s)", node, node.exactType());
+                removeAllocation(node, op);
+                Debug.dump(graph, "After escape", graph);
                 break;
             }
             if (weight < minimumWeight) {
@@ -457,8 +447,8 @@
             if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
                 TTY.println("Trying inlining to get a non-escaping object for %s", node);
             }
-            new InliningPhase(target, runtime, invokes, assumptions, plan).apply(graph, currentContext);
-            new DeadCodeEliminationPhase().apply(graph, currentContext);
+            new InliningPhase(target, runtime, invokes, assumptions, plan).apply(graph);
+            new DeadCodeEliminationPhase().apply(graph);
             if (node.isDeleted()) {
                 if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) {
                     TTY.println("%n!!!!!!!! object died while performing escape analysis: %s (%s)", node, node.exactType());
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -25,10 +25,9 @@
 import java.util.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.loop.*;
 import com.oracle.max.graal.compiler.schedule.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.PhiNode.*;
@@ -74,9 +73,7 @@
         }
 
         public void mergeWith(MemoryMap otherMemoryMap, Block b) {
-            if (GraalOptions.TraceMemoryMaps) {
-                TTY.println("merging block " + otherMemoryMap.block + " into block " + block);
-            }
+            Debug.log("Merging block %s into block %s.", otherMemoryMap.block, block);
             IdentityHashMap<Object, Node> otherMap = otherMemoryMap.map;
 
             for (Map.Entry<Object, Node> entry : map.entrySet()) {
@@ -109,19 +106,14 @@
 
         private void mergeNodes(Object location, Node original, Node newValue, Block mergeBlock) {
             if (original == newValue) {
-                // Nothing to merge.
-                if (GraalOptions.TraceMemoryMaps) {
-                    TTY.println("Nothing to merge both nodes are " + original);
-                }
+                Debug.log("Nothing to merge both nodes are %s.", original);
                 return;
             }
             MergeNode m = (MergeNode) mergeBlock.firstNode();
             if (m.isPhiAtMerge(original)) {
                 PhiNode phi = (PhiNode) original;
                 phi.addInput((ValueNode) newValue);
-                if (GraalOptions.TraceMemoryMaps) {
-                    TTY.println("Add new input to " + original + ": " + newValue);
-                }
+                Debug.log("Add new input to %s: %s.", original, newValue);
                 assert phi.valueCount() <= phi.merge().endCount() : phi.merge();
             } else {
                 PhiNode phi = m.graph().unique(new PhiNode(CiKind.Illegal, m, PhiType.Memory));
@@ -129,9 +121,7 @@
                     phi.addInput((ValueNode) original);
                 }
                 phi.addInput((ValueNode) newValue);
-                if (GraalOptions.TraceMemoryMaps) {
-                    TTY.println("Creating new " + phi + " merge=" + phi.merge() + ", mergeOperationCount=" + mergeOperationCount + ", newValue=" + newValue + ", location=" + location);
-                }
+                Debug.log("Creating new %s merge=%s newValue=%s location=%s.", phi, phi.merge(), newValue, location);
                 assert phi.valueCount() <= phi.merge().endCount() + ((phi.merge() instanceof LoopBeginNode) ? 1 : 0) : phi.merge() + "/" + phi.valueCount() + "/" + phi.merge().endCount() + "/" + mergeOperationCount;
                 assert m.usages().contains(phi);
                 assert phi.merge().usages().contains(phi);
@@ -155,10 +145,7 @@
             StructuredGraph graph = (StructuredGraph) readNode.graph();
             assert readNode.getNullCheck() == false;
 
-            if (GraalOptions.TraceMemoryMaps) {
-                TTY.println("Register read to node " + readNode);
-            }
-
+            Debug.log("Register read to node %s.", readNode);
             FloatingReadNode floatingRead;
             if (readNode.location().locationIdentity() == LocationNode.FINAL_LOCATION) {
                 floatingRead = graph.unique(new FloatingReadNode(readNode.kind(), readNode.object(), readNode.guard(), readNode.location()));
@@ -245,13 +232,11 @@
             propagateFromChildren(loop, modifiedValues);
         }
 
-        if (GraalOptions.TraceMemoryMaps) {
-            print(loopInfo, modifiedValues);
-        }
+        Debug.log("Modified values: %s.", modifiedValues);
 
         // Identify blocks.
         final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false);
-        s.apply(graph, currentContext);
+        s.apply(graph);
         List<Block> blocks = s.getBlocks();
 
         // Process blocks (predecessors first).
@@ -343,15 +328,6 @@
         modifiedValues.get(loop).add(locationIdentity);
     }
 
-    private static void print(LoopInfo loopInfo, HashMap<Loop, Set<Object>> modifiedValues) {
-        TTY.println();
-        TTY.println("Loops:");
-        for (Loop loop : loopInfo.loops()) {
-            TTY.print(loop + " modified values: " + modifiedValues.get(loop));
-            TTY.println();
-        }
-    }
-
     private void mark(LoopBeginNode begin, LoopBeginNode outer, NodeMap<LoopBeginNode> nodeToLoop) {
 
         if (nodeToLoop.get(begin) != null) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GlobalValueNumberingPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -24,11 +24,14 @@
 
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 
 public class GlobalValueNumberingPhase extends Phase {
 
+    public static final DebugMetric metricGlobalValueNumberingHits = Debug.metric("GlobalValueNumberingHits");
+
     @Override
     protected void run(StructuredGraph graph) {
         NodeBitMap visited = graph.createNodeBitMap();
@@ -47,9 +50,7 @@
                 Node newNode = compilerGraph.findDuplicate(n);
                 if (newNode != null) {
                     n.replaceAndDelete(newNode);
-                    if (GraalOptions.Meter) {
-                        currentContext.metrics.GlobalValueNumberingHits++;
-                    }
+                    metricGlobalValueNumberingHits.increment();
                     if (GraalOptions.TraceGVN) {
                         TTY.println("GVN applied and new node is " + newNode);
                     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -33,6 +33,7 @@
 import com.oracle.max.graal.compiler.util.InliningUtil.InlineInfo;
 import com.oracle.max.graal.compiler.util.InliningUtil.InliningCallback;
 import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 
@@ -54,6 +55,10 @@
 
     private final PhasePlan plan;
 
+    // Metrics
+    private static final DebugMetric metricInliningPerformed = Debug.metric("InliningPerformed");
+    private static final DebugMetric metricInliningConsidered = Debug.metric("InliningConsidered");
+
     public InliningPhase(CiTarget target, GraalRuntime runtime, Collection<Invoke> hints, CiAssumptions assumptions, PhasePlan plan) {
         this.target = target;
         this.runtime = runtime;
@@ -94,20 +99,16 @@
                     if (GraalOptions.TraceInlining) {
                         TTY.println("inlining %f: %s", info.weight, info);
                     }
-                    if (GraalOptions.TraceInlining) {
-                        currentContext.observable.fireCompilationEvent("after inlining " + info, graph);
-                    }
+                    Debug.dump(graph, "after inlining %s", info);
                     // get the new nodes here, the canonicalizer phase will reset the mark
                     newNodes = graph.getNewNodes();
                     if (GraalOptions.OptCanonicalizer) {
                         new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph);
                     }
                     if (GraalOptions.Intrinsify) {
-                        new IntrinsificationPhase(runtime).apply(graph, currentContext);
+                        new IntrinsificationPhase(runtime).apply(graph);
                     }
-                    if (GraalOptions.Meter) {
-                        currentContext.metrics.InlinePerformed++;
-                    }
+                    metricInliningPerformed.increment();
                 } catch (CiBailout bailout) {
                     // TODO determine if we should really bail out of the whole compilation.
                     throw bailout;
@@ -146,10 +147,7 @@
     private void scanInvoke(Invoke invoke, int level) {
         InlineInfo info = InliningUtil.getInlineInfo(invoke, level, runtime, assumptions, this);
         if (info != null) {
-            if (GraalOptions.Meter) {
-                currentContext.metrics.InlineConsidered++;
-            }
-
+            metricInliningConsidered.increment();
             inlineCandidates.add(info);
         }
     }
@@ -161,14 +159,14 @@
         StructuredGraph newGraph = new StructuredGraph(method);
 
         if (plan != null) {
-            plan.runPhases(PhasePosition.AFTER_PARSING, newGraph, currentContext);
+            plan.runPhases(PhasePosition.AFTER_PARSING, newGraph);
         }
 
         if (GraalOptions.ProbabilityAnalysis) {
-            new DeadCodeEliminationPhase().apply(newGraph, currentContext, false);
-            new ComputeProbabilityPhase().apply(newGraph, currentContext, false);
+            new DeadCodeEliminationPhase().apply(newGraph);
+            new ComputeProbabilityPhase().apply(newGraph);
         }
-        new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph, currentContext, false);
+        new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph);
         return newGraph;
     }
 
@@ -213,9 +211,9 @@
             if (!parsedMethods.containsKey(method)) {
                 StructuredGraph newGraph = new StructuredGraph(method);
                 if (plan != null) {
-                    plan.runPhases(PhasePosition.AFTER_PARSING, newGraph, currentContext);
+                    plan.runPhases(PhasePosition.AFTER_PARSING, newGraph);
                 }
-                new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph, currentContext, false);
+                new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph);
                 count = graphComplexity(newGraph);
                 parsedMethods.put(method, count);
             } else {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -40,7 +40,7 @@
     @Override
     protected void run(final StructuredGraph graph) {
         final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false);
-        s.apply(graph, currentContext);
+        s.apply(graph);
         s.calculateAlwaysReachedBlock();
 
         NodeBitMap processed = graph.createNodeBitMap();
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -22,100 +22,35 @@
  */
 package com.oracle.max.graal.compiler.phases;
 
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.nodes.*;
 
 public abstract class Phase {
 
-    private final String name;
-    private final boolean shouldVerify;
-    protected GraalContext currentContext;
+    private String name;
 
     protected Phase() {
         this.name = this.getClass().getSimpleName();
-        this.shouldVerify = GraalOptions.VerifyPhases;
+        if (name.endsWith("Phase")) {
+            name = name.substring(0, name.length() - "Phase".length());
+        }
     }
 
     protected Phase(String name) {
-        this(name, GraalOptions.VerifyPhases);
-    }
-
-    protected Phase(String name, boolean shouldVerify) {
         this.name = name;
-        this.shouldVerify = shouldVerify;
     }
 
     protected String getDetailedName() {
         return getName();
     }
 
-    public final void apply(StructuredGraph graph) {
-        apply(graph, GraalContext.EMPTY_CONTEXT);
-    }
-
-    public final void apply(StructuredGraph graph, GraalContext context) {
-        apply(graph, context, true);
-    }
-
-    public final void apply(StructuredGraph graph, boolean plot) {
-        apply(graph,  GraalContext.EMPTY_CONTEXT, plot);
-    }
-
-    public final void apply(StructuredGraph graph, GraalContext context, boolean plot) {
-
-        this.currentContext = context;
-        try {
-            assert graph != null && (!shouldVerify || graph.verify());
-        } catch (GraalInternalError e) {
-            throw e.addContext("start of phase", getDetailedName());
-        }
-
-        int startDeletedNodeCount = graph.getDeletedNodeCount();
-        int startNodeCount = graph.getNodeCount();
-        if (context != null) {
-            context.timers.startScope(getName());
-        }
-        try {
-            try {
-                run(graph);
-            } catch (CiBailout bailout) {
-                throw bailout;
-            } catch (AssertionError e) {
-                throw new GraalInternalError(e);
-            } catch (RuntimeException e) {
-                throw new GraalInternalError(e);
-            } finally {
-                if (context != null) {
-                    context.timers.endScope();
-                }
+    public final void apply(final StructuredGraph graph) {
+        Debug.scope(name, this, new Runnable() {
+            public void run() {
+                Phase.this.run(graph);
+                Debug.dump(graph, "After phase %s", name);
             }
-        } catch (GraalInternalError e) {
-            throw e.addContext(graph).addContext("phase", getDetailedName());
-        }
-
-        if (context != null) {
-            if (GraalOptions.Meter) {
-                int deletedNodeCount = graph.getDeletedNodeCount() - startDeletedNodeCount;
-                int createdNodeCount = graph.getNodeCount() - startNodeCount + deletedNodeCount;
-                context.metrics.get(getName().concat(".executed")).increment();
-                context.metrics.get(getName().concat(".deletedNodes")).increment(deletedNodeCount);
-                context.metrics.get(getName().concat(".createdNodes")).increment(createdNodeCount);
-            }
-
-            boolean shouldFireCompilationEvents = context.isObserved() && this.getClass() != IdentifyBlocksPhase.class && (plot || GraalOptions.PlotVerbose);
-            if (shouldFireCompilationEvents && context.timers.currentLevel() < GraalOptions.PlotLevel) {
-                context.observable.fireCompilationEvent("After " + getName(), graph);
-            }
-        }
-
-        try {
-            assert !shouldVerify || graph.verify();
-        } catch (GraalInternalError e) {
-            throw e.addContext("end of phase", getDetailedName());
-        }
+        });
     }
 
     public final String getName() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/PhasePlan.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/PhasePlan.java	Fri Jan 27 16:39:32 2012 +0100
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.nodes.*;
 
 /**
@@ -68,10 +67,10 @@
         phases[pos.ordinal()].add(phase);
     }
 
-    public void runPhases(PhasePosition pos, StructuredGraph graph, GraalContext context) {
+    public void runPhases(PhasePosition pos, StructuredGraph graph) {
         if (phases[pos.ordinal()] != null) {
             for (Phase p : phases[pos.ordinal()]) {
-                p.apply(graph, context);
+                p.apply(graph);
             }
         }
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -57,7 +57,7 @@
     }
 
     public IdentifyBlocksPhase(boolean scheduleAllNodes, BlockFactory blockFactory) {
-        super(scheduleAllNodes ? "FullSchedule" : "PartSchedule", false);
+        super(scheduleAllNodes ? "FullSchedule" : "PartSchedule");
         this.blockFactory = blockFactory;
         this.scheduleAllNodes = scheduleAllNodes;
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java	Fri Jan 27 16:39:32 2012 +0100
@@ -28,7 +28,6 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.graph.*;
@@ -57,7 +56,7 @@
     }
 
     public abstract FrameMap newFrameMap(RiRegisterConfig registerConfig);
-    public abstract LIRGenerator newLIRGenerator(GraalContext context, Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir);
+    public abstract LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir);
     public abstract AbstractAssembler newAssembler(RiRegisterConfig registerConfig);
     public abstract CiXirAssembler newXirAssembler();
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java	Fri Jan 27 16:39:32 2012 +0100
@@ -27,7 +27,6 @@
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.target.*;
@@ -47,8 +46,8 @@
      * @return an appropriate LIR generator instance
      */
     @Override
-    public LIRGenerator newLIRGenerator(GraalContext context, Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
-        return new AMD64LIRGenerator(context, graph, runtime, target, frameMap, method, lir, xir);
+    public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+        return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Fri Jan 27 16:39:32 2012 +0100
@@ -98,8 +98,8 @@
         }
     }
 
-    public AMD64LIRGenerator(GraalContext context, Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
-        super(context, graph, runtime, target, frameMap, method, lir, xir);
+    public AMD64LIRGenerator(Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+        super(graph, runtime, target, frameMap, method, lir, xir);
         lir.methodEndMarker = new AMD64MethodEndStub();
         lir.spillMoveFactory = new AMD64SpillMoveFactory();
     }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Fri Jan 27 16:39:32 2012 +0100
@@ -24,12 +24,14 @@
 
 import java.lang.reflect.*;
 import java.util.*;
+import java.util.concurrent.*;
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
@@ -108,19 +110,13 @@
         }
 
         @Override
-        public Node inline(StructuredGraph compilerGraph, GraalRuntime runtime, InliningCallback callback) {
-            StructuredGraph graph = null; // TODO: Solve graph caching differently! GraphBuilderPhase.cachedGraphs.get(concrete);
-//            if (graph != null) {
-//                if (GraalOptions.TraceInlining) {
-//                    TTY.println("Reusing graph for %s", methodName(concrete, invoke));
-//                }
-//            } else {
-                if (GraalOptions.TraceInlining) {
-                    TTY.println("Building graph for %s, locals: %d, stack: %d", methodName(concrete, invoke), concrete.maxLocals(), concrete.maxStackSize());
+        public Node inline(StructuredGraph compilerGraph, GraalRuntime runtime, final InliningCallback callback) {
+            StructuredGraph graph = Debug.scope("Inlining", concrete, new Callable<StructuredGraph>() {
+                @Override
+                public StructuredGraph call() throws Exception {
+                    return callback.buildGraph(concrete);
                 }
-                graph = callback.buildGraph(concrete);
-//            }
-
+            });
             return InliningUtil.inline(invoke, graph, true);
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug;
+
+import com.oracle.max.graal.debug.internal.DebugScope;
+import com.oracle.max.graal.debug.internal.MetricImpl;
+import com.oracle.max.graal.debug.internal.TimerImpl;
+import java.util.*;
+import java.util.concurrent.*;
+
+
+public class Debug {
+    private static boolean ENABLED = false;
+
+    public static void enable() {
+        ENABLED = true;
+        DebugScope.initialize();
+    }
+
+    public static boolean isEnabled() {
+        return ENABLED;
+    }
+
+    public static void sandbox(String name, Runnable runnable) {
+        if (ENABLED) {
+            DebugScope.getInstance().scope(name, runnable, null, true, new Object[0]);
+        } else {
+            runnable.run();
+        }
+    }
+
+    public static void scope(String name, Runnable runnable) {
+        scope(name, null, runnable);
+    }
+
+    public static <T> T scope(String name, Callable<T> callable) {
+        return scope(name, null, callable);
+    }
+
+    public static void scope(String name, Object context, Runnable runnable) {
+        if (ENABLED) {
+            DebugScope.getInstance().scope(name, runnable, null, false, new Object[]{context});
+        } else {
+            runnable.run();
+        }
+    }
+
+    public static String currentScope() {
+        if (ENABLED) {
+            return DebugScope.getInstance().getQualifiedName();
+        } else {
+            return "";
+        }
+    }
+
+    public static <T> T scope(String name, Object context, Callable<T> callable) {
+        if (ENABLED) {
+            return DebugScope.getInstance().scope(name, null, callable, false, new Object[]{context});
+        } else {
+            return DebugScope.call(callable);
+        }
+    }
+
+    public static void log(String msg, Object... args) {
+        if (ENABLED && DebugScope.getInstance().isLogEnabled()) {
+            DebugScope.getInstance().log(msg, args);
+        }
+    }
+
+    public static void dump(Object object, String msg, Object... args) {
+        if (ENABLED && DebugScope.getInstance().isDumpEnabled()) {
+            DebugScope.getInstance().dump(object, msg, args);
+        }
+    }
+
+    public static Iterable<Object> context() {
+        if (ENABLED) {
+            return DebugScope.getInstance().getCurrentContext();
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> contextSnapshot(Class<T> clazz) {
+        if (ENABLED) {
+            List<T> result = new ArrayList<>();
+            for (Object o : context()) {
+                if (clazz.isInstance(o)) {
+                    result.add((T) o);
+                }
+            }
+            return result;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    public static DebugMetric metric(String name) {
+        if (ENABLED && DebugScope.getInstance().isMeterEnabled()) {
+            return new MetricImpl(name);
+        } else {
+            return VOID_METRIC;
+        }
+    }
+
+    public static void setConfig(DebugConfig config) {
+        if (ENABLED) {
+            DebugScope.getInstance().setConfig(config);
+        }
+    }
+
+    public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isTimerEnabled) {
+        return new DebugConfig() {
+
+            @Override
+            public boolean isLogEnabled() {
+                return isLogEnabled;
+            }
+
+            @Override
+            public boolean isMeterEnabled() {
+                return isMeterEnabled;
+            }
+
+            @Override
+            public boolean isDumpEnabled() {
+                return isDumpEnabled;
+            }
+
+            @Override
+            public boolean isTimerEnabled() {
+                return isTimerEnabled;
+            }
+
+            @Override
+            public RuntimeException interceptException(RuntimeException e) {
+                return e;
+            }
+
+            @Override
+            public Collection< ? extends DebugDumpHandler> dumpHandlers() {
+                return Collections.emptyList();
+            }
+        };
+    }
+
+    private static final DebugMetric VOID_METRIC = new DebugMetric() {
+        public void increment() { }
+        public void add(int value) { }
+    };
+
+    public static DebugTimer timer(String name) {
+        if (ENABLED && DebugScope.getInstance().isTimerEnabled()) {
+            return new TimerImpl(name);
+        } else {
+            return VOID_TIMER;
+        }
+    }
+
+    private static final DebugTimer VOID_TIMER = new DebugTimer() {
+        public void start() { }
+        public void stop() { }
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugConfig.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug;
+
+import java.util.*;
+
+
+public interface DebugConfig {
+    boolean isLogEnabled();
+    boolean isMeterEnabled();
+    boolean isDumpEnabled();
+    boolean isTimerEnabled();
+    RuntimeException interceptException(RuntimeException e);
+    Collection<? extends DebugDumpHandler> dumpHandlers();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugDumpHandler.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug;
+
+public interface DebugDumpHandler {
+    void dump(Object object, String message);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugMetric.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug;
+
+public interface DebugMetric {
+    void increment();
+    void add(int value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugTimer.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug;
+
+public interface DebugTimer {
+    void start();
+    void stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugScope.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug.internal;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.max.graal.debug.*;
+
+
+public final class DebugScope {
+
+    private static ThreadLocal<DebugScope> instanceTL = new ThreadLocal<>();
+    private static ThreadLocal<DebugConfig> configTL = new ThreadLocal<>();
+    private static ThreadLocal<RuntimeException> lastExceptionThrownTL = new ThreadLocal<>();
+
+    private final String name;
+    private final DebugScope parent;
+
+    private Object[] context;
+
+    private List<DebugScope> children;
+    private DebugValueMap valueMap;
+    private String qualifiedName;
+
+    private static final char SCOPE_SEP = '.';
+
+    private boolean logEnabled;
+    private boolean meterEnabled;
+    private boolean timerEnabled;
+    private boolean dumpEnabled;
+
+    public static DebugScope getInstance() {
+        DebugScope result = instanceTL.get();
+        if (result == null) {
+            instanceTL.set(new DebugScope("", "", null));
+            return instanceTL.get();
+        } else {
+            return result;
+        }
+    }
+
+    public static DebugConfig getConfig() {
+        return configTL.get();
+    }
+
+    private DebugScope(String name, String qualifiedName, DebugScope parent, Object... context) {
+        this.name = name;
+        this.parent = parent;
+        this.context = context;
+        this.qualifiedName = qualifiedName;
+    }
+
+    public boolean isDumpEnabled() {
+        return dumpEnabled;
+    }
+
+    public boolean isLogEnabled() {
+        return logEnabled;
+    }
+
+    public boolean isMeterEnabled() {
+        return meterEnabled;
+    }
+
+    public boolean isTimerEnabled() {
+        return timerEnabled;
+    }
+
+    public void log(String msg, Object... args) {
+        if (isLogEnabled()) {
+            cachedOut.println(String.format(msg, args));
+        }
+    }
+
+    public void dump(Object object, String formatString, Object[] args) {
+        if (isDumpEnabled()) {
+            DebugConfig config = getConfig();
+            if (config != null) {
+                String message = String.format(formatString, args);
+                for (DebugDumpHandler dumpHandler : config.dumpHandlers()) {
+                    dumpHandler.dump(object, message);
+                }
+            }
+        }
+    }
+
+    private static Object lock = new Object();
+
+    public <T> T scope(String newName, Runnable runnable, Callable<T> callable, boolean sandbox, Object[] newContext) {
+        DebugScope oldContext = getInstance();
+        DebugConfig oldConfig = getConfig();
+        DebugScope newChild = null;
+        if (sandbox) {
+            newChild = new DebugScope(newName, newName, null, newContext);
+            setConfig(null);
+        } else {
+            newChild = oldContext.createChild(newName, newContext);
+        }
+        instanceTL.set(newChild);
+        newChild.updateFlags();
+        try {
+            if (logEnabled || dumpEnabled) {
+                synchronized (lock) {
+                    return executeScope(runnable, callable);
+                }
+            } else {
+                return executeScope(runnable, callable);
+            }
+        } finally {
+            newChild.deactivate();
+            instanceTL.set(oldContext);
+            setConfig(oldConfig);
+        }
+    }
+
+    private <T> T executeScope(Runnable runnable, Callable<T> callable) {
+        try {
+            instanceTL.get().log("Starting scope %s", instanceTL.get().getQualifiedName());
+            if (runnable != null) {
+                runnable.run();
+            }
+            if (callable != null) {
+                return call(callable);
+            }
+        } catch (RuntimeException e) {
+            if (e == lastExceptionThrownTL.get()) {
+                throw e;
+            } else {
+                RuntimeException newException = interceptException(e);
+                lastExceptionThrownTL.set(newException);
+                throw newException;
+            }
+        }
+        return null;
+    }
+
+    private void updateFlags() {
+        DebugConfig config = getConfig();
+        if (config == null) {
+            logEnabled = false;
+            meterEnabled = false;
+            timerEnabled = false;
+            dumpEnabled = false;
+        } else {
+            logEnabled = config.isLogEnabled();
+            meterEnabled = config.isMeterEnabled();
+            timerEnabled = config.isTimerEnabled();
+            dumpEnabled = config.isDumpEnabled();
+        }
+    }
+
+    private void deactivate() {
+        context = null;
+    }
+
+    private RuntimeException interceptException(final RuntimeException 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 e;
+                    }
+                }}, false, new Object[]{e});
+        }
+        return e;
+    }
+
+    private DebugValueMap getValueMap() {
+        if (valueMap == null) {
+            valueMap = new DebugValueMap();
+        }
+        return valueMap;
+    }
+
+    long getCurrentValue(int index) {
+        return getValueMap().getCurrentValue(index);
+    }
+
+    void setCurrentValue(int index, long l) {
+        getValueMap().setCurrentValue(index, l);
+    }
+
+    private DebugScope createChild(String newName, Object[] newContext) {
+        String newQualifiedName = newName;
+        if (this.qualifiedName.length() > 0) {
+            newQualifiedName = this.qualifiedName + SCOPE_SEP + newName;
+        }
+        DebugScope result = new DebugScope(newName, newQualifiedName, this, newContext);
+        if (children == null) {
+            children = new ArrayList<>(4);
+        }
+        children.add(result);
+        return result;
+    }
+
+    public Iterable<Object> getCurrentContext() {
+        return new Iterable<Object>() {
+
+            @Override
+            public Iterator<Object> iterator() {
+                return new Iterator<Object>() {
+
+                    DebugScope currentScope = DebugScope.this;
+                    int objectIndex;
+
+                    @Override
+                    public boolean hasNext() {
+                        selectScope();
+                        return currentScope != null;
+                    }
+
+                    private void selectScope() {
+                        while (currentScope != null && currentScope.context.length <= objectIndex) {
+                            currentScope = currentScope.parent;
+                            objectIndex = 0;
+                        }
+                    }
+
+                    @Override
+                    public Object next() {
+                        selectScope();
+                        if (currentScope != null) {
+                            return currentScope.context[objectIndex++];
+                        }
+                        throw new IllegalStateException("May only be called if there is a next element.");
+                    }
+
+                    @Override
+                    public void remove() {
+                        throw new UnsupportedOperationException("This iterator is read only.");
+                    }
+                };
+            }
+        };
+    }
+
+    public static <T> T call(Callable<T> callable) {
+        try {
+            return callable.call();
+        } catch (Exception e) {
+            if (e instanceof RuntimeException) {
+                throw (RuntimeException) e;
+            } else {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public void setConfig(DebugConfig newConfig) {
+        configTL.set(newConfig);
+        updateFlags();
+    }
+
+    public String getQualifiedName() {
+        return qualifiedName;
+    }
+
+    public static PrintStream cachedOut;
+
+    public static void initialize() {
+        cachedOut = System.out;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValue.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug.internal;
+
+public class DebugValue {
+
+    private String name;
+    private int index;
+
+    protected DebugValue(String name) {
+        this.name = name;
+        this.index = -1;
+    }
+
+    protected long getCurrentValue() {
+        ensureInitialized();
+        return DebugScope.getInstance().getCurrentValue(index);
+    }
+
+    protected void setCurrentValue(long l) {
+        ensureInitialized();
+        DebugScope.getInstance().setCurrentValue(index, l);
+    }
+
+    private void ensureInitialized() {
+        if (index == -1) {
+            index = KeyRegistry.register(name);
+        }
+    }
+
+    protected void addToCurrentValue(long timeSpan) {
+        setCurrentValue(getCurrentValue() + timeSpan);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValueMap.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug.internal;
+
+import java.util.Arrays;
+
+public class DebugValueMap {
+
+    private long[] values;
+
+    public void setCurrentValue(int index, long l) {
+        ensureSize(index);
+        values[index] = l;
+    }
+
+    public long getCurrentValue(int index) {
+        ensureSize(index);
+        return values[index];
+    }
+
+    private void ensureSize(int index) {
+        if (values == null) {
+            values = new long[index + 1];
+        }
+        if (values.length <= index) {
+            values = Arrays.copyOf(values, index + 1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/KeyRegistry.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug.internal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class KeyRegistry {
+
+    private static int keyCount;
+    private static Map<String, Integer> keyMap = new HashMap<>();
+
+    public static synchronized int register(String name) {
+        if (!keyMap.containsKey(name)) {
+            keyMap.put(name, keyCount++);
+        }
+        return keyMap.get(name);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/MetricImpl.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug.internal;
+
+import com.oracle.max.graal.debug.*;
+
+public final class MetricImpl extends DebugValue implements DebugMetric {
+
+    public MetricImpl(String name) {
+        super(name);
+    }
+
+    public void increment() {
+        add(1);
+    }
+
+    public void add(int value) {
+        super.addToCurrentValue(value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/TimerImpl.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.debug.internal;
+
+import com.oracle.max.graal.debug.*;
+
+public final class TimerImpl extends DebugValue implements DebugTimer {
+
+    private long startTime = -1;
+
+    public TimerImpl(String name) {
+        super(name);
+    }
+
+    @Override
+    public void start() {
+        startTime = System.currentTimeMillis();
+    }
+
+    @Override
+    public void stop() {
+        long timeSpan = System.currentTimeMillis() - startTime;
+        super.addToCurrentValue(timeSpan);
+    }
+}
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java	Fri Jan 27 16:39:32 2012 +0100
@@ -30,14 +30,12 @@
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.target.*;
 import com.oracle.max.graal.cri.*;
 import com.oracle.max.graal.hotspot.bridge.*;
 import com.oracle.max.graal.hotspot.logging.*;
 import com.oracle.max.graal.hotspot.ri.*;
 import com.oracle.max.graal.hotspot.server.*;
-import com.oracle.max.graal.printer.*;
 
 /**
  * Singleton class holding the instance of the GraalCompiler.
@@ -90,7 +88,6 @@
     private final CompilerToVM vmEntries;
     private final VMToCompiler vmExits;
 
-    private GraalContext context;
     private HotSpotRuntime runtime;
     private GraalCompiler compiler;
     private CiTarget target;
@@ -163,7 +160,7 @@
             Backend backend = Backend.create(target.arch, runtime, target);
             generator.initialize(backend.newXirAssembler());
 
-            compiler = new GraalCompiler(context, getRuntime(), getTarget(), backend, generator);
+            compiler = new GraalCompiler(getRuntime(), getTarget(), backend, generator);
         }
         return compiler;
     }
@@ -216,20 +213,20 @@
     @Override
     public HotSpotRuntime getRuntime() {
         if (runtime == null) {
-            context = new GraalContext("Virtual Machine Compiler");
             if (GraalOptions.PrintCFGToFile) {
-                context.addCompilationObserver(new CFGPrinterObserver());
+//                context.addCompilationObserver(new CFGPrinterObserver());
             }
-            if (GraalOptions.PrintIdealGraphLevel != 0 || GraalOptions.Plot || GraalOptions.PlotOnError) {
-                CompilationObserver observer;
-                if (GraalOptions.PrintIdealGraphFile) {
-                    observer = new IdealGraphPrinterObserver();
-                } else {
-                    observer = new IdealGraphPrinterObserver(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort);
-                }
-                context.addCompilationObserver(observer);
-            }
-            runtime = new HotSpotRuntime(context, config, this);
+           // if (GraalOptions.PrintIdealGraphLevel != 0 || GraalOptions.Plot || GraalOptions.PlotOnError) {
+             //   CompilationObserver observer;
+               // if (GraalOptions.PrintIdealGraphFile) {
+              //      observer = new IdealGraphPrinterObserver();
+              //  } else {
+              //      observer = new IdealGraphPrinterObserver(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort);
+              //  }
+//                context.addCompilationObserver(observer);
+                // TODO(tw): Install observer.
+           // }
+            runtime = new HotSpotRuntime(config, this);
         }
         return runtime;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotDebugConfig.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.hotspot;
+
+import java.util.*;
+import java.util.regex.*;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+import com.oracle.max.graal.printer.*;
+
+
+public class HotSpotDebugConfig implements DebugConfig {
+
+    private final String logFilter;
+    private final String meterFilter;
+    private final String timerFilter;
+    private final String dumpFilter;
+    private final String methodFilter;
+    private final List<DebugDumpHandler> dumpHandlers = new ArrayList<>();
+
+    public HotSpotDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter) {
+        this.logFilter = logFilter;
+        this.meterFilter = meterFilter;
+        this.timerFilter = timerFilter;
+        this.dumpFilter = dumpFilter;
+        this.methodFilter = methodFilter;
+        dumpHandlers.add(new IdealGraphPrinterDumpHandler());
+    }
+
+    public boolean isLogEnabled() {
+        return isEnabled(logFilter);
+    }
+
+    public boolean isMeterEnabled() {
+        return isEnabled(meterFilter);
+    }
+
+    public boolean isDumpEnabled() {
+        return isEnabled(dumpFilter);
+    }
+
+    public boolean isTimerEnabled() {
+        return isEnabled(timerFilter);
+    }
+
+    private boolean isEnabled(String filter) {
+        return filter != null && checkContains(Debug.currentScope(), filter) && checkMethodFilter();
+    }
+
+    private static boolean checkContains(String currentScope, String filter) {
+        if (filter.contains("*")) {
+            /*filter = filter.replace("*", ".*");
+            filter = filter.replace("[", "\\[");
+            filter = filter.replace("]", "\\]");
+            filter = filter.replace(":", "\\:");*/
+            System.out.println("regexp: " + filter + " string=" + currentScope + ", " + Pattern.matches(filter, currentScope));
+            return Pattern.matches(filter, currentScope);
+        }
+        return currentScope.contains(filter);
+    }
+
+    private boolean checkMethodFilter() {
+        if (methodFilter == null) {
+            return true;
+        } else {
+            for (Object o : Debug.context()) {
+                if (o instanceof RiMethod) {
+                    RiMethod riMethod = (RiMethod) o;
+                    if (riMethod.toString().contains(methodFilter)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Debug config:");
+        add(sb, "Log", logFilter);
+        add(sb, "Meter", meterFilter);
+        add(sb, "Time", timerFilter);
+        add(sb, "Dump", dumpFilter);
+        add(sb, "MethodFilter", methodFilter);
+        return sb.toString();
+    }
+
+    private static void add(StringBuilder sb, String name, String filter) {
+        if (filter != null) {
+            sb.append(' ');
+            sb.append(name);
+            sb.append('=');
+            sb.append(filter);
+        }
+    }
+
+    @Override
+    public RuntimeException interceptException(RuntimeException e) {
+        Debug.setConfig(Debug.fixedConfig(true, true, false, false));
+        Debug.log(String.format("Exception occured in scope: %s", Debug.currentScope()));
+        for (Object o : Debug.context()) {
+            Debug.log("Context obj %s", o);
+            if (o instanceof Graph) {
+                Graph graph = (Graph) o;
+                Debug.log("Found graph in context: ", graph);
+                Debug.dump(o, "Exception graph");
+            }
+        }
+        return e;
+    }
+
+    @Override
+    public Collection<? extends DebugDumpHandler> dumpHandlers() {
+        return dumpHandlers;
+    }
+}
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotOptions.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/HotSpotOptions.java	Fri Jan 27 16:39:32 2012 +0100
@@ -77,7 +77,11 @@
                         value = Boolean.parseBoolean(valueString);
                     }
                 } else if (f.getType() == String.class) {
-                    value = valueString;
+                    if (valueString == null) {
+                        value = "";
+                    } else {
+                        value = valueString;
+                    }
                 }
             }
             if (value != null) {
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java	Fri Jan 27 16:39:32 2012 +0100
@@ -32,6 +32,8 @@
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.hotspot.*;
 import com.oracle.max.graal.hotspot.Compiler;
 import com.oracle.max.graal.hotspot.ri.*;
 import com.oracle.max.graal.hotspot.server.*;
@@ -44,6 +46,7 @@
 public class VMToCompilerImpl implements VMToCompiler, Remote {
 
     private final Compiler compiler;
+    private int compiledMethodCount;
 
     public final HotSpotTypePrimitive typeBoolean;
     public final HotSpotTypePrimitive typeChar;
@@ -55,18 +58,27 @@
     public final HotSpotTypePrimitive typeLong;
     public final HotSpotTypePrimitive typeVoid;
 
-    ThreadFactory daemonThreadFactory = new ThreadFactory() {
+    ThreadFactory compilerThreadFactory = new ThreadFactory() {
         @Override
         public Thread newThread(Runnable r) {
-            Thread t = new CompilerThread(r);
-            t.setDaemon(true);
-            return t;
+            return new CompilerThread(r);
         }
     };
-    private static final class CompilerThread extends Thread {
+    private final class CompilerThread extends Thread {
         public CompilerThread(Runnable r) {
             super(r);
-            this.setName("CompilerThread-" + this.getId());
+            this.setName("GraalCompilerThread-" + this.getId());
+            this.setDaemon(true);
+        }
+
+        @Override
+        public void run() {
+            if (GraalOptions.Debug) {
+                Debug.enable();
+                HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter);
+                Debug.setConfig(hotspotDebugConfig);
+            }
+            super.run();
         }
     }
     private ThreadPoolExecutor compileQueue;
@@ -93,12 +105,12 @@
         HotSpotRuntime runtime = (HotSpotRuntime) compiler.getCompiler().runtime;
         if (GraalOptions.Intrinsify) {
             GraalIntrinsics.installIntrinsics(runtime, runtime.getCompiler().getTarget(), PhasePlan.DEFAULT);
-            Snippets.install(runtime, runtime.getCompiler().getTarget(), new SystemSnippets(), GraalOptions.PlotSnippets, PhasePlan.DEFAULT);
-            Snippets.install(runtime, runtime.getCompiler().getTarget(), new UnsafeSnippets(), GraalOptions.PlotSnippets, PhasePlan.DEFAULT);
+            Snippets.install(runtime, runtime.getCompiler().getTarget(), new SystemSnippets(), PhasePlan.DEFAULT);
+            Snippets.install(runtime, runtime.getCompiler().getTarget(), new UnsafeSnippets(), PhasePlan.DEFAULT);
         }
 
         // Create compilation queue.
-        compileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), daemonThreadFactory);
+        compileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), compilerThreadFactory);
 
         // Create queue status printing thread.
         if (GraalOptions.PrintQueue) {
@@ -163,7 +175,8 @@
     }
 
     public void shutdownCompiler() throws Throwable {
-        compiler.getCompiler().context.print();
+//        compiler.getCompiler().context.print();
+        // TODO(tw): Print context results.
         compileQueue.shutdown();
     }
 
@@ -180,7 +193,37 @@
                         PhasePlan plan = new PhasePlan();
                         GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime());
                         plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-                        CiTargetMethod result = compiler.getCompiler().compileMethod(method, -1, plan);
+                        long startTime = 0;
+                        int index = compiledMethodCount++;
+                        final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed();
+                        if (printCompilation) {
+                            TTY.println(String.format("Graal %4d %-70s %-45s %-50s ...",
+                                            index,
+                                            method.holder().name(),
+                                            method.name(),
+                                            method.signature().asString()));
+                            startTime = System.nanoTime();
+                        }
+
+                        CiTargetMethod result = null;
+                        TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
+                        try {
+                            result = compiler.getCompiler().compileMethod(method, -1, plan);
+                        } finally {
+                            filter.remove();
+                            if (printCompilation) {
+                                long time = (System.nanoTime() - startTime) / 100000;
+                                TTY.println(String.format("Graal %4d %-70s %-45s %-50s | %3d.%dms %4dnodes %5dB",
+                                                index,
+                                                "",
+                                                "",
+                                                "",
+                                                time / 10,
+                                                time % 10,
+                                                0,
+                                                (result != null ? result.targetCodeSize() : -1)));
+                            }
+                        }
                         compiler.getRuntime().installMethod(method, result);
                     } catch (CiBailout bailout) {
                         if (GraalOptions.ExitVMOnBailout) {
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java	Fri Jan 27 16:39:32 2012 +0100
@@ -52,14 +52,12 @@
  * CRI runtime implementation for the HotSpot VM.
  */
 public class HotSpotRuntime implements GraalRuntime {
-    final GraalContext context;
     final HotSpotVMConfig config;
     final HotSpotRegisterConfig regConfig;
     private final HotSpotRegisterConfig globalStubRegConfig;
     private final Compiler compiler;
 
-    public HotSpotRuntime(GraalContext context, HotSpotVMConfig config, Compiler compiler) {
-        this.context = context;
+    public HotSpotRuntime(HotSpotVMConfig config, Compiler compiler) {
         this.config = config;
         this.compiler = compiler;
         regConfig = new HotSpotRegisterConfig(config, false);
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Fri Jan 27 16:39:32 2012 +0100
@@ -36,6 +36,7 @@
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.java.BlockMap.Block;
 import com.oracle.max.graal.java.BlockMap.DeoptBlock;
@@ -138,12 +139,12 @@
     private BlockMap createBlockMap() {
         BlockMap map = new BlockMap(method, config.useBranchPrediction());
         map.build();
-        currentContext.metrics.bytecodeCount += method.code().length;
 
-        if (currentContext.isObserved()) {
-            String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method);
-            currentContext.observable.fireCompilationEvent(label, map);
-        }
+//        if (currentContext.isObserved()) {
+//            String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method);
+//            currentContext.observable.fireCompilationEvent(label, map);
+//        }
+        // TODO(tw): Reinstall this logging code when debug framework is finished.
         return map;
     }
 
@@ -158,7 +159,6 @@
         this.canTrapBitSet = blockMap.canTrap;
 
         exceptionHandlers = blockMap.exceptionHandlers();
-        currentContext.metrics.blockCount += blockMap.blocks.size();
 
         nextBlockNumber = blockMap.blocks.size();
 
@@ -200,7 +200,6 @@
     }
 
     private int nextBlockNumber() {
-        currentContext.metrics.blockCount++;
         return nextBlockNumber++;
     }
 
@@ -892,9 +891,7 @@
             } else {
                 exception.exceptionEdge.setNext(createTarget(unwindBlock(bci()), frameState.duplicateWithException(bci(), exception.exception)));
             }
-            if (GraalOptions.Meter) {
-                currentContext.metrics.ExplicitExceptions++;
-            }
+            Debug.metric("ExplicitExceptions").increment();
         }
     }
 
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Fri Jan 27 16:39:32 2012 +0100
@@ -107,7 +107,7 @@
             if (schedule == null) {
                 try {
                     schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY);
-                    schedule.apply((StructuredGraph) graph, false);
+                    schedule.apply((StructuredGraph) graph);
                     blocks = schedule.getBlocks();
 
                     ComputeLinearScanOrder clso = new ComputeLinearScanOrder(schedule.getBlocks().size(), schedule.loopCount(), (LIRBlock) schedule.getStartBlock());
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java	Fri Jan 27 16:39:32 2012 +0100
@@ -27,7 +27,6 @@
 import java.util.Map.Entry;
 
 import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.graph.Node.Verbosity;
@@ -85,7 +84,7 @@
         printer.printProperty("origin", origin);
         printer.endProperties();
         printer.beginMethod(name, shortName, bci);
-        if (GraalOptions.PrintIdealGraphBytecodes && method != null) {
+        if (method != null) {
             printer.beginBytecodes();
             BytecodeStream bytecodes = new BytecodeStream(method.code());
             while (bytecodes.currentBC() != Bytecodes.END) {
@@ -134,7 +133,7 @@
         if (schedule == null) {
             try {
                 schedule = new IdentifyBlocksPhase(true);
-                schedule.apply((StructuredGraph) graph, false);
+                schedule.apply((StructuredGraph) graph);
             } catch (Throwable t) {
                 // nothing to do here...
             }
@@ -169,51 +168,6 @@
         NodeMap<Set<Entry<String, Integer>>> colors = graph.createNodeMap();
         NodeMap<Set<Entry<String, String>>> colorsToString = graph.createNodeMap();
         NodeMap<Set<String>> bits = graph.createNodeMap();
-// TODO This code was never reachable, since there was no code putting a NodeMap or NodeBitMap into the debugObjects.
-// If you need to reactivate this code, put the mapping from names to values into a helper object and register it in the new debugObjects array.
-//
-//        if (debugObjects != null) {
-//            for (Entry<String, Object> entry : debugObjects.entrySet()) {
-//                String name = entry.getKey();
-//                Object obj = entry.getValue();
-//                if (obj instanceof NodeMap) {
-//                    Map<Object, Integer> colorNumbers = new HashMap<Object, Integer>();
-//                    int nextColor = 0;
-//                    NodeMap<?> map = (NodeMap<?>) obj;
-//                    for (Entry<Node, ?> mapEntry : map.entries()) {
-//                        Node node = mapEntry.getKey();
-//                        Object color = mapEntry.getValue();
-//                        Integer colorNumber = colorNumbers.get(color);
-//                        if (colorNumber == null) {
-//                            colorNumber = nextColor++;
-//                            colorNumbers.put(color, colorNumber);
-//                        }
-//                        Set<Entry<String, Integer>> nodeColors = colors.get(node);
-//                        if (nodeColors == null) {
-//                            nodeColors = new HashSet<Entry<String, Integer>>();
-//                            colors.put(node, nodeColors);
-//                        }
-//                        nodeColors.add(new SimpleImmutableEntry<String, Integer>(name + "Color", colorNumber));
-//                        Set<Entry<String, String>> nodeColorStrings = colorsToString.get(node);
-//                        if (nodeColorStrings == null) {
-//                            nodeColorStrings = new HashSet<Entry<String, String>>();
-//                            colorsToString.put(node, nodeColorStrings);
-//                        }
-//                        nodeColorStrings.add(new SimpleImmutableEntry<String, String>(name, color.toString()));
-//                    }
-//                } else if (obj instanceof NodeBitMap) {
-//                    NodeBitMap bitmap = (NodeBitMap) obj;
-//                    for (Node node : bitmap) {
-//                        Set<String> nodeBits = bits.get(node);
-//                        if (nodeBits == null) {
-//                            nodeBits = new HashSet<String>();
-//                            bits.put(node, nodeBits);
-//                        }
-//                        nodeBits.add(name);
-//                    }
-//                }
-//            }
-//        }
 
         for (Node node : graph.getNodes()) {
             if (omittedClasses.contains(node.getClass())) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterDumpHandler.java	Fri Jan 27 16:39:32 2012 +0100
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.printer;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+
+import com.oracle.max.cri.ri.*;
+import com.oracle.max.graal.debug.*;
+import com.oracle.max.graal.graph.*;
+
+/**
+ * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation that can be
+ * inspected with the <a href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
+ */
+public class IdealGraphPrinterDumpHandler implements DebugDumpHandler {
+
+    private static final Pattern INVALID_CHAR = Pattern.compile("[^A-Za-z0-9_.-]");
+
+    private final String host;
+    private final int port;
+
+    public IdealGraphPrinter printer;
+    private OutputStream stream;
+    private Socket socket;
+
+    /**
+     * Creates a new {@link IdealGraphPrinterDumpHandler} that writes output to a file named after the compiled method.
+     */
+    public IdealGraphPrinterDumpHandler() {
+        this(null, -1);
+    }
+
+    /**
+     * Creates a new {@link IdealGraphPrinterDumpHandler} that sends output to a remote IdealGraphVisualizer instance.
+     */
+    public IdealGraphPrinterDumpHandler(String host, int port) {
+        this.host = host;
+        this.port = port;
+    }
+
+    private IdealGraphPrinter printer() {
+        return printer;
+    }
+
+    private Socket socket() {
+        return socket;
+    }
+
+    private void openPrinter(RiResolvedMethod method) {
+        assert stream == null && printer() == null;
+        String name;
+        if (method != null) {
+            name = method.holder().name();
+            name = name.substring(1, name.length() - 1).replace('/', '.');
+            name = name + "." + method.name();
+        } else {
+            name = "null";
+        }
+
+        openPrinter(name, method);
+    }
+
+    private void openPrinter(String title, RiResolvedMethod method) {
+        assert stream == null && printer() == null;
+        if (host != null) {
+            openNetworkPrinter(title, method);
+        } else {
+            openFilePrinter(title, method);
+        }
+    }
+
+    private void openFilePrinter(String title, RiResolvedMethod method) {
+        String filename = title + ".igv.xml";
+        filename = INVALID_CHAR.matcher(filename).replaceAll("_");
+
+        try {
+            stream = new FileOutputStream(filename);
+            printer = new IdealGraphPrinter(stream);
+            printer().begin();
+            printer().beginGroup(title, title, method, -1, "Graal");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public boolean networkAvailable() {
+        try {
+            Socket s = new Socket(host, port);
+            s.setSoTimeout(10);
+            s.close();
+            return true;
+        } catch (IOException e) {
+            return false;
+        }
+    }
+
+    private void openNetworkPrinter(String title, RiResolvedMethod method) {
+        try {
+            socket = new Socket(host, port);
+            if (socket().getInputStream().read() == 'y') {
+                stream = new BufferedOutputStream(socket().getOutputStream(), 0x4000);
+            } else {
+                // server currently does not accept any input
+                socket().close();
+                socket = null;
+                return;
+            }
+
+
+            printer = new IdealGraphPrinter(stream);
+            printer().begin();
+            printer().beginGroup(title, title, method, -1, "Graal");
+            printer().flush();
+            if (socket().getInputStream().read() != 'y') {
+                // server declines input for this method
+                socket().close();
+                socket = null;
+                stream = null;
+                printer = null;
+            }
+        } catch (IOException e) {
+            System.err.println("Error opening connection to " + host + ":" + port + ": " + e);
+
+            if (socket() != null) {
+                try {
+                    socket().close();
+                } catch (IOException ioe) {
+                }
+                socket = null;
+            }
+            stream = null;
+            printer = null;
+        }
+    }
+
+    private void closePrinter() {
+        assert (printer() != null);
+
+        try {
+            printer().endGroup();
+            printer().end();
+
+            if (socket() != null) {
+                socket().close(); // also closes stream
+            } else {
+                stream.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            printer = null;
+            stream = null;
+            socket = null;
+        }
+    }
+
+    public void compilationStarted(String groupTitle) {
+        openPrinter(groupTitle, null);
+    }
+
+    @Override
+    public void dump(Object object, String message) {
+        if (object instanceof Graph) {
+            Graph graph = (Graph) object;
+            List<RiResolvedMethod> inlineContext = Debug.contextSnapshot(RiResolvedMethod.class);
+            System.out.println("dumping graph");
+            for (RiResolvedMethod m : inlineContext) {
+                System.out.println("m="+m);
+            }
+        }
+    }
+}
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterObserver.java	Fri Jan 27 00:40:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,265 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.graal.printer;
-
-import java.io.*;
-import java.net.*;
-import java.util.regex.*;
-
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.observer.*;
-import com.oracle.max.graal.compiler.schedule.*;
-import com.oracle.max.graal.graph.*;
-
-/**
- * Observes compilation events and uses {@link IdealGraphPrinter} to generate a graph representation that can be
- * inspected with the <a href="http://kenai.com/projects/igv">Ideal Graph Visualizer</a>.
- */
-public class IdealGraphPrinterObserver implements CompilationObserver {
-
-    private static final Pattern INVALID_CHAR = Pattern.compile("[^A-Za-z0-9_.-]");
-
-    private final String host;
-    private final int port;
-
-    private static class PrintingContext {
-        public IdealGraphPrinter printer;
-        private OutputStream stream;
-        private Socket socket;
-
-    }
-    private final ThreadLocal<PrintingContext> context = new ThreadLocal<PrintingContext>() {
-        @Override
-        protected PrintingContext initialValue() {
-            return new PrintingContext();
-        }
-    };
-
-    /**
-     * Creates a new {@link IdealGraphPrinterObserver} that writes output to a file named after the compiled method.
-     */
-    public IdealGraphPrinterObserver() {
-        this(null, -1);
-    }
-
-    /**
-     * Creates a new {@link IdealGraphPrinterObserver} that sends output to a remote IdealGraphVisualizer instance.
-     */
-    public IdealGraphPrinterObserver(String host, int port) {
-        this.host = host;
-        this.port = port;
-    }
-
-    private PrintingContext context() {
-        return context.get();
-    }
-
-    private IdealGraphPrinter printer() {
-        return context().printer;
-    }
-
-    private Socket socket() {
-        return context().socket;
-    }
-
-    @Override
-    public void compilationStarted(CompilationEvent event) {
-        openPrinter(event.debugObject(RiResolvedMethod.class), false);
-    }
-
-    private void openPrinter(RiResolvedMethod method, boolean error) {
-        assert (context().stream == null && printer() == null);
-        if ((!TTY.isSuppressed() && GraalOptions.Plot) || (GraalOptions.PlotOnError && error)) {
-            String name;
-            if (method != null) {
-                name = method.holder().name();
-                name = name.substring(1, name.length() - 1).replace('/', '.');
-                name = name + "." + method.name();
-            } else {
-                name = "null";
-            }
-
-            openPrinter(name, method);
-        }
-    }
-
-    private void openPrinter(String title, RiResolvedMethod method) {
-        assert (context().stream == null && printer() == null);
-        if (!TTY.isSuppressed()) {
-            // Use a filter to suppress a recursive attempt to open a printer
-            TTY.Filter filter = new TTY.Filter();
-            try {
-                if (host != null) {
-                    openNetworkPrinter(title, method);
-                } else {
-                    openFilePrinter(title, method);
-                }
-            } finally {
-                filter.remove();
-            }
-        }
-    }
-
-    private void openFilePrinter(String title, RiResolvedMethod method) {
-        String filename = title + ".igv.xml";
-        filename = INVALID_CHAR.matcher(filename).replaceAll("_");
-
-        try {
-            context().stream = new FileOutputStream(filename);
-            context().printer = new IdealGraphPrinter(context().stream);
-            printer().begin();
-            printer().beginGroup(title, title, method, -1, "Graal");
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public boolean networkAvailable() {
-        try {
-            Socket s = new Socket(host, port);
-            s.setSoTimeout(10);
-            s.close();
-            return true;
-        } catch (IOException e) {
-            return false;
-        }
-    }
-
-    private void openNetworkPrinter(String title, RiResolvedMethod method) {
-        try {
-            context().socket = new Socket(host, port);
-            if (socket().getInputStream().read() == 'y') {
-                context().stream = new BufferedOutputStream(socket().getOutputStream(), 0x4000);
-            } else {
-                // server currently does not accept any input
-                socket().close();
-                context().socket = null;
-                return;
-            }
-
-            context().printer = new IdealGraphPrinter(context().stream);
-            printer().begin();
-            printer().beginGroup(title, title, method, -1, "Graal");
-            printer().flush();
-            if (socket().getInputStream().read() != 'y') {
-                // server declines input for this method
-                socket().close();
-                context().socket = null;
-                context().stream = null;
-                context().printer = null;
-            }
-        } catch (IOException e) {
-            System.err.println("Error opening connection to " + host + ":" + port + ": " + e);
-
-            if (socket() != null) {
-                try {
-                    socket().close();
-                } catch (IOException ioe) {
-                }
-                context().socket = null;
-            }
-            context().stream = null;
-            context().printer = null;
-        }
-    }
-
-    @Override
-    public void compilationEvent(CompilationEvent event) {
-        boolean lazyStart = false;
-        if (printer() == null && event.hasDebugObject(CompilationEvent.ERROR)) {
-            openPrinter(event.debugObject(RiResolvedMethod.class), true);
-            lazyStart = true;
-        }
-        Graph graph = event.debugObject(Graph.class);
-        if (printer() != null && graph != null) {
-            printer().print(graph, event.label, true, event.debugObject(IdentifyBlocksPhase.class));
-        }
-        if (lazyStart && printer() != null) {
-            closePrinter();
-        }
-    }
-
-    @Override
-    public void compilationFinished(CompilationEvent event) {
-        if (printer() != null) {
-            closePrinter();
-        }
-    }
-
-    private void closePrinter() {
-        assert (printer() != null);
-
-        try {
-            printer().endGroup();
-            printer().end();
-
-            if (socket() != null) {
-                socket().close(); // also closes stream
-            } else {
-                context().stream.close();
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            context().printer = null;
-            context().stream = null;
-            context().socket = null;
-        }
-    }
-
-    public void printGraphs(String groupTitle, Graph... graphs) {
-        openPrinter(groupTitle, null);
-        if (printer() != null) {
-            int i = 0;
-            for (Graph graph : graphs) {
-                printer().print(graph, "Graph " + i, true);
-                i++;
-            }
-            closePrinter();
-        }
-    }
-
-    public void compilationStarted(String groupTitle) {
-        openPrinter(groupTitle, null);
-    }
-
-    public void printGraph(String graphTitle, Graph graph) {
-        if (printer() != null) {
-            printer().print(graph, graphTitle, true);
-        }
-    }
-
-    public void printSingleGraph(String title, Graph graph) {
-        printSingleGraph(title, title, graph);
-    }
-
-    public void printSingleGraph(String groupTitle, String graphTitle, Graph graph) {
-        openPrinter(groupTitle, null);
-        if (printer() != null) {
-            printer().print(graph, graphTitle, true);
-            closePrinter();
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/GraalIntrinsics.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/GraalIntrinsics.java	Fri Jan 27 16:39:32 2012 +0100
@@ -34,11 +34,11 @@
 public class GraalIntrinsics {
     public static void installIntrinsics(GraalRuntime runtime, CiTarget target, PhasePlan plan) {
         if (GraalOptions.Intrinsify) {
-            Snippets.install(runtime, target, new MathSnippetsX86(), GraalOptions.PlotSnippets, plan);
-            Snippets.install(runtime, target, new DoubleSnippets(), GraalOptions.PlotSnippets, plan);
-            Snippets.install(runtime, target, new FloatSnippets(), GraalOptions.PlotSnippets, plan);
-            Snippets.install(runtime, target, new NodeClassSnippets(), GraalOptions.PlotSnippets, plan);
-            Snippets.install(runtime, target, new ArrayCopySnippets(), GraalOptions.PlotSnippets, plan);
+            Snippets.install(runtime, target, new MathSnippetsX86(), plan);
+            Snippets.install(runtime, target, new DoubleSnippets(), plan);
+            Snippets.install(runtime, target, new FloatSnippets(), plan);
+            Snippets.install(runtime, target, new NodeClassSnippets(), plan);
+            Snippets.install(runtime, target, new ArrayCopySnippets(), plan);
             plan.addPhase(PhasePosition.HIGH_LEVEL, new IntrinsifyArrayCopyPhase(runtime));
         }
     }
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java	Fri Jan 27 16:39:32 2012 +0100
@@ -26,62 +26,46 @@
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.observer.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.extended.*;
 import com.oracle.max.graal.nodes.java.*;
-import com.oracle.max.graal.printer.*;
 
 /**
  * Utilities for snippet installation and management.
  */
 public class Snippets {
 
-    public static void install(GraalRuntime runtime, CiTarget target, SnippetsInterface obj, boolean plotGraphs, PhasePlan plan) {
+    public static void install(GraalRuntime runtime, CiTarget target, SnippetsInterface obj, PhasePlan plan) {
         Class<? extends SnippetsInterface> clazz = obj.getClass();
-        GraalContext context = new GraalContext("Installing Snippet");
         BoxingMethodPool pool = new BoxingMethodPool(runtime);
         if (clazz.isAnnotationPresent(ClassSubstitution.class)) {
-            installSubstitution(runtime, target, plotGraphs, plan, clazz, context, pool, clazz.getAnnotation(ClassSubstitution.class).value());
+            installSubstitution(runtime, target, plan, clazz, pool, clazz.getAnnotation(ClassSubstitution.class).value());
         } else {
-            installSnippets(runtime, target, plotGraphs, plan, clazz, context, pool);
+            installSnippets(runtime, target, plan, clazz, pool);
         }
     }
 
-    private static void installSnippets(GraalRuntime runtime, CiTarget target, boolean plotGraphs, PhasePlan plan, Class< ? extends SnippetsInterface> clazz, GraalContext context,
+    private static void installSnippets(GraalRuntime runtime, CiTarget target, PhasePlan plan, Class< ? extends SnippetsInterface> clazz,
                     BoxingMethodPool pool) {
         for (Method snippet : clazz.getDeclaredMethods()) {
-            try {
-                int modifiers = snippet.getModifiers();
-                if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
-                    throw new RuntimeException("Snippet must not be abstract or native");
-                }
-                RiResolvedMethod snippetRiMethod = runtime.getRiMethod(snippet);
-                if (snippetRiMethod.compilerStorage().get(Graph.class) == null) {
-                    buildSnippetGraph(snippetRiMethod, runtime, target, context, pool, plotGraphs, plan);
-                }
-            } catch (GraalInternalError error) {
-                if (context.isObserved()) {
-                    if (error.node() != null) {
-                        context.observable.fireCompilationEvent("VerificationError on Node " + error.node(), CompilationEvent.ERROR, error.node().graph());
-                    } else if (error.graph() != null) {
-                        context.observable.fireCompilationEvent("VerificationError on Graph " + error.graph(), CompilationEvent.ERROR, error.graph());
-                    }
-                }
-                throw error;
-            } catch (Throwable t) {
-                throw new RuntimeException("Error when installing snippet for " + clazz, t);
+            int modifiers = snippet.getModifiers();
+            if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                throw new RuntimeException("Snippet must not be abstract or native");
+            }
+            RiResolvedMethod snippetRiMethod = runtime.getRiMethod(snippet);
+            if (snippetRiMethod.compilerStorage().get(Graph.class) == null) {
+                buildSnippetGraph(snippetRiMethod, runtime, target, pool, plan);
             }
         }
     }
 
-    private static void installSubstitution(GraalRuntime runtime, CiTarget target, boolean plotGraphs, PhasePlan plan, Class< ? extends SnippetsInterface> clazz, GraalContext context,
+    private static void installSubstitution(GraalRuntime runtime, CiTarget target, PhasePlan plan, Class< ? extends SnippetsInterface> clazz,
                     BoxingMethodPool pool, Class<?> original) throws GraalInternalError {
         for (Method snippet : clazz.getDeclaredMethods()) {
             try {
@@ -94,50 +78,24 @@
                     throw new RuntimeException("Snippet must not be abstract or native");
                 }
                 RiResolvedMethod snippetRiMethod = runtime.getRiMethod(snippet);
-                StructuredGraph graph = buildSnippetGraph(snippetRiMethod, runtime, target, context, pool, plotGraphs, plan);
+                StructuredGraph graph = buildSnippetGraph(snippetRiMethod, runtime, target, pool, plan);
                 runtime.getRiMethod(method).compilerStorage().put(Graph.class, graph);
             } catch (NoSuchMethodException e) {
                 throw new RuntimeException("Could not resolve method to substitute with: " + snippet.getName(), e);
-            } catch (GraalInternalError error) {
-                if (context.isObserved()) {
-                    if (error.node() != null) {
-                        context.observable.fireCompilationEvent("VerificationError on Node " + error.node(), CompilationEvent.ERROR, error.node().graph());
-                    } else if (error.graph() != null) {
-                        context.observable.fireCompilationEvent("VerificationError on Graph " + error.graph(), CompilationEvent.ERROR, error.graph());
-                    }
-                }
-                throw error;
-            } catch (Throwable t) {
-                throw new RuntimeException("Error when installing snippet for " + clazz, t);
             }
         }
     }
 
-    private static StructuredGraph buildSnippetGraph(RiResolvedMethod snippetRiMethod, GraalRuntime runtime, CiTarget target, GraalContext context, BoxingMethodPool pool, boolean plotGraphs, PhasePlan plan) {
-        IdealGraphPrinterObserver observer = null;
-        if (plotGraphs) {
-            observer = new IdealGraphPrinterObserver(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort);
-            observer.compilationStarted(CiUtil.format("snippet:%h.%n(%p)", snippetRiMethod));
-        }
-        StructuredGraph graph = buildSnippetGraph(snippetRiMethod, runtime, target, context, pool, plan, observer);
-        if (observer != null) {
-            observer.compilationFinished(null);
-        }
-        return graph;
-    }
-
-    private static StructuredGraph buildSnippetGraph(RiResolvedMethod snippetRiMethod, GraalRuntime runtime, CiTarget target, GraalContext context, BoxingMethodPool pool, PhasePlan plan, IdealGraphPrinterObserver observer) {
+    private static StructuredGraph buildSnippetGraph(RiResolvedMethod snippetRiMethod, GraalRuntime runtime, CiTarget target, BoxingMethodPool pool, PhasePlan plan) {
 
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault();
         GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config);
         StructuredGraph graph = new StructuredGraph(snippetRiMethod);
-        graphBuilder.apply(graph, context);
+        graphBuilder.apply(graph);
 
-        if (observer != null) {
-            observer.printGraph(snippetRiMethod.name() + ":" + GraphBuilderPhase.class.getSimpleName(), graph);
-        }
+        Debug.dump(graph, "%s: %s", snippetRiMethod.name(), GraphBuilderPhase.class.getSimpleName());
 
-        new SnippetIntrinsificationPhase(runtime, pool).apply(graph, context);
+        new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
 
         for (Invoke invoke : graph.getInvokes()) {
             MethodCallTargetNode callTarget = invoke.callTarget();
@@ -146,29 +104,25 @@
             if (holder.isSubtypeOf(runtime.getType(SnippetsInterface.class))) {
                 StructuredGraph targetGraph = (StructuredGraph) targetMethod.compilerStorage().get(Graph.class);
                 if (targetGraph == null) {
-                    targetGraph = buildSnippetGraph(targetMethod, runtime, target, context, pool, plan, observer);
+                    targetGraph = buildSnippetGraph(targetMethod, runtime, target, pool, plan);
                 }
                 InliningUtil.inline(invoke, targetGraph, true);
                 new CanonicalizerPhase(target, runtime, null).apply(graph);
             }
         }
 
-        new SnippetIntrinsificationPhase(runtime, pool).apply(graph, context);
+        new SnippetIntrinsificationPhase(runtime, pool).apply(graph);
 
-        if (observer != null) {
-            observer.printGraph(snippetRiMethod.name() + ":" + SnippetIntrinsificationPhase.class.getSimpleName(), graph);
-        }
-        new DeadCodeEliminationPhase().apply(graph, context);
-        new CanonicalizerPhase(target, runtime, null).apply(graph, context);
+        Debug.dump(graph, "%s: %s", snippetRiMethod.name(), GraphBuilderPhase.class.getSimpleName());
+        new DeadCodeEliminationPhase().apply(graph);
+        new CanonicalizerPhase(target, runtime, null).apply(graph);
 
         // TODO (gd) remove when we have safepoint polling elimination
         for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {
             end.setSafepointPolling(false);
         }
 
-        if (observer != null) {
-            observer.printGraph(snippetRiMethod.name() + ":" + "Final", graph);
-        }
+        Debug.dump(graph, "%s: Final", snippetRiMethod.name());
 
         snippetRiMethod.compilerStorage().put(Graph.class, graph);
 
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/BoxingEliminationTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/BoxingEliminationTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -28,6 +28,7 @@
 
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.extended.*;
@@ -109,9 +110,9 @@
         }
         new InliningPhase(null, runtime(), hints, null, phasePlan).apply(graph);
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        print(graph);
+        Debug.dump(graph, "Graph");
         new BoxingEliminationPhase().apply(graph);
-        print(graph);
+        Debug.dump(graph, "Graph");
         new ExpandBoxingNodesPhase(pool).apply(graph);
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/DegeneratedLoopsTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/DegeneratedLoopsTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -27,6 +27,7 @@
 import org.junit.*;
 
 import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 
@@ -80,7 +81,7 @@
 
     private void test(String snippet) {
         StructuredGraph graph = parse(snippet);
-        print(graph);
+        Debug.dump(graph, "Graph");
         LocalNode local = graph.getNodes(LocalNode.class).iterator().next();
         ConstantNode constant = ConstantNode.forInt(0, graph);
         for (Node n : local.usages().snapshot()) {
@@ -94,7 +95,7 @@
             invoke.intrinsify(null);
         }
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); print(referenceGraph);
+        StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); Debug.dump(referenceGraph, "Graph");
         assertEquals(referenceGraph, graph);
     }
 }
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/EscapeAnalysisTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/EscapeAnalysisTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -28,6 +28,7 @@
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.java.*;
 
@@ -122,9 +123,9 @@
 
         new InliningPhase(null, runtime(), null, null, getDefaultPhasePlan()).apply(graph);
         new DeadCodeEliminationPhase().apply(graph);
-        print(graph);
+        Debug.dump(graph, "Graph");
         new EscapeAnalysisPhase(null, runtime(), null, getDefaultPhasePlan()).apply(graph);
-        print(graph);
+        Debug.dump(graph, "Graph");
         int retCount = 0;
         for (ReturnNode ret : graph.getNodes(ReturnNode.class)) {
             Assert.assertTrue(ret.result().isConstant());
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -24,18 +24,15 @@
 
 import java.lang.reflect.*;
 
-import org.junit.*;
-
 import junit.framework.Assert;
 
 import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.*;
 import com.oracle.max.graal.cri.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
-import com.oracle.max.graal.printer.*;
 
 /**
  * Base class for Graal compiler unit tests. These are white box tests
@@ -56,23 +53,15 @@
 public abstract class GraphTest {
 
     protected final GraalRuntime runtime;
-    private static IdealGraphPrinterObserver observer;
 
     public GraphTest() {
         this.runtime = GraalRuntimeAccess.getGraalRuntime();
     }
 
-    @BeforeClass
-    public static void init() {
-        IdealGraphPrinterObserver o = new IdealGraphPrinterObserver(GraalOptions.PrintIdealGraphAddress, GraalOptions.PrintIdealGraphPort);
-        if (o.networkAvailable()) {
-            observer = o;
-        }
-    }
-
     protected void assertEquals(StructuredGraph expected, StructuredGraph graph) {
         if (expected.getNodeCount() != graph.getNodeCount()) {
-            print("Node count not matching", expected, graph);
+            Debug.dump(expected, "Node count not matching - expected");
+            Debug.dump(graph, "Node count not matching - actual");
             Assert.fail("Graphs do not have the same number of nodes");
         }
     }
@@ -112,16 +101,4 @@
         plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault()));
         return plan;
     }
-
-    protected void print(String title, StructuredGraph... graphs) {
-        if (observer != null) {
-            observer.printGraphs(getClass().getSimpleName() + ": " + title, graphs);
-        }
-    }
-
-    protected void print(StructuredGraph graph) {
-        if (observer != null) {
-            observer.printSingleGraph(getClass().getSimpleName(), graph);
-        }
-    }
 }
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfBoxingEliminationTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfBoxingEliminationTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -28,6 +28,7 @@
 
 import com.oracle.max.graal.compiler.phases.*;
 import com.oracle.max.graal.compiler.phases.PhasePlan.PhasePosition;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.extended.*;
 
@@ -84,9 +85,9 @@
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
         new PhiStampPhase().apply(graph);
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
-        print(graph);
+        Debug.dump(graph, "Graph");
         new BoxingEliminationPhase().apply(graph);
-        print(graph);
+        Debug.dump(graph, "Graph");
         new ExpandBoxingNodesPhase(pool).apply(graph);
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfCanonicalizerTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/IfCanonicalizerTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -25,6 +25,7 @@
 import org.junit.*;
 
 import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 
@@ -143,7 +144,7 @@
                 n.replaceFirstInput(local, constant);
             }
         }
-        print(graph);
+        Debug.dump(graph, "Graph");
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
         StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
         assertEquals(referenceGraph, graph);
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/NestedLoopTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/NestedLoopTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -25,6 +25,7 @@
 import org.junit.*;
 
 import com.oracle.max.graal.compiler.loop.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.nodes.*;
 
 public class NestedLoopTest extends GraphTest {
@@ -142,7 +143,7 @@
 
     private void test(String snippet, int rootExits, int nestedExits, int innerExits) {
         StructuredGraph graph = parse(snippet);
-        print(graph);
+        Debug.dump(graph, "Graph");
         LoopInfo loopInfo = LoopUtil.computeLoopInfo(graph);
         loopInfo.print();
         Loop rootLoop = loopInfo.rootLoops().get(0);
@@ -161,6 +162,6 @@
         Assert.assertEquals(rootExits, rootLoop.exits().cardinality());
         Assert.assertEquals(nestedExits, nestedLoop.exits().cardinality());
         Assert.assertEquals(innerExits, innerMostLoop.exits().cardinality());
-        print(graph);
+        Debug.dump(graph, "Graph");
     }
 }
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/PhiCreationTests.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/PhiCreationTests.java	Fri Jan 27 16:39:32 2012 +0100
@@ -24,6 +24,7 @@
 
 import org.junit.*;
 
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.nodes.*;
 
 /**
@@ -66,7 +67,7 @@
     @Test
     public void test3() {
         StructuredGraph graph = parse("test3Snippet");
-        print(graph);
+        Debug.dump(graph, "Graph");
         Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
     }
 
@@ -82,7 +83,7 @@
     @Test
     public void test4() {
         StructuredGraph graph = parse("test4Snippet");
-        print(graph);
+        Debug.dump(graph, "Graph");
         Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
     }
 
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/ScalarTypeSystemTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/ScalarTypeSystemTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -27,6 +27,7 @@
 import org.junit.*;
 
 import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.nodes.*;
 
 /**
@@ -162,7 +163,7 @@
 
     private void test(String snippet, String referenceSnippet) {
         StructuredGraph graph = parse(snippet);
-        print(graph);
+        Debug.dump(graph, "Graph");
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
         StructuredGraph referenceGraph = parse(referenceSnippet);
         assertEquals(referenceGraph, graph);
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/StraighteningTest.java	Fri Jan 27 00:40:26 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/StraighteningTest.java	Fri Jan 27 16:39:32 2012 +0100
@@ -27,6 +27,7 @@
 import org.junit.*;
 
 import com.oracle.max.graal.compiler.phases.*;
+import com.oracle.max.graal.debug.*;
 import com.oracle.max.graal.nodes.*;
 
 public class StraighteningTest extends GraphTest {
@@ -87,7 +88,7 @@
 
     private void test(String snippet) {
         StructuredGraph graph = parse(snippet);
-        print(graph);
+        Debug.dump(graph, "Graph");
         new CanonicalizerPhase(null, runtime(), null).apply(graph);
         StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
         assertEquals(referenceGraph, graph);
--- a/mx/projects	Fri Jan 27 00:40:26 2012 +0100
+++ b/mx/projects	Fri Jan 27 16:39:32 2012 +0100
@@ -50,7 +50,12 @@
 # graal.graph
 project@com.oracle.max.graal.graph@subDir=graal
 project@com.oracle.max.graal.graph@sourceDirs=src
-project@com.oracle.max.graal.graph@dependencies=JUNIT
+project@com.oracle.max.graal.graph@dependencies=com.oracle.max.graal.debug,JUNIT
+
+# graal.debug
+project@com.oracle.max.graal.debug@subDir=graal
+project@com.oracle.max.graal.debug@sourceDirs=src
+project@com.oracle.max.graal.debug@checkstyle=com.oracle.max.graal.graph
 
 # graal.snippets
 project@com.oracle.max.graal.snippets@subDir=graal
--- a/src/share/vm/graal/graal_paths.hpp	Fri Jan 27 00:40:26 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
- 
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.cri");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.criutils");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.asm");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.graph");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.nodes");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.compiler");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.java");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.printer");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.snippets");
-    prepend_to_graal_classpath(scp_compiler, graal_dir, "com.oracle.max.graal.hotspot");
--- a/src/share/vm/prims/jni.cpp	Fri Jan 27 00:40:26 2012 +0100
+++ b/src/share/vm/prims/jni.cpp	Fri Jan 27 16:39:32 2012 +0100
@@ -5124,11 +5124,13 @@
     *vm = (JavaVM *)(&main_vm);
     *(JNIEnv**)penv = thread->jni_environment();
 
+#ifdef GRAAL
     if (UseGraal) {
       GraalCompiler* compiler = GraalCompiler::instance();
       ciObjectFactory::initialize(); 
       compiler->initialize();
     }
+#endif
 
     // Tracks the time application was running before GC
     RuntimeService::record_application_start();
--- a/src/share/vm/runtime/arguments.cpp	Fri Jan 27 00:40:26 2012 +0100
+++ b/src/share/vm/runtime/arguments.cpp	Fri Jan 27 16:39:32 2012 +0100
@@ -2096,9 +2096,22 @@
       }
     }
     if (PrintVMOptions) tty->print_cr("GRAAL=%s", graal_dir);
-
+    
     SysClassPath scp_compiler(Arguments::get_sysclasspath());
-#include "graal/graal_paths.hpp"
+    struct dirent* dentry;
+    char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(graal_dir));
+    errno = 0;
+    DIR* graal_dir_handle = os::opendir(graal_dir);
+    while ((dentry = os::readdir(graal_dir_handle, (struct dirent *)tdbuf)) != NULL) {
+      if (strcmp(dentry->d_name, ".") != 0 && strcmp(dentry->d_name, "..")) {
+        prepend_to_graal_classpath(scp_compiler, graal_dir, dentry->d_name);
+        if (PrintVMOptions) {
+          tty->print_cr("Adding project directory %s to bootclasspath", dentry->d_name);
+        }
+      }
+    }
+    os::closedir(graal_dir_handle);
+    FREE_C_HEAP_ARRAY(char, tdbuf);
     scp_compiler.expand_endorsed();
 
     Arguments::set_compilerclasspath(scp_compiler.combined_path());