changeset 4272:75c951399c65

Merge.
author Doug Simon <doug.simon@oracle.com>
date Wed, 11 Jan 2012 18:25:56 +0100
parents 311d193de5a2 ba5f95c3d6f5
children 0519dc447740
files graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCompiler.java graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiStatistics.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/stub/CompilerStub.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompilerStubEmitter.java
diffstat 52 files changed, 772 insertions(+), 1497 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiCompiler.java	Wed Jan 11 18:25:25 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.cri.ci;
-
-import com.oracle.max.cri.ri.*;
-
-public interface CiCompiler {
-
-    /**
-     * Denotes the level of debug info for safepoints that should be generated by a compilation.
-     */
-    enum DebugInfoLevel {
-        /**
-         * Only ref maps are required.
-         */
-        REF_MAPS,
-
-        /**
-         * Code positions and ref maps are required.
-         */
-        CODE_POS_AND_REF_MAPS,
-
-        /**
-         * Frame info, code positions and ref maps are required.
-         * Only a compilation with level can make speculative optimizations.
-         */
-        FULL
-    }
-
-    /**
-     * Compile the specified method.
-     *
-     * @param method the method to compile
-     * @param osrBCI the bytecode index of the entrypoint for an on-stack-replacement or {@code -1} if this is not an
-     *            on-stack-replacement compilation
-     * @param debugInfoLevel TODO
-     */
-    CiResult compileMethod(RiResolvedMethod method, int osrBCI, CiStatistics stats, DebugInfoLevel debugInfoLevel);
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiResult.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiResult.java	Wed Jan 11 18:25:56 2012 +0100
@@ -30,7 +30,6 @@
 public class CiResult {
     private final CiTargetMethod targetMethod;
     private final CiBailout bailout;
-    private final CiStatistics stats;
 
     /**
      * Creates a new compilation result.
@@ -38,10 +37,9 @@
      * @param bailout the bailout condition that occurred
      * @param stats statistics about the compilation
      */
-    public CiResult(CiTargetMethod targetMethod, CiBailout bailout, CiStatistics stats) {
+    public CiResult(CiTargetMethod targetMethod, CiBailout bailout) {
         this.targetMethod = targetMethod;
         this.bailout = bailout;
-        this.stats = stats;
     }
 
     /**
@@ -58,14 +56,6 @@
     }
 
     /**
-     * Returns the statistics about the compilation that were produced, if any.
-     * @return the statistics
-     */
-    public CiStatistics statistics() {
-        return stats;
-    }
-
-    /**
      * Returns the bailout condition that occurred for this compilation, if any.
      * @return the bailout
      */
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiStatistics.java	Wed Jan 11 18:25:25 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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;
-
-/**
- * Contains statistics gathered during the compilation of a method and reported back
- * from the compiler as the result of compilation.
- */
-public class CiStatistics {
-
-    /**
-     * 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;
-
-}
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java	Wed Jan 11 18:25:56 2012 +0100
@@ -130,6 +130,8 @@
      */
     RiRegisterConfig getRegisterConfig(RiMethod method);
 
+    RiRegisterConfig getGlobalStubRegisterConfig();
+
     /**
      * Custom area on the stack of each compiled method that the VM can use for its own purposes.
      * @return the size of the custom area in bytes
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/CiXirAssembler.java	Wed Jan 11 18:25:56 2012 +0100
@@ -499,10 +499,6 @@
          */
         PointerCAS,
         /**
-         * Call the {@link XirTemplate.GlobalFlags#GLOBAL_STUB shared stub} defined by {@code extra} with {@code args} and put the result in {@code r}.
-         */
-        CallStub,
-        /**
          * Call the {@link RiMethod} defined by {@code extra}  with {@code args} and put the result in {@code r}.
          */
         CallRuntime,
@@ -821,11 +817,6 @@
         append(new XirInstruction(CiKind.Void, message, ShouldNotReachHere, null));
     }
 
-    public void callStub(XirTemplate stub, XirOperand result, XirOperand... args) {
-        CiKind resultKind = result == null ? CiKind.Void : result.kind;
-        append(new XirInstruction(resultKind, stub, CallStub, result, args));
-    }
-
     public void callRuntime(Object rt, XirOperand result, XirOperand... args) {
         callRuntime(rt, result, false, args);
     }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/RiXirGenerator.java	Wed Jan 11 18:25:56 2012 +0100
@@ -22,11 +22,9 @@
  */
 package com.oracle.max.cri.xir;
 
-import java.util.*;
-
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.ri.RiType.*;
+import com.oracle.max.cri.ri.RiType.Representation;
 
 /**
  * Represents the interface through which the compiler requests the XIR for a given bytecode from the runtime system.
@@ -112,12 +110,10 @@
     XirSnippet genTypeCheck(XirSite site, XirArgument object, XirArgument hub, RiType type);
 
     /**
-     * Gets the list of XIR templates, using the given XIR assembler to create them if
-     * they haven't yet been created.
+     * Initializes the XIR generator for the given XIR assembler.
      *
      * @param asm the XIR assembler
-     * @return the list of templates
      */
-    List<XirTemplate> makeTemplates(CiXirAssembler asm);
+    void initialize(CiXirAssembler asm);
 
 }
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirTemplate.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/xir/XirTemplate.java	Wed Jan 11 18:25:56 2012 +0100
@@ -112,8 +112,6 @@
 
     public final boolean allocateResultOperand;
 
-    public final XirTemplate[] calleeTemplates;
-
     public final XirMark[] marks;
 
     public final int outgoingStackSize;
@@ -139,7 +137,6 @@
                        XirTemp[] temps,
                        XirConstant[] constantValues,
                        int flags,
-                       XirTemplate[] calleeTemplates,
                        XirMark[] marks,
                        int outgoingStackSize) {
         this.name = name;
@@ -153,7 +150,6 @@
         this.temps = temps;
         this.allocateResultOperand = allocateResultOperand;
         this.constants = constantValues;
-        this.calleeTemplates = calleeTemplates;
         this.marks = marks;
         this.outgoingStackSize = outgoingStackSize;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/simple/SpillAllAllocator.java	Wed Jan 11 18:25:56 2012 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.max.graal.alloc.simple;
 
-import static com.oracle.max.graal.compiler.lir.LIRPhiMapping.*;
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.max.graal.alloc.util.ValueUtil.*;
 
@@ -30,12 +29,14 @@
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ci.CiRegister.RegisterFlag;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.alloc.util.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.*;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandMode;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.ValueProcedure;
+import com.oracle.max.graal.compiler.lir.LIRPhiMapping.PhiValueProcedure;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.compiler.util.*;
 
@@ -43,17 +44,15 @@
     private final GraalContext context;
     private final LIR lir;
     private final FrameMap frameMap;
-    private final RiRegisterConfig registerConfig;
 
     private final DataFlowAnalysis dataFlow;
 
-    public SpillAllAllocator(GraalContext context, LIR lir, GraalCompilation compilation, RiRegisterConfig registerConfig) {
+    public SpillAllAllocator(GraalContext context, LIR lir, FrameMap frameMap) {
         this.context = context;
         this.lir = lir;
-        this.registerConfig = registerConfig;
-        this.frameMap = compilation.frameMap();
+        this.frameMap = frameMap;
 
-        this.dataFlow = new DataFlowAnalysis(context, lir, registerConfig);
+        this.dataFlow = new DataFlowAnalysis(context, lir, frameMap.registerConfig);
         this.blockLocations = new LocationMap[lir.linearScanOrder().size()];
         this.moveResolver = new MoveResolverImpl(frameMap);
     }
@@ -65,7 +64,7 @@
 
         @Override
         protected CiValue scratchRegister(Variable spilled) {
-            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = registerConfig.getCategorizedAllocatableRegisters();
+            EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
             CiRegister[] availableRegs = categorizedRegs.get(spilled.flag);
             for (CiRegister reg : availableRegs) {
                 if (curInRegisterState[reg.number] == null && curOutRegisterState[reg.number] == null) {
@@ -110,7 +109,7 @@
     }
 
     private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
     }
 
 
@@ -132,7 +131,7 @@
     private LIRInstruction curInstruction;
 
     public void execute() {
-        assert LIRVerifier.verify(true, lir, frameMap, registerConfig);
+        assert LIRVerifier.verify(true, lir, frameMap);
 
         dataFlow.execute();
         allocate();
@@ -144,13 +143,13 @@
         resolveDataFlow.execute();
 
         context.observable.fireCompilationEvent("After resolve data flow", lir);
-        assert RegisterVerifier.verify(lir, frameMap, registerConfig);
+        assert RegisterVerifier.verify(lir, frameMap);
 
         AssignRegisters assignRegisters = new AssignRegistersImpl(lir, frameMap);
         assignRegisters.execute();
 
         context.observable.fireCompilationEvent("After register asignment", lir);
-        assert LIRVerifier.verify(true, lir, frameMap, registerConfig);
+        assert LIRVerifier.verify(true, lir, frameMap);
     }
 
     private void allocate() {
@@ -404,7 +403,7 @@
             }
         }
 
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = registerConfig.getCategorizedAllocatableRegisters();
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = frameMap.registerConfig.getCategorizedAllocatableRegisters();
         CiRegister[] availableRegs = categorizedRegs.get(variable.flag);
 
         for (CiRegister reg : availableRegs) {
@@ -457,7 +456,7 @@
     }
 
     private boolean checkNoCallerSavedRegister() {
-        for (CiRegister reg : registerConfig.getCallerSaveRegisters()) {
+        for (CiRegister reg : frameMap.registerConfig.getCallerSaveRegisters()) {
             assert curOutRegisterState[reg.number] == null || curOutRegisterState[reg.number] == curInstruction : "caller saved register in use accross call site";
         }
         return true;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LIRVerifier.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/LIRVerifier.java	Wed Jan 11 18:25:56 2012 +0100
@@ -28,7 +28,6 @@
 import java.util.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag;
@@ -41,7 +40,6 @@
 public final class LIRVerifier {
     private final LIR lir;
     private final FrameMap frameMap;
-    private final RiRegisterConfig registerConfig;
 
     private final boolean beforeRegisterAllocation;
 
@@ -60,7 +58,7 @@
     }
 
     private boolean isAllocatableRegister(CiValue value) {
-        return isRegister(value) && registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+        return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
     }
 
     public static boolean verify(final LIRInstruction op) {
@@ -74,18 +72,17 @@
         return true;
     }
 
-    public static boolean verify(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) {
-        LIRVerifier verifier = new LIRVerifier(beforeRegisterAllocation, lir, frameMap, registerConfig);
+    public static boolean verify(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
+        LIRVerifier verifier = new LIRVerifier(beforeRegisterAllocation, lir, frameMap);
         verifier.verify();
         return true;
     }
 
 
-    private LIRVerifier(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) {
+    private LIRVerifier(boolean beforeRegisterAllocation, LIR lir, FrameMap frameMap) {
         this.beforeRegisterAllocation = beforeRegisterAllocation;
         this.lir = lir;
         this.frameMap = frameMap;
-        this.registerConfig = registerConfig;
         this.blockLiveOut = new BitSet[lir.linearScanOrder().size()];
         this.variableDefinitions = new Object[lir.numVariables()];
     }
@@ -120,7 +117,7 @@
 
                 op.forEachInput(useProc);
                 if (op.hasCall()) {
-                    for (CiRegister register : registerConfig.getCallerSaveRegisters()) {
+                    for (CiRegister register : frameMap.registerConfig.getCallerSaveRegisters()) {
                         curRegistersLive[register.number] = null;
                     }
                 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/alloc/util/RegisterVerifier.java	Wed Jan 11 18:25:56 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -22,12 +22,12 @@
  */
 package com.oracle.max.graal.alloc.util;
 
+import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.max.graal.alloc.util.ValueUtil.*;
 
 import java.util.*;
 
 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.compiler.lir.*;
@@ -36,7 +36,6 @@
 
 public final class RegisterVerifier {
     private final FrameMap frameMap;
-    private final RiRegisterConfig registerConfig;
 
     /**
      * All blocks that must be processed.
@@ -70,16 +69,15 @@
         return new HashMap<>(inputState);
     }
 
-    public static boolean verify(LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) {
-        RegisterVerifier verifier = new RegisterVerifier(lir, frameMap, registerConfig);
+    public static boolean verify(LIR lir, FrameMap frameMap) {
+        RegisterVerifier verifier = new RegisterVerifier(lir, frameMap);
         verifier.verify(lir.startBlock());
         return true;
     }
 
     @SuppressWarnings("unchecked")
-    private RegisterVerifier(LIR lir, FrameMap frameMap, RiRegisterConfig registerConfig) {
+    private RegisterVerifier(LIR lir, FrameMap frameMap) {
         this.frameMap = frameMap;
-        this.registerConfig = registerConfig;
         this.workList = new LinkedList<>();
         this.blockStates = new Map[lir.linearScanOrder().size()];
     }
@@ -162,7 +160,7 @@
         Iterator<Object> iter = curInputState.keySet().iterator();
         while (iter.hasNext()) {
             Object value1 = iter.next();
-            if (value1 instanceof CiRegister && registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) {
+            if (value1 instanceof CiRegister && frameMap.registerConfig.getAttributesMap()[((CiRegister) value1).number].isCallerSave) {
                 assert trace("    remove caller save register %s", value1);
                 iter.remove();
             }
@@ -187,7 +185,7 @@
     }
 
     private boolean isIgnoredRegister(CiValue value) {
-        return isRegister(value) && !registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
+        return isRegister(value) && !frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable;
     }
 
     private CiValue use(CiValue value) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java	Wed Jan 11 18:25:25 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,402 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.max.graal.compiler;
-
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiCompiler.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.*;
-import com.oracle.max.criutils.*;
-import com.oracle.max.graal.alloc.simple.*;
-import com.oracle.max.graal.compiler.alloc.*;
-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.graph.*;
-import com.oracle.max.graal.nodes.*;
-import com.oracle.max.graal.nodes.virtual.*;
-
-/**
- * This class encapsulates global information about the compilation of a particular method,
- * including a reference to the runtime, statistics about the compiled code, etc.
- */
-public final class GraalCompilation {
-    public final GraalCompiler compiler;
-    public final RiResolvedMethod method;
-    public final RiRegisterConfig registerConfig;
-    public final CiStatistics stats;
-    public final FrameState placeholderState;
-
-    public final StructuredGraph graph;
-    public final CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null;
-    public NodeMap<CiValue> nodeOperands;
-
-    private FrameMap frameMap;
-
-    private LIR lir;
-
-    /**
-     * Creates a new compilation for the specified method and runtime.
-     *
-     * @param context the compilation context
-     * @param compiler the compiler
-     * @param method the method to be compiled or {@code null} if generating code for a stub
-     * @param graph the initial graph
-     * @param osrBCI the bytecode index for on-stack replacement, if requested
-     * @param stats externally supplied statistics object to be used if not {@code null}
-     * @param debugInfoLevel TODO
-     */
-    public GraalCompilation(GraalContext context, GraalCompiler compiler, RiResolvedMethod method, StructuredGraph graph, int osrBCI, CiStatistics stats, DebugInfoLevel debugInfoLevel) {
-        if (osrBCI != -1) {
-            throw new CiBailout("No OSR supported");
-        }
-        this.compiler = compiler;
-        this.graph = graph;
-        this.method = method;
-        this.stats = stats == null ? new CiStatistics() : stats;
-        this.registerConfig = method == null ? compiler.compilerStubRegisterConfig : compiler.runtime.getRegisterConfig(method);
-        this.placeholderState = debugInfoLevel == DebugInfoLevel.REF_MAPS ? new FrameState(method, 0, 0, 0, false) : null;
-
-        if (context().isObserved() && method != null) {
-            context().observable.fireCompilationStarted(this);
-        }
-    }
-
-    public void close() {
-        // TODO(tw): Check if we can delete this method.
-    }
-
-    public LIR lir() {
-        return lir;
-    }
-
-    public CiValue operand(ValueNode valueNode) {
-        if (nodeOperands == null) {
-            return null;
-        }
-        return nodeOperands.get(valueNode);
-    }
-
-    public void setOperand(ValueNode valueNode, CiValue operand) {
-        assert operand(valueNode) == null : "operand cannot be set twice";
-        assert operand != null && isLegal(operand) : "operand must be legal";
-        assert operand.kind.stackKind() == valueNode.kind();
-        assert !(valueNode instanceof VirtualObjectNode);
-        nodeOperands.set(valueNode, operand);
-    }
-
-    /**
-     * Converts this compilation to a string.
-     * @return a string representation of this compilation
-     */
-    @Override
-    public String toString() {
-        return "compile: " + method;
-    }
-
-    /**
-     * Returns the frame map of this compilation.
-     * @return the frame map
-     */
-    public FrameMap frameMap() {
-        return frameMap;
-    }
-
-    private TargetMethodAssembler createAssembler() {
-        AbstractAssembler masm = compiler.backend.newAssembler(registerConfig);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(this, masm);
-        tasm.setFrameSize(frameMap.frameSize());
-        tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea());
-        return tasm;
-    }
-
-    public CiTargetMethod compile(PhasePlan plan) {
-        CiTargetMethod targetMethod;
-        try {
-            try {
-                emitHIR(plan);
-                emitLIR(compiler.xir);
-                targetMethod = emitCode();
-
-                if (GraalOptions.Meter) {
-                    context().metrics.BytecodesCompiled += method.codeSize();
-                }
-            } catch (CiBailout bailout) {
-                throw bailout;
-            } catch (GraalInternalError e) {
-                throw e.addContext("method", CiUtil.format("%H.%n(%p):%r", method));
-            } catch (Throwable t) {
-                throw new RuntimeException("Exception while compiling: " + method, t);
-            }
-        } catch (GraalInternalError error) {
-            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 {
-            if (context().isObserved()) {
-                context().observable.fireCompilationFinished(this);
-            }
-        }
-
-        return targetMethod;
-    }
-
-    /**
-     * Builds the graph, optimizes it.
-     */
-    public void emitHIR(PhasePlan plan) {
-        try {
-            context().timers.startScope("HIR");
-
-            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);
-                }
-            }
-
-            new PhiStampPhase().apply(graph);
-
-            if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) {
-                new ComputeProbabilityPhase().apply(graph, context());
-            }
-
-            if (GraalOptions.Intrinsify) {
-                new IntrinsificationPhase(compiler.runtime).apply(graph, context());
-            }
-
-            if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
-                new InliningPhase(compiler.target, compiler.runtime, null, assumptions, plan).apply(graph, context());
-                new DeadCodeEliminationPhase().apply(graph, context());
-                new PhiStampPhase().apply(graph);
-            }
-
-            if (GraalOptions.OptCanonicalizer) {
-                new CanonicalizerPhase(compiler.target, compiler.runtime, assumptions).apply(graph, context());
-            }
-
-            plan.runPhases(PhasePosition.HIGH_LEVEL, graph, context());
-
-            if (GraalOptions.OptLoops) {
-                graph.mark();
-                new FindInductionVariablesPhase().apply(graph, context());
-                if (GraalOptions.OptCanonicalizer) {
-                    new CanonicalizerPhase(compiler.target, compiler.runtime, true, assumptions).apply(graph, context());
-                }
-                new SafepointPollingEliminationPhase().apply(graph, context());
-            }
-
-            if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) {
-                new EscapeAnalysisPhase(compiler.target, compiler.runtime, assumptions, plan).apply(graph, context());
-                new PhiStampPhase().apply(graph);
-                new CanonicalizerPhase(compiler.target, compiler.runtime, assumptions).apply(graph, context());
-            }
-
-            if (GraalOptions.OptGVN) {
-                new GlobalValueNumberingPhase().apply(graph, context());
-            }
-
-            graph.mark();
-            new LoweringPhase(compiler.runtime).apply(graph, context());
-            new CanonicalizerPhase(compiler.target, compiler.runtime, true, assumptions).apply(graph, context());
-
-            if (GraalOptions.OptLoops) {
-                graph.mark();
-                new RemoveInductionVariablesPhase().apply(graph, context());
-                if (GraalOptions.OptCanonicalizer) {
-                    new CanonicalizerPhase(compiler.target, compiler.runtime, true, assumptions).apply(graph, context());
-                }
-            }
-
-            if (GraalOptions.Lower) {
-                new FloatingReadPhase().apply(graph, context());
-                if (GraalOptions.OptReadElimination) {
-                    new ReadEliminationPhase().apply(graph, context());
-                }
-            }
-            new RemovePlaceholderPhase().apply(graph, context());
-            new DeadCodeEliminationPhase().apply(graph, context());
-
-            plan.runPhases(PhasePosition.MID_LEVEL, graph, context());
-
-            plan.runPhases(PhasePosition.LOW_LEVEL, graph, context());
-
-            IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY);
-            schedule.apply(graph, context());
-            if (stats != null) {
-                stats.loopCount = schedule.loopCount();
-            }
-
-            if (context().isObserved()) {
-                context().observable.fireCompilationEvent("After IdentifyBlocksPhase", this, graph, schedule);
-            }
-
-            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;
-
-            context().timers.startScope("Compute Linear Scan Order");
-            try {
-                ComputeLinearScanOrder clso = new ComputeLinearScanOrder(blocks.size(), stats.loopCount, startBlock);
-                List<LIRBlock> linearScanOrder = clso.linearScanOrder();
-                List<LIRBlock> codeEmittingOrder = clso.codeEmittingOrder();
-
-                int z = 0;
-                for (LIRBlock b : linearScanOrder) {
-                    b.setLinearScanNumber(z++);
-                }
-
-                lir = new LIR(startBlock, linearScanOrder, codeEmittingOrder, valueToBlock);
-
-                if (context().isObserved()) {
-                    context().observable.fireCompilationEvent("After linear scan order", this, graph, lir);
-                }
-            } catch (AssertionError t) {
-                    context().observable.fireCompilationEvent("AssertionError in ComputeLinearScanOrder", CompilationEvent.ERROR, this, graph);
-                throw t;
-            } catch (RuntimeException t) {
-                    context().observable.fireCompilationEvent("RuntimeException in ComputeLinearScanOrder", CompilationEvent.ERROR, this, graph);
-                throw t;
-            } finally {
-                context().timers.endScope();
-            }
-        } finally {
-            context().timers.endScope();
-        }
-    }
-
-    public void initFrameMap() {
-        frameMap = this.compiler.backend.newFrameMap(this);
-    }
-
-    private void emitLIR(RiXirGenerator xir) {
-        context().timers.startScope("LIR");
-        try {
-            if (GraalOptions.GenLIR) {
-                context().timers.startScope("Create LIR");
-                nodeOperands = graph.createNodeMap();
-                LIRGenerator lirGenerator = null;
-                try {
-                    initFrameMap();
-
-                    lirGenerator = compiler.backend.newLIRGenerator(this, 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();
-                }
-
-                if (context().isObserved()) {
-                    context().observable.fireCompilationEvent("After LIR generation", this, graph, lir);
-                }
-                if (GraalOptions.PrintLIR && !TTY.isSuppressed()) {
-                    LIR.printLIR(lir.linearScanOrder());
-                }
-
-                if (GraalOptions.AllocSSA) {
-                    new SpillAllAllocator(context(), lir, this, registerConfig).execute();
-                } else {
-                    new LinearScan(this, lir, lirGenerator, frameMap()).allocate();
-                }
-            }
-        } catch (Error e) {
-            if (context().isObserved() && GraalOptions.PlotOnError) {
-                context().observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, this, graph);
-            }
-            throw e;
-        } catch (RuntimeException e) {
-            if (context().isObserved() && GraalOptions.PlotOnError) {
-                context().observable.fireCompilationEvent(e.getClass().getSimpleName() + " in emitLIR", CompilationEvent.ERROR, this, graph);
-            }
-            throw e;
-        } finally {
-            context().timers.endScope();
-        }
-    }
-
-    private CiTargetMethod emitCode() {
-        if (GraalOptions.GenLIR && GraalOptions.GenCode) {
-            context().timers.startScope("Create Code");
-            try {
-                TargetMethodAssembler tasm = createAssembler();
-                lir.emitCode(tasm);
-
-                CiTargetMethod targetMethod = tasm.finishTargetMethod(method, compiler.runtime, false);
-                if (assumptions != null && !assumptions.isEmpty()) {
-                    targetMethod.setAssumptions(assumptions);
-                }
-
-                if (context().isObserved()) {
-                    context().observable.fireCompilationEvent("After code generation", this, lir, targetMethod);
-                }
-                return targetMethod;
-            } finally {
-                context().timers.endScope();
-            }
-        }
-
-        return null;
-    }
-
-    private GraalContext context() {
-        return compiler.context;
-    }
-
-    public void printGraph(String phase, Graph printedGraph) {
-        if (context().isObserved()) {
-            context().observable.fireCompilationEvent(phase, this, printedGraph);
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java	Wed Jan 11 18:25:56 2012 +0100
@@ -24,20 +24,27 @@
 
 import java.util.*;
 
+import com.oracle.max.asm.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.cri.xir.*;
 import com.oracle.max.criutils.*;
+import com.oracle.max.graal.alloc.simple.*;
+import com.oracle.max.graal.compiler.alloc.*;
+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.stub.*;
+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.graph.*;
 import com.oracle.max.graal.nodes.*;
 
 public class GraalCompiler {
 
-    public final Map<Object, CompilerStub> stubs = new HashMap<>();
-
     public final GraalContext context;
 
     /**
@@ -60,27 +67,18 @@
      */
     public final Backend backend;
 
-    public final RiRegisterConfig compilerStubRegisterConfig;
-
-    public GraalCompiler(GraalContext context, GraalRuntime runtime, CiTarget target, RiXirGenerator xirGen, RiRegisterConfig compilerStubRegisterConfig) {
+    public GraalCompiler(GraalContext context, GraalRuntime runtime, CiTarget target, Backend backend, RiXirGenerator xirGen) {
         this.context = context;
         this.runtime = runtime;
         this.target = target;
         this.xir = xirGen;
-        this.compilerStubRegisterConfig = compilerStubRegisterConfig;
-        this.backend = Backend.create(target.arch, this);
-        init();
+        this.backend = backend;
     }
 
-    public CiTargetMethod compileMethod(RiResolvedMethod method, int osrBCI, CiStatistics stats, CiCompiler.DebugInfoLevel debugInfoLevel) {
-        return compileMethod(method, osrBCI, stats, debugInfoLevel, PhasePlan.DEFAULT);
-    }
-
-    public CiTargetMethod compileMethod(RiResolvedMethod method, int osrBCI, CiStatistics stats, CiCompiler.DebugInfoLevel debugInfoLevel, PhasePlan plan) {
-        return compileMethod(method, new StructuredGraph(method), osrBCI, stats, debugInfoLevel, plan);
-    }
-
-    public CiTargetMethod compileMethod(RiResolvedMethod method, StructuredGraph graph, int osrBCI, CiStatistics stats, CiCompiler.DebugInfoLevel debugInfoLevel, PhasePlan plan) {
+    public CiTargetMethod compileMethod(RiResolvedMethod method, int osrBCI, PhasePlan plan) {
+        if (osrBCI != -1) {
+            throw new CiBailout("No OSR supported");
+        }
         context.timers.startScope(getClass());
         try {
             long startTime = 0;
@@ -94,13 +92,38 @@
                                 method.signature().asString()));
                 startTime = System.nanoTime();
             }
+            TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
 
+            StructuredGraph graph = new StructuredGraph(method);
             CiTargetMethod result = null;
-            TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, method);
-            GraalCompilation compilation = new GraalCompilation(context, this, method, graph, osrBCI, stats, debugInfoLevel);
+            context.observable.fireCompilationStarted(runtime, target, method);
             try {
-                result = compilation.compile(plan);
+                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();
+                    }
+                } catch (CiBailout bailout) {
+                    throw bailout;
+                } 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;
@@ -111,7 +134,7 @@
                                     "",
                                     time / 10,
                                     time % 10,
-                                    compilation.graph.getNodeCount(),
+                                    graph.getNodeCount(),
                                     (result != null ? result.targetCodeSize() : -1)));
                 }
             }
@@ -122,50 +145,222 @@
         }
     }
 
-    private void init() {
-        final List<XirTemplate> xirTemplateStubs = xir.makeTemplates(backend.newXirAssembler());
+    /**
+     * Builds the graph, optimizes it.
+     */
+    public LIR emitHIR(StructuredGraph graph, CiAssumptions assumptions, PhasePlan plan) {
+        try {
+            context.timers.startScope("HIR");
 
-        if (xirTemplateStubs != null) {
-            for (XirTemplate template : xirTemplateStubs) {
-                TTY.Filter filter = new TTY.Filter(GraalOptions.PrintFilter, template.name);
+            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);
+                }
+            }
+
+            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.Inline && !plan.isPhaseDisabled(InliningPhase.class)) {
+                new InliningPhase(target, runtime, null, assumptions, plan).apply(graph, context);
+                new DeadCodeEliminationPhase().apply(graph, context);
+                new PhiStampPhase().apply(graph);
+            }
+
+            if (GraalOptions.OptCanonicalizer) {
+                new CanonicalizerPhase(target, runtime, assumptions).apply(graph, context);
+            }
+
+            plan.runPhases(PhasePosition.HIGH_LEVEL, graph, context);
+
+            if (GraalOptions.OptLoops) {
+                graph.mark();
+                new FindInductionVariablesPhase().apply(graph, context);
+                if (GraalOptions.OptCanonicalizer) {
+                    new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context);
+                }
+                new SafepointPollingEliminationPhase().apply(graph, context);
+            }
+
+            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.OptGVN) {
+                new GlobalValueNumberingPhase().apply(graph, context);
+            }
+
+            graph.mark();
+            new LoweringPhase(runtime).apply(graph, context);
+            new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context);
+
+            if (GraalOptions.OptLoops) {
+                graph.mark();
+                new RemoveInductionVariablesPhase().apply(graph, context);
+                if (GraalOptions.OptCanonicalizer) {
+                    new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context);
+                }
+            }
+
+            if (GraalOptions.Lower) {
+                new FloatingReadPhase().apply(graph, context);
+                if (GraalOptions.OptReadElimination) {
+                    new ReadEliminationPhase().apply(graph, context);
+                }
+            }
+            new RemovePlaceholderPhase().apply(graph, context);
+            new DeadCodeEliminationPhase().apply(graph, context);
+
+            plan.runPhases(PhasePosition.MID_LEVEL, graph, context);
+
+            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);
+            }
+
+            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;
+
+            context.timers.startScope("Compute Linear Scan Order");
+            try {
+                ComputeLinearScanOrder clso = new ComputeLinearScanOrder(blocks.size(), schedule.loopCount(), startBlock);
+                List<LIRBlock> linearScanOrder = clso.linearScanOrder();
+                List<LIRBlock> codeEmittingOrder = clso.codeEmittingOrder();
+
+                int z = 0;
+                for (LIRBlock b : linearScanOrder) {
+                    b.setLinearScanNumber(z++);
+                }
+
+                LIR lir = new LIR(startBlock, linearScanOrder, codeEmittingOrder, valueToBlock, schedule.loopCount());
+
+                if (context.isObserved()) {
+                    context.observable.fireCompilationEvent("After linear scan order", graph, lir);
+                }
+                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 {
-                    stubs.put(template, backend.emit(context, template));
+                    frameMap = backend.newFrameMap(runtime.getRegisterConfig(method));
+
+                    lirGenerator = backend.newLIRGenerator(context, 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 {
-                    filter.remove();
+                    context.timers.endScope();
                 }
+
+                if (context.isObserved()) {
+                    context.observable.fireCompilationEvent("After LIR generation", graph, lir);
+                }
+                if (GraalOptions.PrintLIR && !TTY.isSuppressed()) {
+                    LIR.printLIR(lir.linearScanOrder());
+                }
+
+                if (GraalOptions.AllocSSA) {
+                    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);
+            }
+            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();
+        }
+    }
+
+    private TargetMethodAssembler createAssembler(FrameMap frameMap, LIR lir) {
+        AbstractAssembler masm = backend.newAssembler(frameMap.registerConfig);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(context, 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);
+
+                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();
             }
         }
 
-        for (CompilerStub.Id id : CompilerStub.Id.values()) {
-            TTY.Filter suppressor = new TTY.Filter(GraalOptions.PrintFilter, id);
-            try {
-                stubs.put(id, backend.emit(context, id));
-            } finally {
-                suppressor.remove();
-            }
-        }
-    }
-
-    public CompilerStub lookupStub(CompilerStub.Id id) {
-        CompilerStub stub = stubs.get(id);
-        assert stub != null : "no stub for global stub id: " + id;
-        return stub;
-    }
-
-    public CompilerStub lookupStub(XirTemplate template) {
-        CompilerStub stub = stubs.get(template);
-        assert stub != null : "no stub for XirTemplate: " + template;
-        return stub;
-    }
-
-    public CompilerStub lookupStub(CiRuntimeCall runtimeCall) {
-        CompilerStub stub = stubs.get(runtimeCall);
-        if (stub == null) {
-            stub = backend.emit(context, runtimeCall);
-            stubs.put(runtimeCall, stub);
-        }
-
-        assert stub != null : "could not find global stub for runtime call: " + runtimeCall;
-        return stub;
+        return null;
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java	Wed Jan 11 18:25:56 2012 +0100
@@ -74,6 +74,45 @@
     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() {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/IntervalWalker.java	Wed Jan 11 18:25:56 2012 +0100
@@ -32,7 +32,6 @@
  */
 public class IntervalWalker {
 
-    protected final GraalCompilation compilation;
     protected final LinearScan allocator;
 
     /**
@@ -91,7 +90,6 @@
      * @param unhandledAny the list of unhandled {@linkplain RegisterBinding#Any non-fixed} intervals
      */
     IntervalWalker(LinearScan allocator, Interval unhandledFixed, Interval unhandledAny) {
-        this.compilation = allocator.compilation;
         this.allocator = allocator;
 
         unhandledLists = new RegisterBindingLists(unhandledFixed, unhandledAny);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java	Wed Jan 11 18:25:56 2012 +0100
@@ -37,9 +37,12 @@
 import com.oracle.max.graal.compiler.alloc.Interval.SpillState;
 import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.lir.LIRInstruction.*;
+import com.oracle.max.graal.compiler.lir.LIRInstruction.OperandFlag;
+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.graph.*;
+import com.oracle.max.graal.nodes.*;
 
 /**
  * An implementation of the linear scan register allocator algorithm described
@@ -49,7 +52,8 @@
 public final class LinearScan {
 
     final GraalContext context;
-    final GraalCompilation compilation;
+    final CiTarget target;
+    final RiMethod method;
     final LIR ir;
     final LIRGenerator gen;
     final FrameMap frameMap;
@@ -115,17 +119,21 @@
      */
     private final int firstVariableNumber;
 
+    private final StructuredGraph graph;
 
-    public LinearScan(GraalCompilation compilation, LIR ir, LIRGenerator gen, FrameMap frameMap) {
-        this.context = compilation.compiler.context;
-        this.compilation = compilation;
+
+    public LinearScan(GraalContext context, CiTarget target, RiResolvedMethod method, StructuredGraph graph, LIR ir, LIRGenerator gen, FrameMap frameMap) {
+        this.context = context;
+        this.target = target;
+        this.method = method;
+        this.graph = graph;
         this.ir = ir;
         this.gen = gen;
         this.frameMap = frameMap;
         this.sortedBlocks = ir.linearScanOrder().toArray(new LIRBlock[ir.linearScanOrder().size()]);
-        this.registerAttributes = compilation.registerConfig.getAttributesMap();
+        this.registerAttributes = frameMap.registerConfig.getAttributesMap();
 
-        this.registers = compilation.compiler.target.arch.registers;
+        this.registers = target.arch.registers;
         this.firstVariableNumber = registers.length;
         this.variables = new ArrayList<>(ir.numVariables() * 3 / 2);
     }
@@ -280,7 +288,7 @@
     }
 
     int numLoops() {
-        return compilation.stats.loopCount;
+        return ir.loopCount();
     }
 
     boolean isIntervalInLoop(int interval, int loop) {
@@ -814,7 +822,7 @@
     }
 
     private void reportFailure(int numBlocks) {
-        TTY.println(compilation.method.toString());
+        TTY.println(method.toString());
         TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)");
         TTY.print("affected registers:");
         TTY.println(ir.startBlock().liveIn.toString());
@@ -1031,15 +1039,15 @@
         }
     }
 
-    void addRegisterHint(final LIRInstruction op, final CiValue target, OperandMode mode, EnumSet<OperandFlag> flags) {
-        if (flags.contains(OperandFlag.RegisterHint) && isVariableOrRegister(target)) {
+    void addRegisterHint(final LIRInstruction op, final CiValue targetValue, OperandMode mode, EnumSet<OperandFlag> flags) {
+        if (flags.contains(OperandFlag.RegisterHint) && isVariableOrRegister(targetValue)) {
 
-            op.forEachRegisterHint(target, mode, new ValueProcedure() {
+            op.forEachRegisterHint(targetValue, mode, new ValueProcedure() {
                 @Override
                 protected CiValue doValue(CiValue registerHint) {
                     if (isVariableOrRegister(registerHint)) {
                         Interval from = intervalFor(registerHint);
-                        Interval to = intervalFor(target);
+                        Interval to = intervalFor(targetValue);
                         if (from != null && to != null) {
                             to.setLocationHint(from);
                             if (GraalOptions.TraceLinearScanLevel >= 4) {
@@ -1059,8 +1067,7 @@
         intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY];
 
         // create a list with all caller-save registers (cpu, fpu, xmm)
-        RiRegisterConfig registerConfig = compilation.registerConfig;
-        CiRegister[] callerSaveRegs = registerConfig.getCallerSaveRegisters();
+        CiRegister[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters();
 
         // iterate all blocks in reverse order
         for (int i = blockCount() - 1; i >= 0; i--) {
@@ -1339,7 +1346,7 @@
         notPrecoloredIntervals = result.second;
 
         // allocate cpu registers
-        LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals);
+        LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals, !target.arch.isX86());
         lsw.walk();
         lsw.finishAllocation();
     }
@@ -1542,12 +1549,12 @@
                 }
 
                 case Float: {
-                    assert !compilation.compiler.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
+                    assert !target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
                     break;
                 }
 
                 case Double: {
-                    assert !compilation.compiler.target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
+                    assert !target.arch.isX86() || reg.isFpu() : "not xmm register: " + reg;
                     break;
                 }
 
@@ -1869,7 +1876,7 @@
         }
 
         if (context.isObserved()) {
-            context.observable.fireCompilationEvent(label, compilation, this, Arrays.copyOf(intervals, intervalsSize));
+            context.observable.fireCompilationEvent(label, graph, this, Arrays.copyOf(intervals, intervalsSize));
         }
     }
 
@@ -1882,7 +1889,7 @@
         }
 
         if (context.isObserved()) {
-            context.observable.fireCompilationEvent(label, compilation, hirValid ? compilation.graph : null, compilation.lir());
+            context.observable.fireCompilationEvent(label, hirValid ? graph : null, ir);
         }
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScanWalker.java	Wed Jan 11 18:25:56 2012 +0100
@@ -42,6 +42,8 @@
  */
 final class LinearScanWalker extends IntervalWalker {
 
+    private final boolean hasCalleeSavedRegisters;
+
     private CiRegister[] availableRegs;
 
     private final int[] usePos;
@@ -51,6 +53,7 @@
 
     private MoveResolver moveResolver; // for ordering spill moves
 
+
     // accessors mapped to same functions in class LinearScan
     int blockCount() {
         return allocator.blockCount();
@@ -64,8 +67,9 @@
         return allocator.blockForId(opId);
     }
 
-    LinearScanWalker(LinearScan allocator, Interval unhandledFixedFirst, Interval unhandledAnyFirst) {
+    LinearScanWalker(LinearScan allocator, Interval unhandledFixedFirst, Interval unhandledAnyFirst, boolean hasCalleeSavedRegisters) {
         super(allocator, unhandledFixedFirst, unhandledAnyFirst);
+        this.hasCalleeSavedRegisters = hasCalleeSavedRegisters;
         moveResolver = new MoveResolver(allocator);
         spillIntervals = Util.uncheckedCast(new List[allocator.registers.length]);
         for (int i = 0; i < allocator.registers.length; i++) {
@@ -789,7 +793,7 @@
 
     boolean noAllocationPossible(Interval interval) {
 
-        if (compilation.compiler.target.arch.isX86()) {
+        if (!hasCalleeSavedRegisters) {
             // fast calculation of intervals that can never get a register because the
             // the next instruction is a call that blocks all registers
             // Note: this does not work if callee-saved registers are available (e.g. on Sparc)
@@ -815,7 +819,7 @@
     }
 
     void initVarsForAlloc(Interval interval) {
-        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = allocator.compilation.registerConfig.getCategorizedAllocatableRegisters();
+        EnumMap<RegisterFlag, CiRegister[]> categorizedRegs = allocator.frameMap.registerConfig.getCategorizedAllocatableRegisters();
         availableRegs = categorizedRegs.get(asVariable(interval.operand).flag);
     }
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/MoveResolver.java	Wed Jan 11 18:25:56 2012 +0100
@@ -30,7 +30,6 @@
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.util.*;
 
 /**
  */
@@ -193,7 +192,7 @@
 
     private void insertMove(Interval fromInterval, Interval toInterval) {
         assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval;
-        assert Util.archKindsEqual(fromInterval.kind(), toInterval.kind()) : "move between different types";
+        assert fromInterval.kind() == toInterval.kind() : "move between different types";
         assert insertIdx != -1 : "must setup insert position first";
 
         CiValue fromOpr = fromInterval.operand;
@@ -207,7 +206,7 @@
     }
 
     private void insertMove(CiValue fromOpr, Interval toInterval) {
-        assert Util.archKindsEqual(fromOpr.kind, toInterval.kind()) : "move between different types";
+        assert fromOpr.kind == toInterval.kind() : "move between different types";
         assert insertIdx != -1 : "must setup insert position first";
 
         CiValue toOpr = toInterval.operand;
@@ -331,7 +330,7 @@
         }
 
         assert fromInterval.operand != toInterval.operand : "from and to interval equal: " + fromInterval;
-        assert Util.archKindsEqual(fromInterval.kind(), toInterval.kind());
+        assert fromInterval.kind() == toInterval.kind();
         mappingFrom.add(fromInterval);
         mappingFromOpr.add(CiValue.IllegalValue);
         mappingTo.add(toInterval);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/RegisterVerifier.java	Wed Jan 11 18:25:56 2012 +0100
@@ -42,10 +42,6 @@
     ArrayMap<Interval[]> savedStates; // saved information of previous check
 
     // simplified access to methods of LinearScan
-    GraalCompilation compilation() {
-        return allocator.compilation;
-    }
-
     Interval intervalAt(CiValue operand) {
         return allocator.intervalFor(operand);
     }
@@ -249,7 +245,7 @@
             op.forEachInput(useProc);
             // invalidate all caller save registers at calls
             if (op.hasCall()) {
-                for (CiRegister r : allocator.compilation.registerConfig.getCallerSaveRegisters()) {
+                for (CiRegister r : allocator.frameMap.registerConfig.getCallerSaveRegisters()) {
                     statePut(inputState, r.asValue(), null);
                 }
             }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java	Wed Jan 11 18:25:56 2012 +0100
@@ -32,21 +32,30 @@
 import com.oracle.max.criutils.*;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.lir.*;
+import com.oracle.max.graal.compiler.lir.LIR.SlowPath;
 import com.oracle.max.graal.compiler.util.*;
 
 public class TargetMethodAssembler {
-    public final GraalCompilation compilation;
+
     public final AbstractAssembler asm;
     public final CiTargetMethod targetMethod;
     public final CiTarget target;
+    public final RiRuntime runtime;
+    public final FrameMap frameMap;
+    public final List<SlowPath> slowPaths;
+
     private List<ExceptionInfo> exceptionInfoList;
     private int lastSafepointPos;
+    private final GraalContext context;
 
-    public TargetMethodAssembler(GraalCompilation compilation, AbstractAssembler asm) {
-        this.compilation = compilation;
+    public TargetMethodAssembler(GraalContext context, CiTarget target, RiRuntime runtime, FrameMap frameMap, List<SlowPath> slowPaths, AbstractAssembler asm) {
+        this.context = context;
+        this.target = target;
+        this.runtime = runtime;
+        this.frameMap = frameMap;
+        this.slowPaths = slowPaths;
         this.asm = asm;
         this.targetMethod = new CiTargetMethod();
-        this.target = compilation.compiler.target;
         // 0 is a valid pc for safepoints in template methods
         this.lastSafepointPos = -1;
     }
@@ -63,7 +72,7 @@
         targetMethod.addAnnotation(new CiTargetMethod.CodeComment(asm.codeBuffer.position(), s));
     }
 
-    public CiTargetMethod finishTargetMethod(Object name, RiRuntime runtime, boolean isStub) {
+    public CiTargetMethod finishTargetMethod(Object name, boolean isStub) {
         // Install code, data and frame size
         targetMethod.setTargetCode(asm.codeBuffer.close(false), asm.codeBuffer.position());
 
@@ -76,11 +85,11 @@
         }
 
         if (GraalOptions.Meter) {
-            compilation.compiler.context.metrics.TargetMethods++;
-            compilation.compiler.context.metrics.CodeBytesEmitted += targetMethod.targetCodeSize();
-            compilation.compiler.context.metrics.SafepointsEmitted += targetMethod.safepoints.size();
-            compilation.compiler.context.metrics.DataPatches += targetMethod.dataReferences.size();
-            compilation.compiler.context.metrics.ExceptionHandlersEmitted += targetMethod.exceptionHandlers.size();
+            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();
         }
 
         if (GraalOptions.PrintAssembly && !TTY.isSuppressed() && !isStub) {
@@ -226,10 +235,6 @@
     }
 
     public CiAddress asAddress(CiValue value) {
-        if (isStackSlot(value)) {
-            CiStackSlot slot = (CiStackSlot) value;
-            return new CiAddress(slot.kind, compilation.registerConfig.getFrameRegister().asValue(), compilation.frameMap().offsetForStackSlot(slot));
-        }
-        return (CiAddress) value;
+        return frameMap.asAddress(value);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java	Wed Jan 11 18:25:56 2012 +0100
@@ -26,28 +26,23 @@
 import java.util.Map.Entry;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.gen.LIRGenerator.*;
+import com.oracle.max.graal.compiler.gen.LIRGenerator.LockScope;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.virtual.*;
 
 public class DebugInfoBuilder {
-    public final GraalCompilation compilation;
+    private final NodeMap<CiValue> nodeOperands;
 
-    public DebugInfoBuilder(GraalCompilation compilation) {
-        this.compilation = compilation;
+    public DebugInfoBuilder(NodeMap<CiValue> nodeOperands) {
+        this.nodeOperands = nodeOperands;
     }
 
 
     private HashMap<VirtualObjectNode, CiVirtualObject> virtualObjects = new HashMap<>();
 
     public LIRDebugInfo build(FrameState topState, LockScope locks, List<CiStackSlot> pointerSlots, LabelRef exceptionEdge) {
-        if (compilation.placeholderState != null) {
-            return null;
-        }
-
         assert virtualObjects.size() == 0;
         CiFrame frame = computeFrameForState(topState, locks);
 
@@ -158,7 +153,7 @@
             return ((ConstantNode) value).value;
 
         } else if (value != null) {
-            CiValue operand = compilation.operand(value);
+            CiValue operand = nodeOperands.get(value);
             assert operand != null && operand instanceof Variable || operand instanceof CiConstant;
             return operand;
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java	Wed Jan 11 18:25:56 2012 +0100
@@ -22,12 +22,12 @@
  */
 package com.oracle.max.graal.compiler.gen;
 
-import static com.oracle.max.graal.compiler.lir.StandardOpcode.*;
 import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
 import static com.oracle.max.cri.ci.CiValue.*;
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 import static com.oracle.max.cri.util.MemoryBarriers.*;
 import static com.oracle.max.graal.alloc.util.ValueUtil.*;
+import static com.oracle.max.graal.compiler.lir.StandardOpcode.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -48,7 +48,6 @@
 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.stub.*;
 import com.oracle.max.graal.compiler.util.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
@@ -58,13 +57,21 @@
 import com.oracle.max.graal.nodes.extended.*;
 import com.oracle.max.graal.nodes.java.*;
 import com.oracle.max.graal.nodes.spi.*;
+import com.oracle.max.graal.nodes.virtual.*;
 
 /**
  * This class traverses the HIR instructions and generates LIR instructions from them.
  */
 public abstract class LIRGenerator extends LIRGeneratorTool {
     public final GraalContext context;
-    public final GraalCompilation compilation;
+
+    protected final Graph graph;
+    protected final RiRuntime runtime;
+    protected final CiTarget target;
+    protected final RiResolvedMethod method;
+    protected final FrameMap frameMap;
+    public final NodeMap<CiValue> nodeOperands;
+
     protected final LIR lir;
     protected final XirSupport xirSupport;
     protected final RiXirGenerator xir;
@@ -131,19 +138,24 @@
     private LockScope curLocks;
 
 
-    public LIRGenerator(GraalCompilation compilation, RiXirGenerator xir) {
-        this.context = compilation.compiler.context;
-        this.compilation = compilation;
-        this.lir = compilation.lir();
+    public LIRGenerator(GraalContext context, Graph graph, RiRuntime runtime, CiTarget target, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) {
+        this.context = context;
+        this.graph = graph;
+        this.runtime = runtime;
+        this.target = target;
+        this.frameMap = frameMap;
+        this.method = method;
+        this.nodeOperands = graph.createNodeMap();
+        this.lir = lir;
         this.xir = xir;
         this.xirSupport = new XirSupport();
-        this.debugInfoBuilder = new DebugInfoBuilder(compilation);
+        this.debugInfoBuilder = new DebugInfoBuilder(nodeOperands);
         this.blockLocks = new LockScope[lir.linearScanOrder().size()];
     }
 
     @Override
     public CiTarget target() {
-        return compilation.compiler.target;
+        return target;
     }
 
     private LockScope locksFor(LIRBlock block) {
@@ -161,7 +173,10 @@
      */
     @Override
     public CiValue operand(ValueNode node) {
-        return compilation.operand(node);
+        if (nodeOperands == null) {
+            return null;
+        }
+        return nodeOperands.get(node);
     }
 
     /**
@@ -190,7 +205,11 @@
     public CiValue setResult(ValueNode x, CiValue operand) {
         assert (isVariable(operand) && x.kind() == operand.kind) || (isConstant(operand) && x.kind() == operand.kind.stackKind()) : operand.kind + " for node " + x;
 
-        compilation.setOperand(x, operand);
+        assert operand(x) == null : "operand cannot be set twice";
+        assert operand != null && isLegal(operand) : "operand must be legal";
+        assert operand.kind.stackKind() == x.kind();
+        assert !(x instanceof VirtualObjectNode);
+        nodeOperands.set(x, operand);
         return operand;
     }
 
@@ -254,7 +273,7 @@
         if (kind == CiKind.Void) {
             return IllegalValue;
         }
-        return compilation.registerConfig.getReturnRegister(kind).asValue(kind);
+        return frameMap.registerConfig.getReturnRegister(kind).asValue(kind);
     }
 
 
@@ -405,7 +424,7 @@
         emitNode(instr);
 
         if (GraalOptions.TraceLIRVisit) {
-            TTY.println("Operand for " + instr + " = " + compilation.operand(instr));
+            TTY.println("Operand for " + instr + " = " + operand(instr));
         }
     }
 
@@ -419,7 +438,7 @@
     }
 
     private void emitPrologue() {
-        CiCallingConvention incomingArguments = compilation.registerConfig.getCallingConvention(JavaCallee, CiUtil.signatureToKinds(compilation.method), compilation.compiler.target, false);
+        CiCallingConvention incomingArguments = frameMap.registerConfig.getCallingConvention(JavaCallee, CiUtil.signatureToKinds(method), target, false);
 
         CiValue[] params = new CiValue[incomingArguments.locations.length];
         for (int i = 0; i < params.length; i++) {
@@ -427,12 +446,12 @@
         }
         append(PARAMS.create(params));
 
-        XirSnippet prologue = xir.genPrologue(null, compilation.method);
+        XirSnippet prologue = xir.genPrologue(null, method);
         if (prologue != null) {
             emitXir(prologue, null, null, null, false);
         }
 
-        for (LocalNode local : compilation.graph.getNodes(LocalNode.class)) {
+        for (LocalNode local : graph.getNodes(LocalNode.class)) {
             CiValue param = params[local.index()];
             assert param.kind == local.kind().stackKind();
             setResult(local, emitMove(param));
@@ -440,9 +459,9 @@
     }
 
     private boolean checkStartOperands(Node node, FrameState fs) {
-        if (!Modifier.isNative(compilation.method.accessFlags())) {
+        if (!Modifier.isNative(method.accessFlags())) {
             if (node == ((StructuredGraph) node.graph()).start()) {
-                CiKind[] arguments = CiUtil.signatureToKinds(compilation.method);
+                CiKind[] arguments = CiUtil.signatureToKinds(method);
                 int slot = 0;
                 for (CiKind kind : arguments) {
                     ValueNode arg = fs.localAt(slot);
@@ -476,9 +495,9 @@
 
     @Override
     public void visitMonitorEnter(MonitorEnterNode x) {
-        CiStackSlot lockData = compilation.frameMap().allocateStackBlock(compilation.compiler.runtime.sizeOfLockData(), false);
+        CiStackSlot lockData = frameMap.allocateStackBlock(runtime.sizeOfLockData(), false);
         if (x.eliminated()) {
-            // No code is emitted for elimianted locks, but for proper debug information generation we need to
+            // No code is emitted for eliminated locks, but for proper debug information generation we need to
             // register the monitor and its lock data.
             curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData);
             return;
@@ -490,7 +509,7 @@
         LIRDebugInfo stateBefore = state();
         // The state before the monitor enter is used for null checks, so it must not contain the newly locked object.
         curLocks = new LockScope(curLocks, x.stateAfter().outerFrameState(), x, lockData);
-        // The state after the monitor enter is used for deotpimization, after the montior has blocked, so it must contain the newly locked object.
+        // The state after the monitor enter is used for deoptimization, after the monitor has blocked, so it must contain the newly locked object.
         LIRDebugInfo stateAfter = stateFor(x.stateAfter());
 
         XirSnippet snippet = xir.genMonitorEnter(site(x), obj, lockAddress);
@@ -610,9 +629,9 @@
             operand = resultOperandFor(x.kind());
             emitMove(operand(x.result()), operand);
         }
-        XirSnippet epilogue = xir.genEpilogue(site(x), compilation.method);
+        XirSnippet epilogue = xir.genEpilogue(site(x), method);
         if (epilogue != null) {
-            emitXir(epilogue, x, null, compilation.method, false);
+            emitXir(epilogue, x, null, method, false);
             append(StandardOpcode.RETURN.create(operand));
         }
     }
@@ -697,7 +716,7 @@
         LIRDebugInfo info = state();
         XirArgument clazz = toXirArgument(node.type().getEncoding(Representation.ObjectHub));
         XirSnippet typeCheck = xir.genTypeCheck(site(node), toXirArgument(node.object()), clazz, node.type());
-        emitXir(typeCheck, node, info, compilation.method, false);
+        emitXir(typeCheck, node, info, method, false);
     }
 
 
@@ -834,27 +853,27 @@
     @Override
     public void emitInvoke(Invoke x) {
         MethodCallTargetNode callTarget = x.callTarget();
-        RiMethod target = callTarget.targetMethod();
+        RiMethod targetMethod = callTarget.targetMethod();
 
         XirSnippet snippet = null;
         XirArgument receiver;
         switch (callTarget.invokeKind()) {
             case Static:
-                snippet = xir.genInvokeStatic(site(x.node()), target);
+                snippet = xir.genInvokeStatic(site(x.node()), targetMethod);
                 break;
             case Special:
                 receiver = toXirArgument(callTarget.receiver());
-                snippet = xir.genInvokeSpecial(site(x.node()), receiver, target);
+                snippet = xir.genInvokeSpecial(site(x.node()), receiver, targetMethod);
                 break;
             case Virtual:
                 assert callTarget.receiver().kind() == CiKind.Object : callTarget + ": " + callTarget.targetMethod().toString();
                 receiver = toXirArgument(callTarget.receiver());
-                snippet = xir.genInvokeVirtual(site(x.node()), receiver, target);
+                snippet = xir.genInvokeVirtual(site(x.node()), receiver, targetMethod);
                 break;
             case Interface:
                 assert callTarget.receiver().kind() == CiKind.Object : callTarget;
                 receiver = toXirArgument(callTarget.receiver());
-                snippet = xir.genInvokeInterface(site(x.node()), receiver, target);
+                snippet = xir.genInvokeInterface(site(x.node()), receiver, targetMethod);
                 break;
         }
 
@@ -869,8 +888,8 @@
         CiValue resultOperand = resultOperandFor(x.node().kind());
 
         CiKind[] signature = CiUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind(true));
-        CiCallingConvention cc = compilation.registerConfig.getCallingConvention(JavaCall, signature, target(), false);
-        compilation.frameMap().callsMethod(cc, JavaCall);
+        CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false);
+        frameMap.callsMethod(cc, JavaCall);
         List<CiStackSlot> pointerSlots = new ArrayList<>(2);
         List<CiValue> argList = visitInvokeArguments(cc, callTarget.arguments(), pointerSlots);
 
@@ -886,10 +905,10 @@
         if (destinationAddress instanceof CiConstant) {
             // Direct call
             assert ((CiConstant) destinationAddress).isDefaultValue() : "destination address should be zero";
-            append(StandardOpcode.DIRECT_CALL.create(target, resultOperand, argList, null, callInfo, snippet.marks));
+            append(StandardOpcode.DIRECT_CALL.create(targetMethod, resultOperand, argList, null, callInfo, snippet.marks));
         } else {
             // Indirect call
-            append(StandardOpcode.INDIRECT_CALL.create(target, resultOperand, argList, destinationAddress, callInfo, snippet.marks));
+            append(StandardOpcode.INDIRECT_CALL.create(targetMethod, resultOperand, argList, destinationAddress, callInfo, snippet.marks));
         }
 
         if (isLegal(resultOperand)) {
@@ -949,8 +968,8 @@
         List<CiValue> argumentList;
         if (arguments.length > 0) {
             // move the arguments into the correct location
-            CiCallingConvention cc = compilation.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
-            compilation.frameMap().callsMethod(cc, RuntimeCall);
+            CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
+            frameMap.callsMethod(cc, RuntimeCall);
             assert cc.locations.length == args.length : "argument count mismatch";
             for (int i = 0; i < args.length; i++) {
                 CiValue arg = args[i];
@@ -978,8 +997,8 @@
         // TODO Merge with emitCallToRuntime() method above.
 
         CiValue resultOperand = resultOperandFor(x.kind());
-        CiCallingConvention cc = compilation.registerConfig.getCallingConvention(RuntimeCall, x.call().arguments, target(), false);
-        compilation.frameMap().callsMethod(cc, RuntimeCall);
+        CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, x.call().arguments, target(), false);
+        frameMap.callsMethod(cc, RuntimeCall);
         List<CiStackSlot> pointerSlots = new ArrayList<>(2);
         List<CiValue> argList = visitInvokeArguments(cc, x.arguments(), pointerSlots);
 
@@ -1000,18 +1019,6 @@
         }
     }
 
-    protected CompilerStub stubFor(CompilerStub.Id id) {
-        CompilerStub stub = compilation.compiler.lookupStub(id);
-        compilation.frameMap().usesStub(stub);
-        return stub;
-    }
-
-    protected CompilerStub stubFor(XirTemplate template) {
-        CompilerStub stub = compilation.compiler.lookupStub(template);
-        compilation.frameMap().usesStub(stub);
-        return stub;
-    }
-
     @Override
     public void emitLookupSwitch(LookupSwitchNode x) {
         Variable tag = load(operand(x.value()));
@@ -1204,18 +1211,18 @@
         return variable;
     }
 
-    protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, RiMethod method, boolean setInstructionResult) {
-        return emitXir(snippet, x, info, null, method, setInstructionResult);
+    protected CiValue emitXir(XirSnippet snippet, ValueNode x, LIRDebugInfo info, RiMethod currentMethod, boolean setInstructionResult) {
+        return emitXir(snippet, x, info, null, currentMethod, setInstructionResult);
     }
 
-    protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod method, boolean setInstructionResult) {
+    protected CiValue emitXir(XirSnippet snippet, ValueNode instruction, LIRDebugInfo info, LIRDebugInfo infoAfter, RiMethod currentMethod, boolean setInstructionResult) {
         if (GraalOptions.PrintXirTemplates) {
             TTY.println("Emit XIR template " + snippet.template.name);
         }
 
         final CiValue[] operandsArray = new CiValue[snippet.template.variableCount];
 
-        compilation.frameMap().reserveOutgoing(snippet.template.outgoingStackSize);
+        frameMap.reserveOutgoing(snippet.template.outgoingStackSize);
 
         XirOperand resultOperand = snippet.template.resultOperand;
 
@@ -1246,11 +1253,6 @@
             }
         }
 
-        for (XirTemplate calleeTemplate : snippet.template.calleeTemplates) {
-            // TODO Save these for use in AMD64LIRAssembler
-            stubFor(calleeTemplate);
-        }
-
         for (XirConstant c : snippet.template.constants) {
             assert operandsArray[c.index] == null;
             operandsArray[c.index] = c.value;
@@ -1298,7 +1300,7 @@
         }
 
         if (setInstructionResult && isLegal(allocatedResultOperand)) {
-            CiValue operand = compilation.operand(instruction);
+            CiValue operand = operand(instruction);
             if (operand == null) {
                 setResult(instruction, allocatedResultOperand);
             } else {
@@ -1313,7 +1315,7 @@
             append(StandardOpcode.XIR.create(snippet, operandsArray, allocatedResultOperand,
                     inputOperandArray, tempOperandArray, inputOperandIndicesArray, tempOperandIndicesArray,
                     (allocatedResultOperand == IllegalValue) ? -1 : resultOperand.index,
-                    info, infoAfter, method));
+                    info, infoAfter, currentMethod));
             if (GraalOptions.Meter) {
                 context.metrics.LIRXIRInstructions++;
             }
@@ -1332,8 +1334,8 @@
         List<CiValue> argumentList;
         if (arguments.length > 0) {
             // move the arguments into the correct location
-            CiCallingConvention cc = compilation.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
-            compilation.frameMap().callsMethod(cc, RuntimeCall);
+            CiCallingConvention cc = frameMap.registerConfig.getCallingConvention(RuntimeCall, arguments, target(), false);
+            frameMap.callsMethod(cc, RuntimeCall);
             assert cc.locations.length == args.length : "argument count mismatch";
             for (int i = 0; i < args.length; i++) {
                 CiValue arg = args[i];
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/FrameMap.java	Wed Jan 11 18:25:56 2012 +0100
@@ -22,14 +22,13 @@
  */
 package com.oracle.max.graal.compiler.lir;
 
-import static com.oracle.max.graal.alloc.util.ValueUtil.*;
+import static com.oracle.max.cri.ci.CiValueUtil.*;
 
 import java.util.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiCallingConvention.*;
+import com.oracle.max.cri.ci.CiCallingConvention.Type;
 import com.oracle.max.cri.ri.*;
-import com.oracle.max.graal.compiler.stub.*;
 import com.oracle.max.graal.compiler.util.*;
 
 /**
@@ -213,18 +212,6 @@
     }
 
     /**
-     * Informs the frame map that the compiled code uses a particular compiler stub, which
-     * may need stack space for outgoing arguments.
-     * @param stub The compiler stub.
-     */
-    public void usesStub(CompilerStub stub) {
-        // TODO look at the actual stack slot offsets?
-        int argsSize = stub.inArgs.length * target.wordSize;
-        int resultSize = stub.resultKind.isVoid() ? 0 : target.wordSize;
-        reserveOutgoing(Math.max(argsSize, resultSize));
-    }
-
-    /**
      * Reserves space for stack-based outgoing arguments.
      * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments.
      */
@@ -352,4 +339,12 @@
             }
         }
     }
+
+    public CiAddress asAddress(CiValue value) {
+        if (isStackSlot(value)) {
+            CiStackSlot slot = (CiStackSlot) value;
+            return new CiAddress(slot.kind, registerConfig.getFrameRegister().asValue(), offsetForStackSlot(slot));
+        }
+        return (CiAddress) value;
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/lir/LIR.java	Wed Jan 11 18:25:56 2012 +0100
@@ -65,6 +65,8 @@
 
     private int numVariables;
 
+    private final int loopCount;
+
 
     public interface SlowPath {
         void emitCode(TargetMethodAssembler tasm);
@@ -72,13 +74,15 @@
 
     /**
      * Creates a new LIR instance for the specified compilation.
+     * @param loopCount number of loops
      * @param compilation the compilation
      */
-    public LIR(LIRBlock startBlock, List<LIRBlock> linearScanOrder, List<LIRBlock> codeEmittingOrder, NodeMap<LIRBlock> valueToBlock) {
+    public LIR(LIRBlock startBlock, List<LIRBlock> linearScanOrder, List<LIRBlock> codeEmittingOrder, NodeMap<LIRBlock> valueToBlock, int loopCount) {
         this.codeEmittingOrder = codeEmittingOrder;
         this.linearScanOrder = linearScanOrder;
         this.startBlock = startBlock;
         this.valueToBlock = valueToBlock;
+        this.loopCount = loopCount;
 
         slowPaths = new ArrayList<>();
         deoptimizationStubs = new ArrayList<>();
@@ -104,6 +108,10 @@
         return valueToBlock;
     }
 
+    public int loopCount() {
+        return loopCount;
+    }
+
     public int numVariables() {
         return numVariables;
     }
@@ -183,7 +191,7 @@
     private void printAssembly(TargetMethodAssembler tasm) {
         byte[] currentBytes = tasm.asm.codeBuffer.copyData(lastDecodeStart, tasm.asm.codeBuffer.position());
         if (currentBytes.length > 0) {
-            String disasm = tasm.compilation.compiler.runtime.disassemble(currentBytes, lastDecodeStart);
+            String disasm = tasm.runtime.disassemble(currentBytes, lastDecodeStart);
             if (disasm.length() != 0) {
                 TTY.println(disasm);
             } else {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationEvent.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationEvent.java	Wed Jan 11 18:25:56 2012 +0100
@@ -22,6 +22,8 @@
  */
 package com.oracle.max.graal.compiler.observer;
 
+import java.util.*;
+
 /**
  * An event that occurred during compilation. Instances of this class provide information about the event and the state
  * of the compilation when the event was raised. Depending on the state of the compiler and the compilation phase,
@@ -36,16 +38,17 @@
     public static final Object ERROR = new Object() {};
 
     public final String label;
-    private Object[] debugObjects;
+    private List<Object> debugObjects;
 
-    protected CompilationEvent(String label, Object...debugObjects) {
+    protected CompilationEvent(String label, ArrayList<Object> debugObjects) {
         this.label = label;
         this.debugObjects = debugObjects;
     }
 
     @SuppressWarnings("unchecked")
     public <T> T debugObject(Class<T> type) {
-        for (Object o : debugObjects) {
+        for (ListIterator<Object> iter = debugObjects.listIterator(debugObjects.size()); iter.hasPrevious();) {
+            Object o = iter.previous();
             if (type.isInstance(o)) {
                 return (T) o;
             }
@@ -54,7 +57,8 @@
     }
 
     public boolean hasDebugObject(Object search) {
-        for (Object o : debugObjects) {
+        for (ListIterator<Object> iter = debugObjects.listIterator(debugObjects.size()); iter.hasPrevious();) {
+            Object o = iter.previous();
             if (o == search) {
                 return true;
             }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationObserver.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/CompilationObserver.java	Wed Jan 11 18:25:56 2012 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.max.graal.compiler.observer;
 
-import com.oracle.max.graal.compiler.*;
 
 /**
  * Interface for classes that observe events of an {@link ObservableCompiler}.
@@ -31,11 +30,11 @@
 
     /**
      * Called when compilation of a method has started. This is always the first event raised for a particular
-     * {@link GraalCompilation}.
+     * method compilation.
      *
-     * @param compilation Current state of the compilation.
+     * @param event Information associated with the event and current state of the compilation.
      */
-    void compilationStarted(GraalCompilation compilation);
+    void compilationStarted(CompilationEvent event);
 
     /**
      * Called when an event has occurred, for example that a particular phase in the compilation has been entered.
@@ -46,10 +45,10 @@
 
     /**
      * Called when compilation of a method has completed (successfully or not). This is always the last event raised for
-     * a particular {@link GraalCompilation}.
+     * a particular method compilation.
      *
-     * @param compilation Current state of the compilation.
+     * @param event Information associated with the event and current state of the compilation.
      */
-    void compilationFinished(GraalCompilation compilation);
+    void compilationFinished(CompilationEvent event);
 
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/ObservableContext.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/observer/ObservableContext.java	Wed Jan 11 18:25:56 2012 +0100
@@ -24,8 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.max.graal.compiler.*;
-
 /**
  * Base class for compilers that notify subscribed {@link CompilationObserver CompilationObservers} of
  * {@link CompilationEvent CompilationEvents} that occur during their compilations.
@@ -34,6 +32,20 @@
 
     private List<CompilationObserver> observers;
 
+    private ThreadLocal<StringBuilder> scopeName = new ThreadLocal<StringBuilder>() {
+        @Override
+        protected StringBuilder initialValue() {
+            return new StringBuilder();
+        }
+    };
+
+    private ThreadLocal<ArrayList<Object>> debugObjects = new ThreadLocal<ArrayList<Object>>() {
+        @Override
+        protected ArrayList<Object> initialValue() {
+            return new ArrayList<>();
+        }
+    };
+
     /**
      * @return {@code true} if one or more observers are subscribed to receive notifications from this compiler,
      *         {@code false} otherwise.
@@ -56,28 +68,36 @@
         observers.add(observer);
     }
 
-    public void fireCompilationStarted(GraalCompilation compilation) {
+    public void fireCompilationStarted(Object... additionalDebugObjects) {
         if (isObserved()) {
+            addDebugObjects(null, additionalDebugObjects);
+            CompilationEvent event = new CompilationEvent("started", debugObjects.get());
             for (CompilationObserver observer : observers) {
-                observer.compilationStarted(compilation);
+                observer.compilationStarted(event);
             }
+            removeDebugObjects(null, additionalDebugObjects);
         }
     }
 
-    public void fireCompilationEvent(String label, Object...debugObjects) {
+    public void fireCompilationEvent(String label, Object... additionalDebugObjects) {
         if (isObserved()) {
-            CompilationEvent event = new CompilationEvent(label, debugObjects);
+            addDebugObjects(null, additionalDebugObjects);
+            CompilationEvent event = new CompilationEvent(label, debugObjects.get());
             for (CompilationObserver observer : observers) {
                 observer.compilationEvent(event);
             }
+            removeDebugObjects(null, additionalDebugObjects);
         }
     }
 
-    public void fireCompilationFinished(GraalCompilation compilation) {
+    public void fireCompilationFinished(Object... additionalDebugObjects) {
         if (isObserved()) {
+            addDebugObjects(null, additionalDebugObjects);
+            CompilationEvent event = new CompilationEvent("finished", debugObjects.get());
             for (CompilationObserver observer : observers) {
-                observer.compilationFinished(compilation);
+                observer.compilationFinished(event);
             }
+            removeDebugObjects(null, additionalDebugObjects);
         }
     }
 
@@ -100,4 +120,25 @@
             observers = null;
         }
     }
+
+    public void addDebugObjects(String name, Object[] additionalDebugObjects) {
+        if (name != null) {
+            if (scopeName.get().length() > 0) {
+                scopeName.get().append('.');
+            }
+            scopeName.get().append(name);
+        }
+        for (Object obj : additionalDebugObjects) {
+            debugObjects.get().add(obj);
+        }
+    }
+
+    public void removeDebugObjects(String name, Object[] additionalDebugObjects) {
+        if (name != null) {
+            scopeName.get().setLength(Math.max(0, scopeName.get().length() - name.length()));
+        }
+        for (int i = 0; i < additionalDebugObjects.length; i++) {
+            debugObjects.get().remove(debugObjects.get().size() - 1);
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/stub/CompilerStub.java	Wed Jan 11 18:25:25 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.stub;
-
-import static com.oracle.max.cri.ci.CiKind.*;
-
-import com.oracle.max.cri.ci.*;
-
-/**
- * A compiler stub is a shared routine that performs an operation on behalf of compiled code.
- * Typically the routine is too large to inline, is infrequent, or requires runtime support.
- * Compiler stubs are called with a callee-save convention; the compiler stub must save any
- * registers it may destroy and then restore them upon return. This allows the register
- * allocator to ignore calls to compiler stubs. Parameters to compiler stubs are
- * passed on the stack in order to preserve registers for the rest of the code.
- */
-public class CompilerStub {
-
-    public enum Id {
-        f2i(Int, Float),
-        f2l(Long, Float),
-        d2i(Int, Double),
-        d2l(Long, Double);
-
-        public final CiKind resultKind;
-        public final CiKind[] arguments;
-
-        private Id(CiKind resultKind, CiKind... args) {
-            this.resultKind = resultKind;
-            this.arguments = args;
-        }
-    }
-
-    public final Id id;
-    public final CiKind resultKind;
-    public final Object stubObject;
-
-    /**
-     * The slots in which the stub finds its incoming arguments.
-     * To get the arguments from the perspective of the stub's caller,
-     * use {@link CiStackSlot#asOutArg()}.
-     */
-    public final CiStackSlot[] inArgs;
-
-    /**
-     * The slot in which the stub places its return value (if any).
-     * To get the value from the perspective of the stub's caller,
-     * use {@link CiStackSlot#asOutArg()}.
-     */
-    public final CiStackSlot outResult;
-
-    public CompilerStub(Id id, CiKind resultKind, Object stubObject, CiStackSlot[] argSlots, CiStackSlot resultSlot) {
-        this.id = id;
-        this.resultKind = resultKind;
-        this.stubObject = stubObject;
-        this.inArgs = argSlots;
-        this.outResult = resultSlot;
-    }
-
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/Backend.java	Wed Jan 11 18:25:56 2012 +0100
@@ -31,36 +31,34 @@
 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.stub.*;
+import com.oracle.max.graal.graph.*;
 
 /**
  * The {@code Backend} class represents a compiler backend for Graal.
  */
 public abstract class Backend {
-    public final GraalCompiler compiler;
+    public final RiRuntime runtime;
+    public final CiTarget target;
 
-    protected Backend(GraalCompiler compiler) {
-        this.compiler = compiler;
+    protected Backend(RiRuntime runtime, CiTarget target) {
+        this.runtime = runtime;
+        this.target = target;
     }
 
-    public static Backend create(CiArchitecture arch, GraalCompiler compiler) {
+    public static Backend create(CiArchitecture arch, RiRuntime runtime, CiTarget target) {
         String className = arch.getClass().getName().replace("com.oracle.max.asm", "com.oracle.max.graal.compiler") + "Backend";
         try {
             Class<?> c = Class.forName(className);
-            Constructor<?> cons = c.getDeclaredConstructor(GraalCompiler.class);
-            return (Backend) cons.newInstance(compiler);
+            Constructor<?> cons = c.getDeclaredConstructor(RiRuntime.class, CiTarget.class);
+            return (Backend) cons.newInstance(runtime, target);
         } catch (Exception e) {
             throw new Error("Could not instantiate " + className, e);
         }
     }
 
-    public abstract FrameMap newFrameMap(GraalCompilation compilation);
-    public abstract LIRGenerator newLIRGenerator(GraalCompilation compilation, RiXirGenerator xir);
+    public abstract FrameMap newFrameMap(RiRegisterConfig registerConfig);
+    public abstract LIRGenerator newLIRGenerator(GraalContext context, Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir);
     public abstract AbstractAssembler newAssembler(RiRegisterConfig registerConfig);
     public abstract CiXirAssembler newXirAssembler();
 
-    public abstract CompilerStub emit(GraalContext context, CompilerStub.Id stub);
-    public abstract CompilerStub emit(GraalContext context, CiRuntimeCall runtimeCall);
-    public abstract CompilerStub emit(GraalContext context, XirTemplate t);
-
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64Backend.java	Wed Jan 11 18:25:56 2012 +0100
@@ -25,24 +25,21 @@
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiCompiler.*;
 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.stub.*;
-import com.oracle.max.graal.compiler.stub.CompilerStub.Id;
 import com.oracle.max.graal.compiler.target.*;
-import com.oracle.max.graal.nodes.*;
+import com.oracle.max.graal.graph.*;
 
 /**
  * The {@code X86Backend} class represents the backend for the AMD64 architecture.
  */
 public class AMD64Backend extends Backend {
 
-    public AMD64Backend(GraalCompiler compiler) {
-        super(compiler);
+    public AMD64Backend(RiRuntime runtime, CiTarget target) {
+        super(runtime, target);
     }
     /**
      * Creates a new LIRGenerator for x86.
@@ -50,62 +47,22 @@
      * @return an appropriate LIR generator instance
      */
     @Override
-    public LIRGenerator newLIRGenerator(GraalCompilation compilation, RiXirGenerator xir) {
-        return new AMD64LIRGenerator(compilation, xir);
+    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);
     }
 
     @Override
-    public FrameMap newFrameMap(GraalCompilation compilation) {
-        return new FrameMap(compilation.compiler.runtime, compilation.compiler.target, compilation.registerConfig);
+    public FrameMap newFrameMap(RiRegisterConfig registerConfig) {
+        return new FrameMap(runtime, target, registerConfig);
     }
 
     @Override
     public AbstractAssembler newAssembler(RiRegisterConfig registerConfig) {
-        return new AMD64MacroAssembler(compiler.target, registerConfig);
+        return new AMD64MacroAssembler(target, registerConfig);
     }
 
     @Override
     public CiXirAssembler newXirAssembler() {
-        return new AMD64XirAssembler(compiler.target);
-    }
-
-    @Override
-    public CompilerStub emit(GraalContext context, Id stub) {
-        final GraalCompilation comp = new GraalCompilation(context, compiler, null, new StructuredGraph(), -1, null, DebugInfoLevel.FULL);
-        try {
-            return new AMD64CompilerStubEmitter(comp, stub.arguments, stub.resultKind).emit(stub);
-        } finally {
-            comp.close();
-        }
-    }
-
-    @Override
-    public CompilerStub emit(GraalContext context, CiRuntimeCall rtCall) {
-        final GraalCompilation comp = new GraalCompilation(context, compiler, null, new StructuredGraph(), -1, null, DebugInfoLevel.FULL);
-        try {
-            return new AMD64CompilerStubEmitter(comp, rtCall.arguments, rtCall.resultKind).emit(rtCall);
-        } finally {
-            comp.close();
-        }
-    }
-
-    private static CiKind[] getArgumentKinds(XirTemplate template) {
-        CiXirAssembler.XirParameter[] params = template.parameters;
-        CiKind[] result = new CiKind[params.length];
-        for (int i = 0; i < params.length; i++) {
-            result[i] = params[i].kind;
-        }
-        return result;
-    }
-
-
-    @Override
-    public CompilerStub emit(GraalContext context, XirTemplate t) {
-        final GraalCompilation comp = new GraalCompilation(context, compiler, null, new StructuredGraph(), -1, null, DebugInfoLevel.FULL);
-        try {
-            return new AMD64CompilerStubEmitter(comp, getArgumentKinds(t), t.resultOperand.kind).emit(t);
-        } finally {
-            comp.close();
-        }
+        return new AMD64XirAssembler(target);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CallOpcode.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CallOpcode.java	Wed Jan 11 18:25:56 2012 +0100
@@ -28,12 +28,11 @@
 
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiTargetMethod.*;
-import com.oracle.max.cri.xir.CiXirAssembler.*;
+import com.oracle.max.cri.ci.CiTargetMethod.Mark;
+import com.oracle.max.cri.xir.CiXirAssembler.XirMark;
 import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.compiler.asm.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.stub.*;
 import com.oracle.max.graal.compiler.util.*;
 
 public enum AMD64CallOpcode implements StandardOpcode.CallOpcode {
@@ -94,38 +93,14 @@
         }
     }
 
-    public static void callStub(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CompilerStub stub, LIRDebugInfo info, CiValue result, CiValue... args) {
-        assert args.length == stub.inArgs.length;
-        for (int i = 0; i < args.length; i++) {
-            assert stub.inArgs[i].inCallerFrame();
-            AMD64MoveOpcode.move(tasm, masm, stub.inArgs[i].asOutArg(), args[i]);
-        }
-
-        directCall(tasm, masm, stub.stubObject, info);
-
-        if (isLegal(result)) {
-            AMD64MoveOpcode.move(tasm, masm, result, stub.outResult.asOutArg());
-        }
-
-        // Clear out parameters
-        if (GraalOptions.GenAssertionCode) {
-            for (int i = 0; i < args.length; i++) {
-                CiStackSlot inArg = stub.inArgs[i];
-                CiStackSlot outArg = inArg.asOutArg();
-                CiAddress dst = tasm.asAddress(outArg);
-                masm.movptr(dst, 0);
-            }
-        }
-    }
-
     public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Object target, LIRDebugInfo info) {
         int before = masm.codeBuffer.position();
         if (target instanceof CiRuntimeCall) {
-            long maxOffset = tasm.compilation.compiler.runtime.getMaxCallTargetOffset((CiRuntimeCall) target);
+            long maxOffset = tasm.runtime.getMaxCallTargetOffset((CiRuntimeCall) target);
             if (maxOffset != (int) maxOffset) {
                 // offset might not fit a 32-bit immediate, generate an
                 // indirect call with a 64-bit immediate
-                CiRegister scratch = tasm.compilation.registerConfig.getScratchRegister();
+                CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
                 // TODO(cwi): we want to get rid of a generally reserved scratch register.
                 masm.movq(scratch, 0L);
                 masm.call(scratch);
@@ -159,7 +134,7 @@
     }
 
     private static Object asCallTarget(TargetMethodAssembler tasm, Object o) {
-        return tasm.compilation.compiler.runtime.asCallTarget(o);
+        return tasm.runtime.asCallTarget(o);
     }
 
     public static void shouldNotReachHere(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64CompilerStubEmitter.java	Wed Jan 11 18:25:25 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.max.graal.compiler.target.amd64;
-
-import static com.oracle.max.cri.ci.CiCallingConvention.Type.*;
-import static com.oracle.max.cri.ci.CiValueUtil.*;
-
-import java.util.*;
-
-import com.oracle.max.asm.*;
-import com.oracle.max.asm.target.amd64.*;
-import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
-import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiRegister.*;
-import com.oracle.max.cri.ri.*;
-import com.oracle.max.cri.xir.*;
-import com.oracle.max.cri.xir.CiXirAssembler.*;
-import com.oracle.max.graal.compiler.*;
-import com.oracle.max.graal.compiler.asm.*;
-import com.oracle.max.graal.compiler.stub.*;
-
-/**
- * An object used to produce a single compiler stub.
- */
-public class AMD64CompilerStubEmitter {
-
-    private static final CiRegister convertArgument = AMD64.xmm0;
-    private static final CiRegister convertResult = AMD64.rax;
-
-    /**
-     * The slots in which the stub finds its incoming arguments.
-     * To get the arguments from the perspective of the stub's caller,
-     * use {@link CiStackSlot#asOutArg()}.
-     */
-    private final CiStackSlot[] inArgs;
-
-    /**
-     * The slot in which the stub places its return value (if any).
-     * To get the value from the perspective of the stub's caller,
-     * use {@link CiStackSlot#asOutArg()}.
-     */
-    private final CiStackSlot outResult;
-
-    /**
-     * The layout of the callee save area of the stub being emitted.
-     */
-    private CiCalleeSaveLayout calleeSaveLayout;
-
-    /**
-     * The compilation object for the stub being emitted.
-     */
-    private final GraalCompilation comp;
-
-    private final TargetMethodAssembler tasm;
-    private final AMD64MacroAssembler asm;
-
-    public AMD64CompilerStubEmitter(GraalCompilation compilation, CiKind[] argTypes, CiKind resultKind) {
-        compilation.initFrameMap();
-        this.comp = compilation;
-        final RiRegisterConfig registerConfig = compilation.compiler.compilerStubRegisterConfig;
-        this.asm = new AMD64MacroAssembler(compilation.compiler.target, registerConfig);
-        this.tasm = new TargetMethodAssembler(compilation, asm);
-
-        inArgs = new CiStackSlot[argTypes.length];
-        if (argTypes.length != 0) {
-            final CiValue[] locations = registerConfig.getCallingConvention(JavaCallee, argTypes, compilation.compiler.target, true).locations;
-            for (int i = 0; i < argTypes.length; i++) {
-                inArgs[i] = (CiStackSlot) locations[i];
-            }
-        }
-
-        if (resultKind != CiKind.Void) {
-            final CiValue location = registerConfig.getCallingConvention(JavaCallee, new CiKind[] {resultKind}, compilation.compiler.target, true).locations[0];
-            outResult = (CiStackSlot) location;
-        } else {
-            outResult = null;
-        }
-    }
-
-    public CompilerStub emit(CiRuntimeCall runtimeCall) {
-        emitStandardForward(null, runtimeCall);
-        String name = "graal-stub-" + runtimeCall;
-        CiTargetMethod targetMethod = tasm.finishTargetMethod(name, comp.compiler.runtime, true);
-        Object stubObject = comp.compiler.runtime.registerCompilerStub(targetMethod, name);
-        return new CompilerStub(null, runtimeCall.resultKind, stubObject, inArgs, outResult);
-    }
-
-    public CompilerStub emit(CompilerStub.Id stub) {
-        switch (stub) {
-            case f2i:
-                emitF2I();
-                break;
-            case f2l:
-                emitF2L();
-                break;
-            case d2i:
-                emitD2I();
-                break;
-            case d2l:
-                emitD2L();
-                break;
-        }
-
-        String name = "graal-stub-" + stub;
-        CiTargetMethod targetMethod = tasm.finishTargetMethod(name, comp.compiler.runtime, true);
-        Object stubObject = comp.compiler.runtime.registerCompilerStub(targetMethod, name);
-        return new CompilerStub(stub, stub.resultKind, stubObject, inArgs, outResult);
-    }
-
-    private static CiValue allocateOperand(XirTemp temp, ArrayList<CiRegister> allocatableRegisters) {
-        if (temp instanceof XirRegister) {
-            XirRegister fixed = (XirRegister) temp;
-            return fixed.register;
-        }
-
-        return newRegister(temp.kind, allocatableRegisters);
-    }
-
-    private static CiValue newRegister(CiKind kind, ArrayList<CiRegister> allocatableRegisters) {
-        assert kind != CiKind.Float && kind != CiKind.Double;
-        assert allocatableRegisters.size() > 0;
-        return allocatableRegisters.remove(allocatableRegisters.size() - 1).asValue(kind);
-    }
-
-    public CompilerStub emit(XirTemplate template) {
-        ArrayList<CiRegister> allocatableRegisters = new ArrayList<>(Arrays.asList(comp.registerConfig.getCategorizedAllocatableRegisters().get(RegisterFlag.CPU)));
-        for (XirTemp t : template.temps) {
-            if (t instanceof XirRegister) {
-                final XirRegister fixed = (XirRegister) t;
-                if (isRegister(fixed.register)) {
-                    allocatableRegisters.remove(asRegister(fixed.register));
-                }
-            }
-        }
-
-        prologue(comp.registerConfig.getCalleeSaveLayout());
-
-        CiValue[] operands = new CiValue[template.variableCount];
-
-        XirOperand resultOperand = template.resultOperand;
-
-        if (template.allocateResultOperand) {
-            CiValue outputOperand = CiValue.IllegalValue;
-            // This snippet has a result that must be separately allocated
-            // Otherwise it is assumed that the result is part of the inputs
-            if (resultOperand.kind != CiKind.Void && resultOperand.kind != CiKind.Illegal) {
-                outputOperand = outResult;
-                assert operands[resultOperand.index] == null;
-            }
-            operands[resultOperand.index] = outputOperand;
-        }
-
-        for (int i = 0; i < template.parameters.length; i++) {
-            final XirParameter param = template.parameters[i];
-            assert !(param instanceof XirConstantOperand) : "constant parameters not supported for stubs";
-
-            CiValue op = inArgs[i];
-            assert operands[param.index] == null;
-
-            // Is the value destroyed?
-            if (template.isParameterDestroyed(param.parameterIndex)) {
-                CiValue newOp = newRegister(op.kind, allocatableRegisters);
-                AMD64MoveOpcode.move(tasm, asm, newOp, op);
-                operands[param.index] = newOp;
-            } else {
-                operands[param.index] = op;
-            }
-        }
-
-        for (XirConstant c : template.constants) {
-            assert operands[c.index] == null;
-            operands[c.index] = c.value;
-        }
-
-        for (XirTemp t : template.temps) {
-            CiValue op = allocateOperand(t, allocatableRegisters);
-            assert operands[t.index] == null;
-            operands[t.index] = op;
-        }
-
-        for (CiValue operand : operands) {
-            assert operand != null;
-        }
-
-        Label[] labels = new Label[template.labels.length];
-        for (int i = 0; i < labels.length; i++) {
-            labels[i] = new Label();
-        }
-
-        assert template.marks.length == 0 : "marks not supported in compiler stubs";
-        AMD64XirOpcode.emitXirInstructions(tasm, asm, null, template.fastPath, labels, operands, null);
-        epilogue();
-        String stubName = "graal-" + template.name;
-        CiTargetMethod targetMethod = tasm.finishTargetMethod(stubName, comp.compiler.runtime, true);
-        Object stubObject = comp.compiler.runtime.registerCompilerStub(targetMethod, stubName);
-        return new CompilerStub(null, template.resultOperand.kind, stubObject, inArgs, outResult);
-    }
-
-    private void convertPrologue() {
-        prologue(new CiCalleeSaveLayout(0, -1, comp.compiler.target.wordSize, convertArgument, convertResult));
-        asm.movq(convertArgument, tasm.asAddress(inArgs[0]));
-    }
-
-    private void convertEpilogue() {
-        asm.movq(tasm.asAddress(outResult), convertResult);
-        epilogue();
-    }
-
-    private void emitD2L() {
-        emitCOMISSD(true, false);
-    }
-
-    private void emitD2I() {
-        emitCOMISSD(true, true);
-    }
-
-    private void emitF2L() {
-        emitCOMISSD(false, false);
-    }
-
-    private void emitF2I() {
-        emitCOMISSD(false, true);
-    }
-
-    private void emitCOMISSD(boolean isDouble, @SuppressWarnings("unused") boolean isInt) {
-        // TODO(tw): Check why isInt is never checked?
-        convertPrologue();
-        if (isDouble) {
-            asm.ucomisd(convertArgument, tasm.asDoubleConstRef(CiConstant.DOUBLE_0));
-        } else {
-            asm.ucomiss(convertArgument, tasm.asFloatConstRef(CiConstant.FLOAT_0));
-        }
-        Label nan = new Label();
-        Label ret = new Label();
-        asm.jccb(ConditionFlag.parity, nan);
-        asm.jccb(ConditionFlag.below, ret);
-
-        // input is > 0 -> return maxInt
-        // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff
-        asm.decrementl(convertResult, 1);
-        asm.jmpb(ret);
-
-        // input is NaN -> return 0
-        asm.bind(nan);
-        asm.xorptr(convertResult, convertResult);
-
-        asm.bind(ret);
-        convertEpilogue();
-    }
-
-    private void emitStandardForward(CompilerStub.Id stub, CiRuntimeCall call) {
-        if (stub != null) {
-            assert stub.resultKind == call.resultKind;
-            assert stub.arguments.length == call.arguments.length;
-            for (int i = 0; i < stub.arguments.length; i++) {
-                assert stub.arguments[i] == call.arguments[i];
-            }
-        }
-
-        prologue(comp.registerConfig.getCalleeSaveLayout());
-        forwardRuntimeCall(call);
-        epilogue();
-    }
-
-    private void prologue(CiCalleeSaveLayout csl) {
-        assert this.calleeSaveLayout == null;
-        assert csl != null : "stub should define a callee save area";
-        this.calleeSaveLayout = csl;
-        int entryCodeOffset = comp.compiler.runtime.codeOffset();
-        if (entryCodeOffset != 0) {
-            // pad to normal code entry point
-            asm.nop(entryCodeOffset);
-        }
-        final int frameSize = frameSize();
-        asm.subq(AMD64.rsp, frameSize);
-        tasm.setFrameSize(frameSize);
-        comp.frameMap().setFrameSize(frameSize);
-        asm.save(csl, csl.frameOffsetToCSA);
-    }
-
-    private void epilogue() {
-        tasm.targetMethod.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position());
-
-        // Restore registers
-        int frameToCSA = calleeSaveLayout.frameOffsetToCSA;
-        asm.restore(calleeSaveLayout, frameToCSA);
-
-        // Restore rsp
-        asm.addq(AMD64.rsp, frameSize());
-        asm.ret(0);
-    }
-
-    private int frameSize() {
-        return comp.compiler.target.alignFrameSize(calleeSaveLayout.size);
-    }
-
-    private void forwardRuntimeCall(CiRuntimeCall call) {
-        // Load arguments
-        CiCallingConvention cc = comp.registerConfig.getCallingConvention(RuntimeCall, call.arguments, comp.compiler.target, false);
-        for (int i = 0; i < cc.locations.length; ++i) {
-            CiValue location = cc.locations[i];
-            asm.movq(asRegister(location), tasm.asAddress(inArgs[i]));
-        }
-
-        if (GraalOptions.AlignCallsForPatching) {
-            asm.alignForPatchableDirectCall();
-        }
-        // Call to the runtime
-        int before = asm.codeBuffer.position();
-        asm.call();
-        int after = asm.codeBuffer.position();
-        tasm.recordDirectCall(before, after - before, comp.compiler.runtime.asCallTarget(call), null);
-        asm.ensureUniquePC();
-
-        if (call.resultKind != CiKind.Void) {
-            CiRegister returnRegister = comp.registerConfig.getReturnRegister(call.resultKind);
-            asm.movq(tasm.asAddress(outResult), returnRegister);
-        }
-    }
-}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFIOpcode.java	Wed Jan 11 18:25:56 2012 +0100
@@ -24,41 +24,46 @@
 
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 
-import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.graal.compiler.asm.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.stub.*;
 import com.oracle.max.graal.compiler.util.*;
 
 public enum AMD64ConvertFIOpcode implements LIROpcode {
     F2I, D2I;
 
-    public LIRInstruction create(CiValue result, final CompilerStub stub, CiValue x) {
+    public LIRInstruction create(CiValue result, CiValue x) {
         CiValue[] inputs = new CiValue[] {x};
         CiValue[] outputs = new CiValue[] {result};
 
         return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, LIRInstruction.NO_OPERANDS) {
             @Override
             public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), stub, input(0));
+                emit(tasm, masm, output(0), input(0));
             }
         };
     }
 
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CompilerStub stub, CiValue x) {
+    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x) {
+        AMD64ConvertFSlowPath slowPath;
         switch (this) {
-            case F2I: masm.cvttss2sil(asIntReg(result), asFloatReg(x)); break;
-            case D2I: masm.cvttsd2sil(asIntReg(result), asDoubleReg(x)); break;
-            default: throw Util.shouldNotReachHere();
+            case F2I:
+                masm.cvttss2sil(asIntReg(result), asFloatReg(x));
+                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asFloatReg(x), false, false);
+                break;
+            case D2I:
+                masm.cvttsd2sil(asIntReg(result), asDoubleReg(x));
+                slowPath = new AMD64ConvertFSlowPath(masm, asIntReg(result), asDoubleReg(x), true, false);
+                break;
+            default:
+                throw Util.shouldNotReachHere();
         }
+        tasm.slowPaths.add(slowPath);
 
-        Label endLabel = new Label();
         masm.cmp32(asIntReg(result), Integer.MIN_VALUE);
-        masm.jcc(ConditionFlag.notEqual, endLabel);
-        AMD64CallOpcode.callStub(tasm, masm, stub, null, result, x);
-        masm.bind(endLabel);
+        masm.jcc(ConditionFlag.equal, slowPath.start);
+        masm.bind(slowPath.continuation);
     }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFLOpcode.java	Wed Jan 11 18:25:56 2012 +0100
@@ -24,19 +24,17 @@
 
 import static com.oracle.max.cri.ci.CiValueUtil.*;
 
-import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.max.asm.target.amd64.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.graal.compiler.asm.*;
 import com.oracle.max.graal.compiler.lir.*;
-import com.oracle.max.graal.compiler.stub.*;
 import com.oracle.max.graal.compiler.util.*;
 
 public enum AMD64ConvertFLOpcode implements LIROpcode {
     F2L, D2L;
 
-    public LIRInstruction create(CiValue result, final CompilerStub stub, CiValue x, CiValue scratch) {
+    public LIRInstruction create(CiValue result, CiValue x, CiValue scratch) {
         CiValue[] inputs = new CiValue[] {x};
         CiValue[] temps = new CiValue[] {scratch};
         CiValue[] outputs = new CiValue[] {result};
@@ -44,27 +42,31 @@
         return new AMD64LIRInstruction(this, outputs, null, inputs, LIRInstruction.NO_OPERANDS, temps) {
             @Override
             public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-                emit(tasm, masm, output(0), stub, input(0), temp(0));
+                emit(tasm, masm, output(0), input(0), temp(0));
             }
         };
     }
 
-    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CompilerStub stub, CiValue x, CiValue scratch) {
-        assert differentRegisters(result, scratch);
+    private void emit(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue result, CiValue x, CiValue scratch) {
+        AMD64ConvertFSlowPath slowPath;
+        switch (this) {
+            case F2L:
+                masm.cvttss2siq(asLongReg(result), asFloatReg(x));
+                slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asFloatReg(x), false, true);
+                break;
+            case D2L:
+                masm.cvttsd2siq(asLongReg(result), asDoubleReg(x));
+                slowPath = new AMD64ConvertFSlowPath(masm, asLongReg(result), asDoubleReg(x), true, true);
+                break;
+            default:
+                throw Util.shouldNotReachHere();
+        }
+        tasm.slowPaths.add(slowPath);
 
-        CiRegister dst = asLongReg(result);
         CiRegister tmp = asLongReg(scratch);
-        switch (this) {
-            case F2L: masm.cvttss2siq(dst, asFloatReg(x)); break;
-            case D2L: masm.cvttsd2siq(dst, asDoubleReg(x)); break;
-            default: throw Util.shouldNotReachHere();
-        }
-
-        Label endLabel = new Label();
         masm.movq(tmp, java.lang.Long.MIN_VALUE);
-        masm.cmpq(dst, tmp);
-        masm.jcc(ConditionFlag.notEqual, endLabel);
-        AMD64CallOpcode.callStub(tasm, masm, stub, null, result, x);
-        masm.bind(endLabel);
+        masm.cmpq(asLongReg(result), tmp);
+        masm.jcc(ConditionFlag.equal, slowPath.start);
+        masm.bind(slowPath.continuation);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64ConvertFSlowPath.java	Wed Jan 11 18:25:56 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.max.graal.compiler.target.amd64;
+
+import com.oracle.max.asm.*;
+import com.oracle.max.asm.target.amd64.*;
+import com.oracle.max.asm.target.amd64.AMD64Assembler.*;
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.graal.compiler.asm.*;
+import com.oracle.max.graal.compiler.lir.*;
+
+class AMD64ConvertFSlowPath implements LIR.SlowPath {
+
+    public final Label start = new Label();
+    public final Label continuation = new Label();
+
+    private final CiRegister result;
+    private final CiRegister input;
+    private final AMD64MacroAssembler masm;
+    private final boolean inputIsDouble;
+    private final boolean resultIsLong;
+
+    public AMD64ConvertFSlowPath(AMD64MacroAssembler masm, CiRegister result, CiRegister input, boolean inputIsDouble, boolean resultIsLong) {
+        this.masm = masm;
+        this.result = result;
+        this.input = input;
+        this.inputIsDouble = inputIsDouble;
+        this.resultIsLong = resultIsLong;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm) {
+        masm.bind(start);
+        if (inputIsDouble) {
+            masm.ucomisd(input, tasm.asDoubleConstRef(CiConstant.DOUBLE_0));
+        } else {
+            masm.ucomiss(input, tasm.asFloatConstRef(CiConstant.FLOAT_0));
+        }
+        Label nan = new Label();
+        masm.jcc(ConditionFlag.parity, nan);
+        masm.jcc(ConditionFlag.below, continuation);
+
+        // input is > 0 -> return maxInt
+        // result register already contains 0x80000000, so subtracting 1 gives 0x7fffffff
+        if (resultIsLong) {
+            masm.decrementq(result, 1);
+        } else {
+            masm.decrementl(result, 1);
+        }
+        masm.jmp(continuation);
+
+        // input is NaN -> return 0
+        masm.bind(nan);
+        masm.xorptr(result, result);
+        masm.jmp(continuation);
+    }
+}
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64DeoptimizationStub.java	Wed Jan 11 18:25:56 2012 +0100
@@ -53,7 +53,7 @@
         AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm;
 
         // TODO(cwi): we want to get rid of a generally reserved scratch register.
-        CiRegister scratch = tasm.compilation.registerConfig.getScratchRegister();
+        CiRegister scratch = tasm.frameMap.registerConfig.getScratchRegister();
 
         masm.bind(label);
         if (GraalOptions.CreateDeoptInfo && deoptInfo != null) {
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRGenerator.java	Wed Jan 11 18:25:56 2012 +0100
@@ -40,12 +40,13 @@
 import com.oracle.max.asm.*;
 import com.oracle.max.asm.target.amd64.*;
 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.stub.*;
 import com.oracle.max.graal.compiler.util.*;
+import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.DeoptimizeNode.DeoptAction;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.calc.*;
@@ -73,8 +74,8 @@
         StandardOpcode.XIR = AMD64XirOpcode.XIR;
     }
 
-    public AMD64LIRGenerator(GraalCompilation compilation, RiXirGenerator xir) {
-        super(compilation, xir);
+    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);
         lir.methodEndMarker = new AMD64MethodEndStub();
     }
 
@@ -424,12 +425,12 @@
             case D2F: append(D2F.create(result, input)); break;
             case I2F: append(I2F.create(result, input)); break;
             case I2D: append(I2D.create(result, input)); break;
-            case F2I: append(F2I.create(result, stubFor(CompilerStub.Id.f2i), input)); break;
-            case D2I: append(D2I.create(result, stubFor(CompilerStub.Id.d2i), input)); break;
+            case F2I: append(F2I.create(result, input)); break;
+            case D2I: append(D2I.create(result, input)); break;
             case L2F: append(L2F.create(result, input)); break;
             case L2D: append(L2D.create(result, input)); break;
-            case F2L: append(F2L.create(result, stubFor(CompilerStub.Id.f2l), input, newVariable(CiKind.Long))); break;
-            case D2L: append(D2L.create(result, stubFor(CompilerStub.Id.d2l), input, newVariable(CiKind.Long))); break;
+            case F2L: append(F2L.create(result, input, newVariable(CiKind.Long))); break;
+            case D2L: append(D2L.create(result, input, newVariable(CiKind.Long))); break;
             case MOV_I2F: append(MOV_I2F.create(result, input)); break;
             case MOV_L2D: append(MOV_L2D.create(result, input)); break;
             case MOV_F2I: append(MOV_F2I.create(result, input)); break;
@@ -453,8 +454,8 @@
 
     @Override
     public void emitMembar(int barriers) {
-        int necessaryBarriers = compilation.compiler.target.arch.requiredBarriers(barriers);
-        if (compilation.compiler.target.isMP && necessaryBarriers != 0) {
+        int necessaryBarriers = target.arch.requiredBarriers(barriers);
+        if (target.isMP && necessaryBarriers != 0) {
             append(MEMBAR.create(necessaryBarriers));
         }
     }
@@ -463,7 +464,7 @@
     protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, CiValue index) {
         // Making a copy of the switch value is necessary because jump table destroys the input value
         Variable tmp = emitMove(index);
-        append(TABLE_SWITCH.create(lowKey, defaultTarget, targets, tmp, newVariable(compilation.compiler.target.wordKind)));
+        append(TABLE_SWITCH.create(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
     }
 
     @Override
@@ -496,7 +497,7 @@
         }
 
         if (kind == CiKind.Object) {
-            Variable loadedAddress = newVariable(compilation.compiler.target.wordKind);
+            Variable loadedAddress = newVariable(target.wordKind);
             append(LEA_MEMORY.create(loadedAddress, addrBase, addrIndex, CiAddress.Scale.Times1, addrDisplacement));
             preGCWriteBarrier(loadedAddress, false, null);
 
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirAssembler.java	Wed Jan 11 18:25:56 2012 +0100
@@ -43,7 +43,6 @@
     protected XirTemplate buildTemplate(String name, boolean isStub) {
         List<XirInstruction> fastPath = new ArrayList<>(instructions.size());
         List<XirInstruction> slowPath = new ArrayList<>();
-        List<XirTemplate> calleeTemplates = new ArrayList<>();
 
         int flags = 0;
 
@@ -164,18 +163,6 @@
                     currentList.add(new XirInstruction(i.kind, i.op, i.result, i.x(), i.y(), fixedRAX));
                     appended = true;
                     break;
-                case CallStub:
-                    for (int j = 0; j < i.arguments.length; j++) {
-                        XirOperand op = i.arguments[j];
-                        if (op instanceof XirConstantOperand && (op.kind == CiKind.Object || op.kind == CiKind.Long)) {
-                            XirOperand tempLocation = createTemp("callStubTempLocation", op.kind);
-                            currentList.add(new XirInstruction(op.kind, XirOp.Mov, tempLocation, op));
-                            i.arguments[j] = tempLocation;
-                        }
-                    }
-                    flags |= HAS_STUB_CALL.mask;
-                    calleeTemplates.add((XirTemplate) i.extra);
-                    break;
                 case CallRuntime:
                     flags |= HAS_RUNTIME_CALL.mask;
                     break;
@@ -228,9 +215,8 @@
         XirParameter[] xirParameters = parameters.toArray(new XirParameter[parameters.size()]);
         XirTemp[] temporaryOperands = temps.toArray(new XirTemp[temps.size()]);
         XirConstant[] constantOperands = constants.toArray(new XirConstant[constants.size()]);
-        XirTemplate[] calleeTemplateArray = calleeTemplates.toArray(new XirTemplate[calleeTemplates.size()]);
         XirMark[] marksArray = marks.toArray(new XirMark[marks.size()]);
-        return new XirTemplate(name, this.variableCount, this.allocateResultOperand, resultOperand, fp, sp, xirLabels, xirParameters, temporaryOperands, constantOperands, flags, calleeTemplateArray, marksArray, outgoingStackSize);
+        return new XirTemplate(name, this.variableCount, this.allocateResultOperand, resultOperand, fp, sp, xirLabels, xirParameters, temporaryOperands, constantOperands, flags, marksArray, outgoingStackSize);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64XirOpcode.java	Wed Jan 11 18:25:56 2012 +0100
@@ -85,7 +85,7 @@
         }
 
         if (snippet.template.slowPath != null) {
-            tasm.compilation.lir().slowPaths.add(new SlowPath(op, labels, snippet.marks));
+            tasm.slowPaths.add(new SlowPath(op, labels, snippet.marks));
         }
     }
 
@@ -294,26 +294,13 @@
 
                     break;
 
-                case CallStub: {
-                    XirTemplate stubId = (XirTemplate) inst.extra;
-                    CiValue result = CiValue.IllegalValue;
-                    if (inst.result != null) {
-                        result = operands[inst.result.index];
-                    }
-                    CiValue[] args = new CiValue[inst.arguments.length];
-                    for (int i = 0; i < args.length; i++) {
-                        args[i] = operands[inst.arguments[i].index];
-                    }
-                    AMD64CallOpcode.callStub(tasm, masm, tasm.compilation.compiler.lookupStub(stubId), info, result, args);
-                    break;
-                }
                 case CallRuntime: {
                     CiKind[] signature = new CiKind[inst.arguments.length];
                     for (int i = 0; i < signature.length; i++) {
                         signature[i] = inst.arguments[i].kind;
                     }
 
-                    CiCallingConvention cc = tasm.compilation.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false);
+                    CiCallingConvention cc = tasm.frameMap.registerConfig.getCallingConvention(RuntimeCall, signature, tasm.target, false);
                     for (int i = 0; i < inst.arguments.length; i++) {
                         CiValue argumentLocation = cc.locations[i];
                         CiValue argumentSourceLocation = operands[inst.arguments[i].index];
@@ -326,7 +313,7 @@
                     AMD64CallOpcode.directCall(tasm, masm, runtimeCallInformation.target, (runtimeCallInformation.useInfoAfter) ? infoAfter : info);
 
                     if (inst.result != null && inst.result.kind != CiKind.Illegal && inst.result.kind != CiKind.Void) {
-                        CiRegister returnRegister = tasm.compilation.registerConfig.getReturnRegister(inst.result.kind);
+                        CiRegister returnRegister = tasm.frameMap.registerConfig.getReturnRegister(inst.result.kind);
                         CiValue resultLocation = returnRegister.asValue(inst.result.kind.stackKind());
                         AMD64MoveOpcode.move(tasm, masm, operands[inst.result.index], resultLocation);
                     }
@@ -430,7 +417,7 @@
                     break;
                 }
                 case StackOverflowCheck: {
-                    int frameSize = tasm.compilation.frameMap().frameSize();
+                    int frameSize = tasm.frameMap.frameSize();
                     int lastFramePage = frameSize / tasm.target.pageSize;
                     // emit multiple stack bangs for methods with frames larger than a page
                     for (int i = 0; i <= lastFramePage; i++) {
@@ -441,7 +428,7 @@
                     break;
                 }
                 case PushFrame: {
-                    int frameSize = tasm.compilation.frameMap().frameSize();
+                    int frameSize = tasm.frameMap.frameSize();
                     masm.decrementq(AMD64.rsp, frameSize); // does not emit code for frameSize == 0
                     if (GraalOptions.ZapStackOnMethodEntry) {
                         final int intSize = 4;
@@ -449,22 +436,22 @@
                             masm.movl(new CiAddress(CiKind.Int, AMD64.rsp.asValue(), i * intSize), 0xC1C1C1C1);
                         }
                     }
-                    CiCalleeSaveLayout csl = tasm.compilation.registerConfig.getCalleeSaveLayout();
+                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
                     if (csl != null && csl.size != 0) {
-                        int frameToCSA = tasm.compilation.frameMap().offsetToCalleeSaveArea();
+                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
                         assert frameToCSA >= 0;
                         masm.save(csl, frameToCSA);
                     }
                     break;
                 }
                 case PopFrame: {
-                    int frameSize = tasm.compilation.frameMap().frameSize();
+                    int frameSize = tasm.frameMap.frameSize();
 
-                    CiCalleeSaveLayout csl = tasm.compilation.registerConfig.getCalleeSaveLayout();
+                    CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout();
                     if (csl != null && csl.size != 0) {
                         tasm.targetMethod.setRegisterRestoreEpilogueOffset(masm.codeBuffer.position());
                         // saved all registers, restore all registers
-                        int frameToCSA = tasm.compilation.frameMap().offsetToCalleeSaveArea();
+                        int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea();
                         masm.restore(csl, frameToCSA);
                     }
 
@@ -481,7 +468,7 @@
                     if (isRegister(result)) {
                         masm.pop(asRegister(result));
                     } else {
-                        CiRegister rscratch = tasm.compilation.registerConfig.getScratchRegister();
+                        CiRegister rscratch = tasm.frameMap.registerConfig.getScratchRegister();
                         masm.pop(rscratch);
                         AMD64MoveOpcode.move(tasm, masm, result, rscratch.asValue());
                     }
@@ -569,7 +556,7 @@
 
     private static CiValue assureNot64BitConstant(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue value) {
         if (isConstant(value) && (value.kind == CiKind.Long || value.kind == CiKind.Object)) {
-            CiRegisterValue register = tasm.compilation.registerConfig.getScratchRegister().asValue(value.kind);
+            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(value.kind);
             AMD64MoveOpcode.move(tasm, masm, register, value);
             return register;
         }
@@ -578,7 +565,7 @@
 
     private static CiRegisterValue assureInRegister(TargetMethodAssembler tasm, AMD64MacroAssembler masm, CiValue pointer) {
         if (isConstant(pointer)) {
-            CiRegisterValue register = tasm.compilation.registerConfig.getScratchRegister().asValue(pointer.kind);
+            CiRegisterValue register = tasm.frameMap.registerConfig.getScratchRegister().asValue(pointer.kind);
             AMD64MoveOpcode.move(tasm, masm, register, pointer);
             return register;
         }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/Util.java	Wed Jan 11 18:25:56 2012 +0100
@@ -26,7 +26,6 @@
 
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.criutils.*;
-import com.oracle.max.graal.compiler.*;
 import com.oracle.max.graal.graph.*;
 import com.oracle.max.graal.nodes.*;
 
@@ -346,24 +345,6 @@
     }
 
     /**
-     * Determines if the kinds of two given IR nodes are equal at the {@linkplain #archKind(CiKind) architecture}
-     * level in the context of the {@linkplain GraalCompilation#compilation()} compilation.
-     */
-    public static boolean archKindsEqual(ValueNode i, ValueNode other) {
-        return archKindsEqual(i.kind(), other.kind());
-    }
-
-    /**
-     * Determines if two given kinds are equal at the {@linkplain #archKind(CiKind) architecture} level
-     * in the context of the {@linkplain GraalCompilation#compilation()} compilation.
-     */
-    public static boolean archKindsEqual(CiKind k1, CiKind k2) {
-        // TODO(cwi): I think that implementation should do it with the new handling of Word types.
-        return k1 == k2;
-    }
-
-
-    /**
      * Checks that two instructions are equivalent, optionally comparing constants.
      * @param x the first instruction
      * @param y the second instruction
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/CompilerImpl.java	Wed Jan 11 18:25:56 2012 +0100
@@ -31,6 +31,7 @@
 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.*;
@@ -151,17 +152,18 @@
     @Override
     public GraalCompiler getCompiler() {
         if (compiler == null) {
-            RiRegisterConfig registerConfig;
-
             // these options are important - graal will not generate correct code without them
             GraalOptions.StackShadowPages = config.stackShadowPages;
 
-            registerConfig = getRuntime().globalStubRegConfig;
-            RiXirGenerator generator = new HotSpotXirGenerator(config, getTarget(), registerConfig, this);
+            RiXirGenerator generator = new HotSpotXirGenerator(config, getTarget(), getRuntime().getGlobalStubRegisterConfig(), this);
             if (Logger.ENABLED) {
                 generator = LoggingProxy.getProxy(RiXirGenerator.class, generator);
             }
-            compiler = new GraalCompiler(context, getRuntime(), getTarget(), generator, registerConfig);
+
+            Backend backend = Backend.create(target.arch, runtime, target);
+            generator.initialize(backend.newXirAssembler());
+
+            compiler = new GraalCompiler(context, getRuntime(), getTarget(), backend, generator);
         }
         return compiler;
     }
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Jan 11 18:25:56 2012 +0100
@@ -27,12 +27,11 @@
 import java.util.concurrent.*;
 
 import com.oracle.max.cri.ci.*;
-import com.oracle.max.cri.ci.CiCompiler.*;
 import com.oracle.max.cri.ri.*;
 import com.oracle.max.criutils.*;
 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.compiler.phases.PhasePlan.PhasePosition;
 import com.oracle.max.graal.hotspot.*;
 import com.oracle.max.graal.hotspot.Compiler;
 import com.oracle.max.graal.hotspot.ri.*;
@@ -168,9 +167,9 @@
                 public void run() {
                     try {
                         PhasePlan plan = new PhasePlan();
-                        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), null);
+                        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime());
                         plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-                        CiTargetMethod result = compiler.getCompiler().compileMethod(method, -1, null, DebugInfoLevel.FULL, plan);
+                        CiTargetMethod result = compiler.getCompiler().compileMethod(method, -1, plan);
                         HotSpotTargetMethod.installMethod(compiler, method, result, true);
                     } catch (CiBailout bailout) {
                         if (GraalOptions.ExitVMOnBailout) {
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotRuntime.java	Wed Jan 11 18:25:56 2012 +0100
@@ -51,7 +51,7 @@
     final GraalContext context;
     final HotSpotVMConfig config;
     final HotSpotRegisterConfig regConfig;
-    public final HotSpotRegisterConfig globalStubRegConfig;
+    private final HotSpotRegisterConfig globalStubRegConfig;
     private final Compiler compiler;
 
     public HotSpotRuntime(GraalContext context, HotSpotVMConfig config, Compiler compiler) {
@@ -430,4 +430,9 @@
         Compiler compilerInstance = CompilerImpl.getInstance();
         return HotSpotTargetMethod.installMethod(compilerInstance, (HotSpotMethodResolved) method, code, false);
     }
+
+    @Override
+    public RiRegisterConfig getGlobalStubRegisterConfig() {
+        return globalStubRegConfig;
+    }
 }
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java	Wed Jan 11 18:25:56 2012 +0100
@@ -1306,10 +1306,8 @@
     }
 
     @Override
-    public List<XirTemplate> makeTemplates(CiXirAssembler asm) {
+    public void initialize(CiXirAssembler asm) {
         this.globalAsm = asm;
-        List<XirTemplate> templates = new ArrayList<>();
-        return templates;
     }
 
     private void verifyPointer(CiXirAssembler asm, XirOperand pointer) {
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Wed Jan 11 18:25:56 2012 +0100
@@ -67,7 +67,6 @@
 
     private StructuredGraph currentGraph;
 
-    private final CiStatistics stats;
     private final RiRuntime runtime;
     private RiConstantPool constantPool;
     private RiExceptionHandler[] exceptionHandlers;
@@ -104,17 +103,12 @@
     private final GraphBuilderConfiguration config;
 
     public GraphBuilderPhase(RiRuntime runtime) {
-        this(runtime, null);
+        this(runtime, GraphBuilderConfiguration.getDefault());
     }
 
-    public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats) {
-        this(runtime, stats, GraphBuilderConfiguration.getDefault());
-    }
-
-    public GraphBuilderPhase(RiRuntime runtime, CiStatistics stats, GraphBuilderConfiguration config) {
+    public GraphBuilderPhase(RiRuntime runtime, GraphBuilderConfiguration config) {
         this.config = config;
         this.runtime = runtime;
-        this.stats = stats;
         this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
     }
 
@@ -143,9 +137,7 @@
     private BlockMap createBlockMap() {
         BlockMap map = new BlockMap(method, config.useBranchPrediction());
         map.build();
-        if (stats != null) {
-            stats.bytecodeCount += method.code().length;
-        }
+        currentContext.metrics.bytecodeCount += method.code().length;
 
         if (currentContext.isObserved()) {
             String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method);
@@ -165,9 +157,8 @@
         this.canTrapBitSet = blockMap.canTrap;
 
         exceptionHandlers = blockMap.exceptionHandlers();
-        if (stats != null) {
-            stats.blockCount += blockMap.blocks.size();
-        }
+        currentContext.metrics.blockCount += blockMap.blocks.size();
+
         nextBlockNumber = blockMap.blocks.size();
 
         lastInstr = currentGraph.start();
@@ -208,9 +199,7 @@
     }
 
     private int nextBlockNumber() {
-        if (stats != null) {
-            stats.blockCount++;
-        }
+        currentContext.metrics.blockCount++;
         return nextBlockNumber++;
     }
 
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinter.java	Wed Jan 11 18:25:56 2012 +0100
@@ -30,14 +30,15 @@
 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.compiler.alloc.*;
 import com.oracle.max.graal.compiler.alloc.Interval.UsePosList;
+import com.oracle.max.graal.compiler.gen.*;
 import com.oracle.max.graal.compiler.lir.*;
 import com.oracle.max.graal.compiler.schedule.*;
 import com.oracle.max.graal.graph.*;
-import com.oracle.max.graal.graph.Node.*;
-import com.oracle.max.graal.graph.NodeClass.*;
+import com.oracle.max.graal.graph.Node.Verbosity;
+import com.oracle.max.graal.graph.NodeClass.NodeClassIterator;
+import com.oracle.max.graal.graph.NodeClass.Position;
 import com.oracle.max.graal.java.*;
 import com.oracle.max.graal.nodes.*;
 import com.oracle.max.graal.nodes.calc.*;
@@ -48,29 +49,26 @@
 class CFGPrinter extends CompilationPrinter {
 
     public final ByteArrayOutputStream buffer;
-    public final GraalCompilation compilation;
     public final CiTarget target;
     public final RiRuntime runtime;
+    private LIR lir;
+    private LIRGenerator lirGenerator;
 
     /**
      * Creates a control flow graph printer.
      *
      * @param buffer where the output generated via this printer shown be written
      */
-    public CFGPrinter(ByteArrayOutputStream buffer, GraalCompilation compilation) {
+    public CFGPrinter(ByteArrayOutputStream buffer, CiTarget target, RiRuntime runtime) {
         super(buffer);
         this.buffer = buffer;
-        this.compilation = compilation;
-        this.target = compilation.compiler.target;
-        this.runtime = compilation.compiler.runtime;
+        this.target = target;
+        this.runtime = runtime;
     }
 
-    public CFGPrinter(ByteArrayOutputStream buffer, GraalCompilation compilation, CiTarget target, RiRuntime runtime) {
-        super(buffer);
-        this.buffer = buffer;
-        this.compilation = compilation;
-        this.target = target;
-        this.runtime = runtime;
+    public void setLIR(LIR lir, LIRGenerator lirGenerator) {
+        this.lir = lir;
+        this.lirGenerator = lirGenerator;
     }
 
     /**
@@ -230,8 +228,8 @@
         } else if (node instanceof FloatingNode) {
             out.print("f ").print(HOVER_START).print("~").print(HOVER_SEP).print("floating").print(HOVER_END).println(COLUMN_END);
         }
-        if (compilation.nodeOperands != null && node instanceof ValueNode) {
-            CiValue operand = compilation.operand((ValueNode) node);
+        if (lirGenerator != null && lirGenerator.nodeOperands != null && node instanceof ValueNode) {
+            CiValue operand = lirGenerator.nodeOperands.get(node);
             if (operand != null) {
                 out.print("result ").print(operand.toString()).println(COLUMN_END);
             }
@@ -330,8 +328,8 @@
 
     private String stateValueToString(ValueNode value) {
         String result = nodeToString(value);
-        if (value != null) {
-            CiValue operand = compilation.operand(value);
+        if (lirGenerator != null && lirGenerator.nodeOperands != null && value != null) {
+            CiValue operand = lirGenerator.nodeOperands.get(value);
             if (operand != null) {
                 result += ": " + operand;
             }
@@ -345,8 +343,8 @@
      * @param block the block to print
      */
     private void printLIR(LIRBlock block) {
-        List<LIRInstruction> lir = block.lir();
-        if (lir == null) {
+        List<LIRInstruction> lirInstructions = block.lir();
+        if (lirInstructions == null) {
             return;
         }
 
@@ -366,8 +364,8 @@
             }
         }
 
-        for (int i = 0; i < lir.size(); i++) {
-            LIRInstruction inst = lir.get(i);
+        for (int i = 0; i < lirInstructions.size(); i++) {
+            LIRInstruction inst = lirInstructions.get(i);
             out.printf("nr %4d ", inst.id()).print(COLUMN_END);
 
             if (inst.info != null) {
@@ -396,7 +394,7 @@
             return "-";
         }
         String prefix;
-        if (node instanceof BeginNode && compilation != null && compilation.lir() == null) {
+        if (node instanceof BeginNode && lir == null) {
             prefix = "B";
         } else if (node instanceof ValueNode) {
             ValueNode value = (ValueNode) node;
@@ -412,7 +410,7 @@
     }
 
     private String blockToString(Block block) {
-        if (compilation != null && compilation.lir() == null) {
+        if (lir == null) {
             // During all the front-end phases, the block schedule is built only for the debug output.
             // Therefore, the block numbers would be different for every CFG printed -> use the id of the first instruction.
             return "B" + block.firstNode().toString(Verbosity.Id);
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java	Wed Jan 11 18:25:56 2012 +0100
@@ -28,8 +28,8 @@
 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.compiler.alloc.*;
+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.schedule.*;
@@ -54,13 +54,15 @@
     };
 
     @Override
-    public void compilationStarted(GraalCompilation compilation) {
+    public void compilationStarted(CompilationEvent event) {
         if (TTY.isSuppressed()) {
             return;
         }
+        RiRuntime runtime = event.debugObject(RiRuntime.class);
+        CiTarget target = event.debugObject(CiTarget.class);
 
-        CFGPrinter cfgPrinter = new CFGPrinter(new ByteArrayOutputStream(), compilation);
-        cfgPrinter.printCompilation(compilation.method);
+        CFGPrinter cfgPrinter = new CFGPrinter(new ByteArrayOutputStream(), target, runtime);
+        cfgPrinter.printCompilation(event.debugObject(RiResolvedMethod.class));
         observations.get().push(cfgPrinter);
     }
 
@@ -75,6 +77,7 @@
         }
 
         RiRuntime runtime = cfgPrinter.runtime;
+        cfgPrinter.setLIR(event.debugObject(LIR.class), event.debugObject(LIRGenerator.class));
         BlockMap blockMap = event.debugObject(BlockMap.class);
         Graph graph = event.debugObject(Graph.class);
         IdentifyBlocksPhase schedule = event.debugObject(IdentifyBlocksPhase.class);
@@ -116,7 +119,7 @@
     }
 
     @Override
-    public void compilationFinished(GraalCompilation compilation) {
+    public void compilationFinished(CompilationEvent event) {
         if (TTY.isSuppressed()) {
             return;
         }
--- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterObserver.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinterObserver.java	Wed Jan 11 18:25:56 2012 +0100
@@ -85,23 +85,23 @@
     }
 
     @Override
-    public void compilationStarted(GraalCompilation compilation) {
-        openPrinter(compilation, false);
+    public void compilationStarted(CompilationEvent event) {
+        openPrinter(event.debugObject(RiResolvedMethod.class), false);
     }
 
-    private void openPrinter(GraalCompilation compilation, boolean error) {
+    private void openPrinter(RiResolvedMethod method, boolean error) {
         assert (context().stream == null && printer() == null);
         if ((!TTY.isSuppressed() && GraalOptions.Plot) || (GraalOptions.PlotOnError && error)) {
             String name;
-            if (compilation != null) {
-                name = compilation.method.holder().name();
+            if (method != null) {
+                name = method.holder().name();
                 name = name.substring(1, name.length() - 1).replace('/', '.');
-                name = name + "." + compilation.method.name();
+                name = name + "." + method.name();
             } else {
                 name = "null";
             }
 
-            openPrinter(name, compilation == null ? null : compilation.method);
+            openPrinter(name, method);
         }
     }
 
@@ -189,7 +189,7 @@
     public void compilationEvent(CompilationEvent event) {
         boolean lazyStart = false;
         if (printer() == null && event.hasDebugObject(CompilationEvent.ERROR)) {
-            openPrinter(event.debugObject(GraalCompilation.class), true);
+            openPrinter(event.debugObject(RiResolvedMethod.class), true);
             lazyStart = true;
         }
         Graph graph = event.debugObject(Graph.class);
@@ -202,7 +202,7 @@
     }
 
     @Override
-    public void compilationFinished(GraalCompilation compilation) {
+    public void compilationFinished(CompilationEvent event) {
         if (printer() != null) {
             closePrinter();
         }
--- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java	Wed Jan 11 18:25:56 2012 +0100
@@ -129,7 +129,7 @@
     private static StructuredGraph buildSnippetGraph(RiResolvedMethod snippetRiMethod, GraalRuntime runtime, CiTarget target, GraalContext context, BoxingMethodPool pool, PhasePlan plan, IdealGraphPrinterObserver observer) {
 
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDeoptFreeDefault();
-        GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, null, config);
+        GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config);
         StructuredGraph graph = new StructuredGraph(snippetRiMethod);
         graphBuilder.apply(graph, context);
 
--- a/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Wed Jan 11 18:25:25 2012 +0100
+++ b/graal/com.oracle.max.graal.tests/src/com/oracle/max/graal/compiler/tests/GraphTest.java	Wed Jan 11 18:25:56 2012 +0100
@@ -103,13 +103,13 @@
     protected StructuredGraph parse(Method m) {
         RiResolvedMethod riMethod = runtime.getRiMethod(m);
         StructuredGraph graph = new StructuredGraph(riMethod);
-        new GraphBuilderPhase(runtime, null, GraphBuilderConfiguration.getDeoptFreeDefault()).apply(graph);
+        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDeoptFreeDefault()).apply(graph);
         return graph;
     }
 
     protected PhasePlan getDefaultPhasePlan() {
         PhasePlan plan = new PhasePlan();
-        plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, null, GraphBuilderConfiguration.getDeoptFreeDefault()));
+        plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDeoptFreeDefault()));
         return plan;
     }
 
--- a/hotspot/.cproject	Wed Jan 11 18:25:25 2012 +0100
+++ b/hotspot/.cproject	Wed Jan 11 18:25:56 2012 +0100
@@ -36,6 +36,9 @@
 									<listOptionValue builtIn="false" value="_REENTRANT=1"/>
 									<listOptionValue builtIn="false" value="DEBUG=1"/>
 									<listOptionValue builtIn="false" value="AMD64=1"/>
+									<listOptionValue builtIn="false" value="LINUX=1"/>
+									<listOptionValue builtIn="false" value="TARGET_ARCH_x86"/>
+									<listOptionValue builtIn="false" value="TARGET_COMPILER_gcc=1"/>
 								</option>
 								<option id="gnu.cpp.compiler.option.preprocessor.undef.2137486146" name="Undefined symbols (-U)" superClass="gnu.cpp.compiler.option.preprocessor.undef" valueType="undefDefinedSymbols">
 									<listOptionValue builtIn="false" value="PRODUCT"/>
--- a/hotspot/.project	Wed Jan 11 18:25:25 2012 +0100
+++ b/hotspot/.project	Wed Jan 11 18:25:56 2012 +0100
@@ -93,7 +93,7 @@
 		<link>
 			<name>generated</name>
 			<type>2</type>
-			<locationURI>PARENT-1-PROJECT_LOC/build/linux/linux_amd64_compiler1/generated</locationURI>
+			<locationURI>PARENT-1-PROJECT_LOC/build/linux/linux_amd64_graal/generated</locationURI>
 		</link>
 		<link>
 			<name>os</name>
--- a/hotspot/.settings/org.eclipse.core.runtime.prefs	Wed Jan 11 18:25:25 2012 +0100
+++ b/hotspot/.settings/org.eclipse.core.runtime.prefs	Wed Jan 11 18:25:56 2012 +0100
@@ -1,6 +1,6 @@
 #Wed Sep 01 16:13:40 PDT 2010
 content-types/enabled=true
-content-types/org.eclipse.cdt.core.cHeader/file-extensions=hpp,incl
+content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=hpp,incl
 content-types/org.eclipse.cdt.core.cxxSource/file-extensions=cpp
 eclipse.preferences.version=1