changeset 12358:c2407e223244

Merge
author Gilles Duboscq <duboscq@ssw.jku.at>
date Fri, 11 Oct 2013 17:53:29 +0200
parents 36b1f3224948 (current diff) bba234a1670e (diff)
children e800bf0c230c
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java
diffstat 160 files changed, 1000 insertions(+), 964 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Fri Oct 11 17:53:29 2013 +0200
@@ -26,7 +26,7 @@
 import com.oracle.graal.api.meta.*;
 
 /**
- * Encapsulates the main functionality of the runtime for the compiler.
+ * Access to code cache related details and requirements.
  */
 public interface CodeCacheProvider {
 
@@ -56,7 +56,7 @@
     /**
      * Gets the register configuration to use when compiling a given method.
      */
-    RegisterConfig lookupRegisterConfig();
+    RegisterConfig getRegisterConfig();
 
     /**
      * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Fri Oct 11 17:53:29 2013 +0200
@@ -339,7 +339,7 @@
             argTypes[argIndex++] = sig.getParameterType(i, null);
         }
 
-        RegisterConfig registerConfig = codeCache.lookupRegisterConfig();
+        RegisterConfig registerConfig = codeCache.getRegisterConfig();
         return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget(), stackOnly);
     }
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java	Fri Oct 11 17:52:33 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.code;
-
-import com.oracle.graal.api.meta.*;
-
-/**
- * A {@link CodeCacheProvider} that delegates to another {@link CodeCacheProvider}.
- */
-public class DelegatingCodeCacheProvider implements CodeCacheProvider {
-
-    private final CodeCacheProvider delegate;
-
-    public DelegatingCodeCacheProvider(CodeCacheProvider delegate) {
-        this.delegate = delegate;
-    }
-
-    protected CodeCacheProvider delegate() {
-        return delegate;
-    }
-
-    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
-        return delegate().addMethod(method, compResult);
-    }
-
-    public String disassemble(CompilationResult compResult, InstalledCode installedCode) {
-        return delegate().disassemble(compResult, installedCode);
-    }
-
-    public RegisterConfig lookupRegisterConfig() {
-        return delegate().lookupRegisterConfig();
-    }
-
-    public int getMinimumOutgoingSize() {
-        return delegate().getMinimumOutgoingSize();
-    }
-
-    public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
-        return delegate().lookupForeignCall(descriptor);
-    }
-
-    public boolean needsDataPatch(Constant constant) {
-        return delegate().needsDataPatch(constant);
-    }
-
-    public TargetDescription getTarget() {
-        return delegate().getTarget();
-    }
-}
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Fri Oct 11 17:53:29 2013 +0200
@@ -96,9 +96,9 @@
         for (Constant c1 : constants) {
             for (Constant c2 : constants) {
                 // test symmetry
-                assertEquals(metaAccess.constantEquals(c1, c2), metaAccess.constantEquals(c2, c1));
+                assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1));
                 if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) {
-                    assertEquals(c1.equals(c2), metaAccess.constantEquals(c2, c1));
+                    assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1));
                 }
             }
         }
@@ -107,7 +107,7 @@
     @Test
     public void lookupArrayLengthTest() {
         for (Constant c : constants) {
-            Integer actual = metaAccess.lookupArrayLength(c);
+            Integer actual = constantReflection.lookupArrayLength(c);
             if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) {
                 assertNull(actual);
             } else {
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java	Fri Oct 11 17:53:29 2013 +0200
@@ -41,6 +41,7 @@
 
     public final Unsafe unsafe;
     public final MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+    public final ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
     public final Collection<Class<?>> classes = new HashSet<>();
     public final Map<Class<?>, Class<?>> arrayClasses = new HashMap<>();
     public final List<Constant> constants = new ArrayList<>();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Fri Oct 11 17:53:29 2013 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Reflection operations on values represented as {@linkplain Constant constants}.
+ */
+public interface ConstantReflectionProvider {
+
+    /**
+     * Compares two constants for equality. The equality relationship is symmetric.
+     * 
+     * @return {@code true} if the two parameters represent the same runtime object, {@code false}
+     *         otherwise
+     */
+    boolean constantEquals(Constant x, Constant y);
+
+    /**
+     * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array}
+     * is not an array, or the array length is not available at this point, the return value is
+     * {@code null}.
+     */
+    Integer lookupArrayLength(Constant array);
+
+    /**
+     * Reads a value of this kind using a base address and a displacement.
+     * 
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @param compressible whether this is a read of a compressed or an uncompressed pointer
+     * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the
+     *         value cannot be read.
+     */
+    Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible);
+}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java	Fri Oct 11 17:52:33 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.meta;
-
-import java.lang.reflect.*;
-
-/**
- * A {@link MetaAccessProvider} that delegates to another {@link MetaAccessProvider}.
- */
-public class DelegatingMetaAccessProvider implements MetaAccessProvider {
-
-    private final MetaAccessProvider delegate;
-
-    public DelegatingMetaAccessProvider(MetaAccessProvider delegate) {
-        this.delegate = delegate;
-    }
-
-    protected MetaAccessProvider delegate() {
-        return delegate;
-    }
-
-    public ResolvedJavaType lookupJavaType(Class<?> clazz) {
-        return delegate.lookupJavaType(clazz);
-    }
-
-    public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) {
-        return delegate.lookupJavaMethod(reflectionMethod);
-    }
-
-    public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) {
-        return delegate.lookupJavaConstructor(reflectionConstructor);
-    }
-
-    public ResolvedJavaField lookupJavaField(Field reflectionField) {
-        return delegate.lookupJavaField(reflectionField);
-    }
-
-    public ResolvedJavaType lookupJavaType(Constant constant) {
-        return delegate.lookupJavaType(constant);
-    }
-
-    public Signature parseMethodDescriptor(String methodDescriptor) {
-        return delegate.parseMethodDescriptor(methodDescriptor);
-    }
-
-    public boolean constantEquals(Constant x, Constant y) {
-        return delegate.constantEquals(x, y);
-    }
-
-    public Integer lookupArrayLength(Constant array) {
-        return delegate.lookupArrayLength(array);
-    }
-
-    public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) {
-        return delegate.readUnsafeConstant(kind, base, displacement, compressible);
-    }
-
-    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
-        return delegate.isReexecutable(descriptor);
-    }
-
-    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
-        return delegate.getKilledLocations(descriptor);
-    }
-
-    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
-        return delegate.canDeoptimize(descriptor);
-    }
-
-    public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
-        return delegate().encodeDeoptActionAndReason(action, reason);
-    }
-}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Fri Oct 11 17:53:29 2013 +0200
@@ -25,7 +25,7 @@
 import java.lang.reflect.*;
 
 /**
- * Interface implemented by the runtime to allow access to its metadata.
+ * Provides access to the metadata of a class typically provided in a class file.
  */
 public interface MetaAccessProvider {
 
@@ -68,35 +68,6 @@
     Signature parseMethodDescriptor(String methodDescriptor);
 
     /**
-     * Compares two constants for equality. This is used instead of {@link Constant#equals(Object)}
-     * in case the runtime has an interpretation for object equality other than
-     * {@code x.asObject() == y.asObject()}. For primitive constants, this is equivalent to calling
-     * {@code x.equals(y)}. The equality relationship is symmetric.
-     * 
-     * @return {@code true} if the two parameters represent the same runtime object, {@code false}
-     *         otherwise
-     */
-    boolean constantEquals(Constant x, Constant y);
-
-    /**
-     * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array}
-     * is not an array, or the array length is not available at this point, the return value is
-     * {@code null}.
-     */
-    Integer lookupArrayLength(Constant array);
-
-    /**
-     * Reads a value of this kind using a base address and a displacement.
-     * 
-     * @param base the base address from which the value is read
-     * @param displacement the displacement within the object in bytes
-     * @param compressible whether this is a read of a compressed or an uncompressed pointer
-     * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the
-     *         value cannot be read.
-     */
-    Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible);
-
-    /**
      * Determines if a given foreign call is side-effect free. Deoptimization cannot return
      * execution to a point before a foreign call that has a side effect.
      */
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -53,7 +53,7 @@
 
     protected InstalledCode assembleMethod(Method m, CodeGenTest test) {
         ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(m);
-        RegisterConfig registerConfig = codeCache.lookupRegisterConfig();
+        RegisterConfig registerConfig = codeCache.getRegisterConfig();
         CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false);
 
         CompilationResult compResult = new CompilationResult();
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java	Fri Oct 11 17:53:29 2013 +0200
@@ -23,27 +23,20 @@
 
 package com.oracle.graal.compiler.hsail;
 
-import com.oracle.graal.api.code.CompilationResult;
-import java.lang.reflect.Method;
+import java.lang.reflect.*;
 
-import com.amd.okra.OkraContext;
-import com.amd.okra.OkraKernel;
-import com.oracle.graal.hotspot.HotSpotGraalRuntime;
-import com.oracle.graal.hotspot.HotSpotVMConfig;
-import com.oracle.graal.hotspot.amd64.AMD64HotSpotRuntime;
+import com.amd.okra.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.Graal;
-import com.oracle.graal.java.GraphBuilderConfiguration;
-import com.oracle.graal.java.GraphBuilderPhase;
-import com.oracle.graal.nodes.StructuredGraph;
-import com.oracle.graal.nodes.java.MethodCallTargetNode;
-import com.oracle.graal.nodes.spi.Replacements;
-import com.oracle.graal.phases.OptimisticOptimizations;
-import com.oracle.graal.graph.Node;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
-import com.oracle.graal.compiler.target.Backend;
-import com.oracle.graal.nodes.spi.GraalCodeCacheProvider;
-import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.amd64.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
 
 /**
  * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by
@@ -51,16 +44,6 @@
  */
 public class ForEachToGraal implements CompileAndDispatch {
 
-    protected final GraalCodeCacheProvider runtime;
-    protected final Replacements replacements;
-    protected final Backend backend;
-
-    public ForEachToGraal() {
-        this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
-        this.replacements = Graal.getRequiredCapability(Replacements.class);
-        this.backend = Graal.getRequiredCapability(Backend.class);
-    }
-
     private static CompilationResult getCompiledLambda(Class consumerClass) {
         /**
          * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java	Fri Oct 11 17:53:29 2013 +0200
@@ -69,12 +69,12 @@
      */
     @Override
     public FrameMap newFrameMap() {
-        return new HSAILFrameMap(runtime(), target, new HSAILRegisterConfig());
+        return new HSAILFrameMap(getCodeCache(), target, new HSAILRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new HSAILLIRGenerator(graph, metaAccess(), runtime(), target, frameMap, cc, lir);
+        return new HSAILLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir);
     }
 
     public String getPartialCodeString() {
@@ -104,7 +104,7 @@
         FrameMap frameMap = lirGen.frameMap;
         AbstractAssembler masm = new HSAILAssembler(target);
         HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
         return tasm;
     }
@@ -142,12 +142,12 @@
         int pidx = 0;
         for (int i = 0; i < totalParamCount; i++) {
             if (i == 0 && !isStatic) {
-                paramtypes[i] = metaAccess().lookupJavaType(Object.class);
+                paramtypes[i] = getMetaAccess().lookupJavaType(Object.class);
                 paramNames[i] = "%_this";
             } else if (i < nonConstantParamCount) {
                 if (isObjectLambda && (i == (nonConstantParamCount))) {
                     // Set up the gid register mapping.
-                    paramtypes[i] = metaAccess().lookupJavaType(int.class);
+                    paramtypes[i] = getMetaAccess().lookupJavaType(int.class);
                     paramNames[i] = "%_gid";
                 } else {
                     paramtypes[i] = signature.getParameterType(pidx++, null);
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java	Fri Oct 11 17:53:29 2013 +0200
@@ -36,11 +36,11 @@
 import com.oracle.graal.hsail.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code.
@@ -114,21 +114,19 @@
 
     public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
         Debug.dump(graph, "Graph");
+        Providers providers = GraalCompiler.getGraalProviders();
         TargetDescription target = new TargetDescription(new HSAIL(), true, 8, 0, true);
-        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        GraalCodeCacheProvider codeCache = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
-        HSAILBackend hsailBackend = new HSAILBackend(metaAccess, codeCache, target);
+        HSAILBackend hsailBackend = new HSAILBackend(providers.getMetaAccess(), providers.getCodeCache(), target);
         PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, new HSAILPhase());
         new HSAILPhase().apply(graph);
         CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false);
-        Replacements replacements = Graal.getRequiredCapability(Replacements.class);
         SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class);
         try {
-            CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), metaAccess, codeCache, replacements, hsailBackend, target, null, phasePlan,
-                            OptimisticOptimizations.NONE, new SpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult());
+            CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(),
+                            suitesProvider.getDefaultSuites(), new CompilationResult());
             return new HSAILCompilationResult(compResult);
         } catch (GraalInternalError e) {
             String partialCode = hsailBackend.getPartialCodeString();
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Fri Oct 11 17:53:29 2013 +0200
@@ -23,7 +23,6 @@
 package com.oracle.graal.compiler.ptx.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
@@ -77,8 +76,8 @@
              * Ultimately we might want to have both the kernel and the code natively compiled for
              * GPU fallback to CPU in cases of ECC failure on kernel invocation.
              */
-            CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), getMetaAccess(), getCodeCache(), graalRuntime().getReplacements(), ptxBackend, target, null, phasePlan,
-                            OptimisticOptimizations.NONE, new SpeculationLog(), Suites.createDefaultSuites(), new ExternalCompilationResult());
+            CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE,
+                            new SpeculationLog(), Suites.createDefaultSuites(), new ExternalCompilationResult());
             return result;
         } else {
             return null;
@@ -104,7 +103,7 @@
             boolean isStatic = Modifier.isStatic(compiledMethod.getModifiers());
             Object[] executeArgs = argsWithReceiver((isStatic ? null : this), args);
             HotSpotRuntime hsr = (HotSpotRuntime) getCodeCache();
-            InstalledCode installedCode = hsr.addExternalMethod(compiledMethod, result, sg);
+            InstalledCode installedCode = hsr.addExternalMethod(compiledMethod, result);
             Annotation[][] params = compiledMethod.getParameterAnnotations();
 
             int dimensionX = 1;
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java	Fri Oct 11 17:53:29 2013 +0200
@@ -59,12 +59,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new PTXFrameMap(runtime(), target, runtime().lookupRegisterConfig());
+        return new PTXFrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new PTXLIRGenerator(graph, metaAccess(), runtime(), target, frameMap, cc, lir);
+        return new PTXLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir);
     }
 
     class HotSpotFrameContext implements FrameContext {
@@ -94,7 +94,7 @@
         FrameMap frameMap = lirGen.frameMap;
         AbstractAssembler masm = createAssembler(frameMap);
         HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        TargetMethodAssembler tasm = new PTXTargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new PTXTargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(0);
         return tasm;
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -307,7 +307,7 @@
     private void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
     }
@@ -324,7 +324,7 @@
                 graph = parse(snippet);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 if (loopPeeling) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -36,7 +36,7 @@
 
     private StructuredGraph getCanonicalizedGraph(String name) {
         StructuredGraph graph = parse(name);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         return graph;
     }
 
@@ -54,7 +54,7 @@
             assertEquals(referenceGraph, graph);
         }
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
         for (int i = 1; i < 4; i++) {
             StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i);
             assertEquals(referenceGraph, graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -142,7 +142,7 @@
 
         StructuredGraph graph = parse("testNullnessSnippet");
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) {
             assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
         }
@@ -164,7 +164,7 @@
     @Test
     public void testDisjunction() {
         StructuredGraph graph = parse("testDisjunctionSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         IfNode ifNode = (IfNode) graph.start().next();
         InstanceOfNode instanceOf = (InstanceOfNode) ifNode.condition();
         IsNullNode x = graph.unique(new IsNullNode(graph.getLocal(0)));
@@ -172,9 +172,9 @@
         ShortCircuitOrNode disjunction = graph.unique(new ShortCircuitOrNode(x, false, y, false, NOT_FREQUENT_PROBABILITY));
         LogicNegationNode negation = graph.unique(new LogicNegationNode(disjunction));
         ifNode.setCondition(negation);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) {
             assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
         }
@@ -192,7 +192,7 @@
     public void testInvoke() {
         test("testInvokeSnippet", new Integer(16));
         StructuredGraph graph = parse("testInvokeSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
 
         InvokeNode invoke = graph.getNodes().filter(InvokeNode.class).first();
@@ -222,9 +222,9 @@
     @Test
     public void testTypeMerging() {
         StructuredGraph graph = parse("testTypeMergingSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
 
         assertEquals(0, graph.getNodes().filter(StoreFieldNode.class).count());
     }
@@ -239,9 +239,9 @@
     @Test
     public void testInstanceOfCheckCast() {
         StructuredGraph graph = parse("testInstanceOfCheckCastSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
 
         assertEquals(0, graph.getNodes().filter(CheckCastNode.class).count());
     }
@@ -252,7 +252,7 @@
         StructuredGraph graph = parse("testInstanceOfCheckCastSnippet");
 
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-        PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements);
+        PhaseContext context = new PhaseContext(getProviders(), null);
 
         new LoweringPhase(canonicalizer).apply(graph, context);
         canonicalizer.apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -82,7 +82,7 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new CanonicalizerPhase(true).apply(graph, context);
                 Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -114,7 +114,7 @@
             public StructuredGraph call() throws Exception {
                 Debug.dump(graph, "After parsing: " + snippet);
                 Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count());
-                new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements));
+                new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
                 Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count());
                 return graph;
             }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -68,7 +68,7 @@
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault();
         new GraphBuilderPhase(getMetaAccess(), conf, OptimisticOptimizations.ALL).apply(graph);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         return graph;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -58,7 +58,7 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements);
+                PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new FloatingReadPhase().apply(graph);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -52,6 +52,7 @@
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.test.*;
 
@@ -76,16 +77,20 @@
  */
 public abstract class GraalCompilerTest extends GraalTest {
 
-    private final GraalCodeCacheProvider codeCache;
+    private final CodeCacheProvider codeCache;
     private final MetaAccessProvider metaAccess;
-    protected final Replacements replacements;
+    private final ConstantReflectionProvider constantReflection;
+    private final LoweringProvider lowerer;
+    private final Replacements replacements;
     protected final Backend backend;
     protected final Suites suites;
 
     public GraalCompilerTest() {
         this.replacements = Graal.getRequiredCapability(Replacements.class);
         this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        this.codeCache = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+        this.constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
+        this.codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
+        this.lowerer = Graal.getRequiredCapability(LoweringProvider.class);
         this.backend = Graal.getRequiredCapability(Backend.class);
         this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
     }
@@ -160,14 +165,26 @@
         return result.toString();
     }
 
-    protected GraalCodeCacheProvider getCodeCache() {
+    protected Providers getProviders() {
+        return new Providers(metaAccess, codeCache, constantReflection, lowerer, getReplacements());
+    }
+
+    protected CodeCacheProvider getCodeCache() {
         return codeCache;
     }
 
+    protected ConstantReflectionProvider getConstantReflection() {
+        return constantReflection;
+    }
+
     protected MetaAccessProvider getMetaAccess() {
         return metaAccess;
     }
 
+    protected LoweringProvider getLowerer() {
+        return lowerer;
+    }
+
     /**
      * Parses a Java method to produce a graph.
      * 
@@ -462,7 +479,7 @@
 
         final int id = compilationId.incrementAndGet();
 
-        InstalledCode installedCode = Debug.scope("Compiling", new Object[]{getCodeCache(), new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() {
+        InstalledCode installedCode = Debug.scope("Compiling", new Object[]{new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() {
 
             public InstalledCode call() throws Exception {
                 final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
@@ -474,7 +491,7 @@
                 GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
                 phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                 CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-                final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, metaAccess, getCodeCache(), replacements, backend, getCodeCache().getTarget(), null, phasePlan,
+                final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan,
                                 OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult());
                 if (printCompilation) {
                     TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
@@ -567,4 +584,8 @@
         plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(metaAccess, gbConf, OptimisticOptimizations.ALL));
         return plan;
     }
+
+    protected Replacements getReplacements() {
+        return replacements;
+    }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -145,7 +145,7 @@
             n.replaceFirstInput(local, constant);
         }
         Debug.dump(graph, "Graph");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         for (FrameState fs : local.usages().filter(FrameState.class).snapshot()) {
             fs.replaceFirstInput(local, null);
         }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -59,7 +59,7 @@
         final Method method = getMethod("testMethod");
         final StructuredGraph graph = parse(method);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getMetaAccess(), getCodeCache(), replacements, backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(),
+        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(),
                         OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult());
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
@@ -81,7 +81,7 @@
         }
         assertTrue(graphLineSPs > 0);
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getMetaAccess(), getCodeCache(), replacements, backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(true),
+        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(true),
                         OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult());
         int lineSPs = 0;
         for (Infopoint sp : cr.getInfopoints()) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -66,7 +66,7 @@
             hints.put(invoke, 1000d);
         }
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -77,7 +77,7 @@
         }
 
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -61,7 +61,7 @@
         test("testSynchronizedSnippet", new A(), new A());
 
         StructuredGraph graph = getGraph("testSynchronizedSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new LockEliminationPhase().apply(graph);
         assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
         assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -79,7 +79,7 @@
         test("testSynchronizedMethodSnippet", new A());
 
         StructuredGraph graph = getGraph("testSynchronizedMethodSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new LockEliminationPhase().apply(graph);
         assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
         assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -90,7 +90,7 @@
         StructuredGraph graph = parse(method);
         PhasePlan phasePlan = getDefaultPhasePlan();
         Assumptions assumptions = new Assumptions(true);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
         new CanonicalizerPhase(true).apply(graph, context);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -134,8 +134,8 @@
         }
 
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
         Debug.scope("Test", new DebugDumpScope("Test:" + snippet), new Runnable() {
 
             @Override
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -553,7 +553,8 @@
             @Override
             public SchedulePhase call() throws Exception {
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(),
+                                OptimisticOptimizations.ALL);
                 new CanonicalizerPhase(true).apply(graph, context);
                 if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
                     new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
@@ -575,7 +576,8 @@
                 new FloatingReadPhase().apply(graph);
                 new RemoveValueProxyPhase().apply(graph);
 
-                MidTierContext midContext = new MidTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+                MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(),
+                                OptimisticOptimizations.ALL);
                 new GuardLoweringPhase().apply(graph, midContext);
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext);
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -94,7 +94,7 @@
             hints.put(invoke, 1000d);
         }
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -91,7 +91,7 @@
 
     private StructuredGraph compileTestSnippet(final String snippet) {
         StructuredGraph graph = parse(snippet);
-        PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements);
+        PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
         new LoweringPhase(canonicalizer).apply(graph, context);
         canonicalizer.apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -83,7 +83,7 @@
             // structure changes significantly
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements);
+                PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new FloatingReadPhase().apply(graph);
                 new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -245,9 +245,9 @@
     private <T extends Node & IterableNodeType> void test(String test, String ref) {
         StructuredGraph testGraph = parse(test);
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getProviders(), assumptions));
         StructuredGraph refGraph = parse(ref);
-        new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getProviders(), assumptions));
         assertEquals(testGraph, refGraph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -167,9 +167,9 @@
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         StructuredGraph referenceGraph = parse(referenceSnippet);
         assertEquals(referenceGraph, graph);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -110,7 +110,7 @@
 
     private void testZeroReturn(String methodName) {
         StructuredGraph graph = parse(methodName);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         new DeadCodeEliminationPhase().apply(graph);
         assertConstantReturn(graph, 0);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -90,7 +90,7 @@
         // No debug scope to reduce console noise for @Test(expected = ...) tests
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
         assertEquals(referenceGraph, graph);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -185,13 +185,13 @@
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         // a second canonicalizer is needed to process nested MaterializeNodes
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         StructuredGraph referenceGraph = parse(referenceSnippet);
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
         assertEquals(referenceGraph, graph);
     }
 
@@ -241,9 +241,9 @@
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         Debug.dump(graph, "Graph");
         Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -119,7 +119,7 @@
 
             @Override
             public LIR call() {
-                return GraalCompiler.emitHIR(getMetaAccess(), getCodeCache(), backend.target, graph, replacements, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites);
+                return GraalCompiler.emitHIR(getProviders(), backend.target, graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites);
             }
         });
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -56,7 +56,7 @@
     public void test1() {
         Method method = getMethod("testMethod");
         final StructuredGraph graph = parse(method);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         new DeadCodeEliminationPhase().apply(graph);
 
         for (Node node : graph.getNodes()) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -41,7 +41,7 @@
     protected void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new EarlyReadEliminationPhase(new CanonicalizerPhase(true)).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -233,7 +233,7 @@
                 new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
                 new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -88,7 +88,7 @@
 
     private void processMethod(final String snippet) {
         graph = parse(snippet);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new IterativeInliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -243,7 +243,7 @@
     protected void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new PartialEscapePhase(false, true, new CanonicalizerPhase(true)).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -198,7 +198,7 @@
                 StructuredGraph graph = parse(snippet);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
                 new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -237,7 +237,7 @@
                 StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method);
                 PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode);
                 Assumptions assumptions = new Assumptions(true);
-                HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
                 Debug.dump(graph, "Graph");
                 new CanonicalizerPhase(true).apply(graph, context);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Oct 11 17:53:29 2013 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.alloc.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -50,6 +51,7 @@
 import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * Static methods for orchestrating the compilation of a {@linkplain StructuredGraph graph}.
@@ -131,10 +133,10 @@
      *            argument can be null.
      * @return the result of the compilation
      */
-    public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final MetaAccessProvider metaAccess,
-                    final GraalCodeCacheProvider codeCache, final Replacements replacements, final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan,
-                    final OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites, final CompilationResult compilationResult) {
-        Debug.scope("GraalCompiler", new Object[]{graph, codeCache}, new Runnable() {
+    public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers,
+                    final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts,
+                    final SpeculationLog speculationLog, final Suites suites, final CompilationResult compilationResult) {
+        Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Runnable() {
 
             public void run() {
                 final Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
@@ -142,7 +144,7 @@
 
                     public LIR call() {
                         try (TimerCloseable a = FrontEnd.start()) {
-                            return emitHIR(metaAccess, codeCache, target, graph, replacements, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
+                            return emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
                         }
                     }
                 });
@@ -179,13 +181,9 @@
 
     /**
      * Builds the graph, optimizes it.
-     * 
-     * @param metaAccess
-     * @param codeCache
-     * @param target
      */
-    public static LIR emitHIR(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, TargetDescription target, final StructuredGraph graph, Replacements replacements,
-                    Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) {
+    public static LIR emitHIR(Providers providers, TargetDescription target, final StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan,
+                    OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) {
 
         if (speculationLog != null) {
             speculationLog.snapshot();
@@ -198,13 +196,13 @@
             Debug.dump(graph, "initial state");
         }
 
-        HighTierContext highTierContext = new HighTierContext(metaAccess, codeCache, assumptions, replacements, cache, plan, optimisticOpts);
+        HighTierContext highTierContext = new HighTierContext(providers, assumptions, cache, plan, optimisticOpts);
         suites.getHighTier().apply(graph, highTierContext);
 
-        MidTierContext midTierContext = new MidTierContext(metaAccess, codeCache, assumptions, replacements, target, optimisticOpts);
+        MidTierContext midTierContext = new MidTierContext(providers, assumptions, target, optimisticOpts);
         suites.getMidTier().apply(graph, midTierContext);
 
-        LowTierContext lowTierContext = new LowTierContext(metaAccess, codeCache, assumptions, replacements, target);
+        LowTierContext lowTierContext = new LowTierContext(providers, assumptions, target);
         suites.getLowTier().apply(graph, lowTierContext);
 
         // we do not want to store statistics about OSR compilations because it may prevent inlining
@@ -288,4 +286,16 @@
 
         Debug.dump(result, "After code generation");
     }
+
+    /**
+     * Creates a set of providers via {@link Graal#getRequiredCapability(Class)}.
+     */
+    public static Providers getGraalProviders() {
+        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
+        ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
+        LoweringProvider lowerer = Graal.getRequiredCapability(LoweringProvider.class);
+        Replacements replacements = Graal.getRequiredCapability(Replacements.class);
+        return new Providers(metaAccess, codeCache, constantReflection, lowerer, replacements);
+    }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Fri Oct 11 17:53:29 2013 +0200
@@ -36,21 +36,21 @@
 public abstract class Backend {
 
     private final MetaAccessProvider metaAccess;
-    private final CodeCacheProvider runtime;
+    private final CodeCacheProvider codeCache;
     public final TargetDescription target;
 
     protected Backend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target) {
         this.metaAccess = metaAccess;
-        this.runtime = codeCache;
+        this.codeCache = codeCache;
         this.target = target;
     }
 
-    public MetaAccessProvider metaAccess() {
+    public MetaAccessProvider getMetaAccess() {
         return metaAccess;
     }
 
-    public CodeCacheProvider runtime() {
-        return runtime;
+    public CodeCacheProvider getCodeCache() {
+        return codeCache;
     }
 
     public abstract FrameMap newFrameMap();
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Fri Oct 11 17:53:29 2013 +0200
@@ -445,22 +445,19 @@
     }
 
     /**
-     * An iterator that will iterate over the fields given in {@link #offsets}. The first
-     * {@link #directCount} offsets are treated as fields of type {@link Node}, while the rest of
-     * the fields are treated as {@link NodeList}s. All elements of these NodeLists will be visited
-     * by the iterator as well. This iterator can be used to iterate over the inputs or successors
-     * of a node.
+     * An iterator that will iterate over the fields given in {@link #getOffsets()}. The first
+     * {@link #getDirectCount()} offsets are treated as fields of type {@link Node}, while the rest
+     * of the fields are treated as {@link NodeList}s. All elements of these NodeLists will be
+     * visited by the iterator as well. This iterator can be used to iterate over the inputs or
+     * successors of a node.
      * 
      * An iterator of this type will not return null values, unless the field values are modified
      * concurrently. Concurrent modifications are detected by an assertion on a best-effort basis.
      */
-    public static final class NodeClassIterator implements Iterator<Node> {
+    public abstract static class NodeClassIterator implements Iterator<Node> {
 
         private final NodeClass nodeClass;
-        private final Node node;
-        private final int modCount;
-        private final int directCount;
-        private final long[] offsets;
+        protected final Node node;
         private int index;
         private int subIndex;
 
@@ -468,26 +465,19 @@
          * Creates an iterator that will iterate over fields in the given node.
          * 
          * @param node the node which contains the fields.
-         * @param offsets the offsets of the fields.
-         * @param directCount the number of fields that should be treated as fields of type
-         *            {@link Node}, the rest are treated as {@link NodeList}s.
          */
-        private NodeClassIterator(Node node, long[] offsets, int directCount) {
+        NodeClassIterator(Node node) {
             this.node = node;
             this.nodeClass = node.getNodeClass();
-            this.modCount = MODIFICATION_COUNTS_ENABLED ? node.modCount() : 0;
-            this.offsets = offsets;
-            this.directCount = directCount;
             index = NOT_ITERABLE;
             subIndex = 0;
-            forward();
         }
 
-        private void forward() {
-            if (index < directCount) {
+        void forward() {
+            if (index < getDirectCount()) {
                 index++;
-                while (index < directCount) {
-                    Node element = getNode(node, offsets[index]);
+                while (index < getDirectCount()) {
+                    Node element = getNode(node, getOffsets()[index]);
                     if (element != null) {
                         return;
                     }
@@ -496,8 +486,8 @@
             } else {
                 subIndex++;
             }
-            while (index < offsets.length) {
-                NodeList<Node> list = getNodeList(node, offsets[index]);
+            while (index < getOffsets().length) {
+                NodeList<Node> list = getNodeList(node, getOffsets()[index]);
                 while (subIndex < list.size()) {
                     if (list.get(subIndex) != null) {
                         return;
@@ -510,10 +500,10 @@
         }
 
         private Node nextElement() {
-            if (index < directCount) {
-                return getNode(node, offsets[index]);
-            } else if (index < offsets.length) {
-                NodeList<Node> list = getNodeList(node, offsets[index]);
+            if (index < getDirectCount()) {
+                return getNode(node, getOffsets()[index]);
+            } else if (index < getOffsets().length) {
+                NodeList<Node> list = getNodeList(node, getOffsets()[index]);
                 return list.get(subIndex);
             }
             throw new NoSuchElementException();
@@ -521,8 +511,77 @@
 
         @Override
         public boolean hasNext() {
+            return index < getOffsets().length;
+        }
+
+        @Override
+        public Node next() {
             try {
-                return index < offsets.length;
+                return nextElement();
+            } finally {
+                forward();
+            }
+        }
+
+        public Position nextPosition() {
+            try {
+                if (index < getDirectCount()) {
+                    return new Position(getOffsets() == nodeClass.inputOffsets, index, NOT_ITERABLE);
+                } else {
+                    return new Position(getOffsets() == nodeClass.inputOffsets, index, subIndex);
+                }
+            } finally {
+                forward();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        protected abstract int getDirectCount();
+
+        protected abstract long[] getOffsets();
+    }
+
+    private class NodeClassInputsIterator extends NodeClassIterator {
+        NodeClassInputsIterator(Node node) {
+            this(node, true);
+        }
+
+        NodeClassInputsIterator(Node node, boolean forward) {
+            super(node);
+            if (forward) {
+                forward();
+            }
+        }
+
+        @Override
+        protected int getDirectCount() {
+            return directInputCount;
+        }
+
+        @Override
+        protected long[] getOffsets() {
+            return inputOffsets;
+        }
+    }
+
+    private final class NodeClassInputsWithModCountIterator extends NodeClassInputsIterator {
+        private final int modCount;
+
+        private NodeClassInputsWithModCountIterator(Node node) {
+            super(node, false);
+            assert MODIFICATION_COUNTS_ENABLED;
+            this.modCount = node.modCount();
+            forward();
+        }
+
+        @Override
+        public boolean hasNext() {
+            try {
+                return super.hasNext();
             } finally {
                 assert modCount == node.modCount() : "must not be modified";
             }
@@ -531,29 +590,80 @@
         @Override
         public Node next() {
             try {
-                return nextElement();
+                return super.next();
             } finally {
-                forward();
-                assert modCount == node.modCount();
+                assert modCount == node.modCount() : "must not be modified";
             }
         }
 
+        @Override
         public Position nextPosition() {
             try {
-                if (index < directCount) {
-                    return new Position(offsets == nodeClass.inputOffsets, index, NOT_ITERABLE);
-                } else {
-                    return new Position(offsets == nodeClass.inputOffsets, index, subIndex);
-                }
+                return super.nextPosition();
             } finally {
+                assert modCount == node.modCount();
+            }
+        }
+    }
+
+    private class NodeClassSuccessorsIterator extends NodeClassIterator {
+        NodeClassSuccessorsIterator(Node node) {
+            this(node, true);
+        }
+
+        NodeClassSuccessorsIterator(Node node, boolean forward) {
+            super(node);
+            if (forward) {
                 forward();
-                assert modCount == node.modCount();
             }
         }
 
         @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
+        protected int getDirectCount() {
+            return directSuccessorCount;
+        }
+
+        @Override
+        protected long[] getOffsets() {
+            return successorOffsets;
+        }
+    }
+
+    private final class NodeClassSuccessorsWithModCountIterator extends NodeClassSuccessorsIterator {
+        private final int modCount;
+
+        private NodeClassSuccessorsWithModCountIterator(Node node) {
+            super(node, false);
+            assert MODIFICATION_COUNTS_ENABLED;
+            this.modCount = node.modCount();
+            forward();
+        }
+
+        @Override
+        public boolean hasNext() {
+            try {
+                return super.hasNext();
+            } finally {
+                assert modCount == node.modCount() : "must not be modified";
+            }
+        }
+
+        @Override
+        public Node next() {
+            try {
+                return super.next();
+            } finally {
+                assert modCount == node.modCount() : "must not be modified";
+            }
+        }
+
+        @Override
+        public Position nextPosition() {
+            try {
+                return super.nextPosition();
+            } finally {
+                assert modCount == node.modCount();
+            }
         }
     }
 
@@ -808,7 +918,11 @@
 
             @Override
             public NodeClassIterator iterator() {
-                return new NodeClassIterator(node, inputOffsets, directInputCount);
+                if (MODIFICATION_COUNTS_ENABLED) {
+                    return new NodeClassInputsWithModCountIterator(node);
+                } else {
+                    return new NodeClassInputsIterator(node);
+                }
             }
 
             @Override
@@ -824,7 +938,11 @@
 
             @Override
             public NodeClassIterator iterator() {
-                return new NodeClassIterator(node, successorOffsets, directSuccessorCount);
+                if (MODIFICATION_COUNTS_ENABLED) {
+                    return new NodeClassSuccessorsWithModCountIterator(node);
+                } else {
+                    return new NodeClassSuccessorsIterator(node);
+                }
             }
 
             @Override
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java	Fri Oct 11 17:53:29 2013 +0200
@@ -32,6 +32,8 @@
 
     MetaAccessProvider getMetaAccess();
 
+    ConstantReflectionProvider getConstantReflection();
+
     boolean canonicalizeReads();
 
     void removeIfUnused(Node node);
--- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -101,7 +101,7 @@
         InstalledCode installedCode = getCode(javaMethod, parse(method));
 
         TargetDescription target = getCodeCache().getTarget();
-        RegisterConfig registerConfig = getCodeCache().lookupRegisterConfig();
+        RegisterConfig registerConfig = getCodeCache().getRegisterConfig();
         AMD64Assembler asm = new AMD64Assembler(target, registerConfig);
 
         gen.generateCode(asm);
@@ -115,7 +115,7 @@
     }
 
     private Register getArgumentRegister(int index, Kind kind) {
-        Register[] regs = getCodeCache().lookupRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, kind);
+        Register[] regs = getCodeCache().getRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, kind);
         return regs[index];
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Oct 11 17:53:29 2013 +0200
@@ -69,12 +69,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new AMD64FrameMap(runtime(), target, runtime().lookupRegisterConfig());
+        return new AMD64FrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new AMD64HotSpotLIRGenerator(graph, runtime(), runtime(), target, frameMap, cc, lir);
+        return new AMD64HotSpotLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir);
     }
 
     /**
@@ -174,7 +174,7 @@
         Stub stub = gen.getStub();
         AbstractAssembler masm = createAssembler(frameMap);
         HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext(stub != null);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
         StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot;
         if (deoptimizationRescueSlot != null && stub == null) {
@@ -235,13 +235,13 @@
         AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
         FrameMap frameMap = tasm.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
-        HotSpotVMConfig config = runtime().config;
+        HotSpotVMConfig config = getRuntime().config;
         Label verifiedStub = new Label();
 
         // Emit the prefix
         if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) {
             tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
-            CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{runtime().lookupJavaType(Object.class)}, target, false);
+            CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{getRuntime().lookupJavaType(Object.class)}, target, false);
             Register inlineCacheKlass = rax; // see definition of IC_Klass in
                                              // c1_LIRAssembler_x86.cpp
             Register receiver = asRegister(cc.getArgument(0));
@@ -256,7 +256,7 @@
             } else {
                 asm.cmpq(inlineCacheKlass, src);
             }
-            AMD64Call.directConditionalJmp(tasm, asm, runtime().lookupForeignCall(IC_MISS_HANDLER), ConditionFlag.NotEqual);
+            AMD64Call.directConditionalJmp(tasm, asm, getCodeCache().lookupForeignCall(IC_MISS_HANDLER), ConditionFlag.NotEqual);
         }
 
         asm.align(config.codeEntryAlignment);
@@ -270,9 +270,9 @@
         HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
         if (frameContext != null && !frameContext.isStub) {
             tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, runtime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
             tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, runtime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
+            AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Fri Oct 11 17:53:29 2013 +0200
@@ -82,7 +82,7 @@
     @Override
     protected Value[] getNativeABICallerSaveRegisters() {
         if (nativeABICallerSaveRegisters == null) {
-            List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().lookupRegisterConfig().getAllocatableRegisters()));
+            List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().getRegisterConfig().getAllocatableRegisters()));
             if (getConfig().windowsOs) {
                 // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
                 callerSave.remove(AMD64.rdi);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Fri Oct 11 17:53:29 2013 +0200
@@ -50,7 +50,7 @@
     }
 
     private static Register findPollOnReturnScratchRegister() {
-        RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().lookupRegisterConfig();
+        RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().getRegisterConfig();
         for (Register r : config.getAllocatableRegisters(Kind.Long)) {
             if (r != config.getReturnRegister(Kind.Long) && r != AMD64.rbp) {
                 return r;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Fri Oct 11 17:53:29 2013 +0200
@@ -41,6 +41,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.amd64.*;
 
 public class AMD64HotSpotRuntime extends HotSpotRuntime {
@@ -72,7 +73,8 @@
         registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
         registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
 
-        convertSnippets = new AMD64ConvertSnippets.Templates(this, this, replacements, graalRuntime.getTarget());
+        Providers providers = new Providers(this, this, this, this, replacements);
+        convertSnippets = new AMD64ConvertSnippets.Templates(providers, graalRuntime.getTarget());
         super.registerReplacements(replacements);
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Oct 11 17:53:29 2013 +0200
@@ -66,12 +66,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new SPARCFrameMap(runtime(), target, runtime().lookupRegisterConfig());
+        return new SPARCFrameMap(getRuntime(), target, getRuntime().getRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new SPARCHotSpotLIRGenerator(graph, runtime(), runtime(), target, frameMap, cc, lir);
+        return new SPARCHotSpotLIRGenerator(graph, getRuntime(), getRuntime(), target, frameMap, cc, lir);
     }
 
     /**
@@ -155,7 +155,7 @@
         AbstractAssembler masm = createAssembler(frameMap);
         // On SPARC we always use stack frames.
         HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, getRuntime(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
         StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot;
         if (deoptimizationRescueSlot != null && stub == null) {
@@ -176,7 +176,7 @@
         SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm;
         FrameMap frameMap = tasm.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
-        HotSpotVMConfig config = runtime().config;
+        HotSpotVMConfig config = getRuntime().config;
         Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label();
 
         // Emit the prefix
@@ -184,7 +184,7 @@
         if (unverifiedStub != null) {
             tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
             // We need to use JavaCall here because we haven't entered the frame yet.
-            CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{runtime().lookupJavaType(Object.class)}, target, false);
+            CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getRuntime().lookupJavaType(Object.class)}, target, false);
             Register inlineCacheKlass = g5; // see MacroAssembler::ic_call
             Register scratch = g3;
             Register receiver = asRegister(cc.getArgument(0));
@@ -206,9 +206,9 @@
         HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
         if (frameContext != null && !frameContext.isStub) {
             tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, runtime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
             tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, runtime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
+            SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
@@ -218,7 +218,7 @@
         if (unverifiedStub != null) {
             masm.bind(unverifiedStub);
             Register scratch = g3;
-            SPARCCall.indirectJmp(tasm, masm, scratch, runtime().lookupForeignCall(IC_MISS_HANDLER));
+            SPARCCall.indirectJmp(tasm, masm, scratch, getRuntime().lookupForeignCall(IC_MISS_HANDLER));
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -205,8 +205,8 @@
         CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         // create suites everytime, as we modify options for the compiler
         final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
-        final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getMetaAccess(), getCodeCache(), replacements, backend, getCodeCache().getTarget(), null, phasePlan,
-                        OptimisticOptimizations.ALL, new SpeculationLog(), suitesLocal, new CompilationResult());
+        final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
+                        new SpeculationLog(), suitesLocal, new CompilationResult());
         addMethod(method, compResult);
 
         AOTCompilation.setValue(originalSetting);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -40,15 +40,15 @@
  */
 public class CompressedOopTest extends GraalCompilerTest {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
 
     public CompressedOopTest() {
-        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
     }
 
     private HotSpotInstalledCode getInstalledCode(String name) throws Exception {
         final Method method = CompressedOopTest.class.getMethod(name, Object.class, Object.class, Object.class);
-        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(method);
+        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
         final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(javaMethod, parse(method));
         return installedBenchmarkCode;
     }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -48,12 +48,12 @@
     @Override
     protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true, null);
+        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true);
         HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult);
         CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(compiledNmethod, installedCode, null);
         Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK);
 
-        // HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime;
+        // HotSpotRuntime hsRuntime = (HotSpotRuntime) getCodeCache();
         // TTY.println(hsMethod.toString());
         // TTY.println(hsRuntime.disassemble(installedCode));
         return installedCode;
@@ -113,7 +113,7 @@
             Method method = lookup(className, methodName);
             if (method != null) {
                 ResolvedJavaMethod installedCodeOwner = getMetaAccess().lookupJavaMethod(method);
-                StructuredGraph graph = replacements.getMethodSubstitution(installedCodeOwner);
+                StructuredGraph graph = getReplacements().getMethodSubstitution(installedCodeOwner);
                 if (graph != null) {
                     Assert.assertNotNull(getCode(installedCodeOwner, graph, true));
                     atLeastOneCompiled = true;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -39,23 +39,23 @@
 public class InstalledCodeExecuteHelperTest extends GraalCompilerTest {
 
     private static final int ITERATIONS = 100000;
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
     Object[] argsToBind;
 
     public InstalledCodeExecuteHelperTest() {
-        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
     }
 
     @Test
     public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
         final Method fooMethod = InstalledCodeExecuteHelperTest.class.getMethod("foo", Object.class, Object.class, Object.class);
-        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(fooMethod);
         final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
 
         argsToBind = new Object[]{fooCode};
 
         final Method benchmarkMethod = InstalledCodeExecuteHelperTest.class.getMethod("benchmark", HotSpotInstalledCode.class);
-        final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod);
+        final ResolvedJavaMethod benchmarkJavaMethod = metaAccess.lookupJavaMethod(benchmarkMethod);
         final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod));
 
         Assert.assertEquals(Integer.valueOf(42), benchmark(fooCode));
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -53,13 +53,12 @@
  * offsets) passed as input parameters can be checked against printed output from the G1 write
  * barrier snippets. The runtime checks have been validated offline.
  */
-
 public class WriteBarrierAdditionTest extends GraalCompilerTest {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
 
     public WriteBarrierAdditionTest() {
-        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
     }
 
     public static class Container {
@@ -237,7 +236,7 @@
 
     private HotSpotInstalledCode getInstalledCode(String name) throws Exception {
         final Method method = WriteBarrierAdditionTest.class.getMethod(name, Object.class, Object.class, Object.class);
-        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(method);
+        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
         final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(javaMethod, parse(method));
         return installedBenchmarkCode;
     }
@@ -247,8 +246,8 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                HighTierContext highContext = new HighTierContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                MidTierContext midContext = new MidTierContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements, getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+                HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
                 new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext);
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext);
                 new GuardLoweringPhase().apply(graph, midContext);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -632,10 +632,10 @@
 
             public AssertionError call() {
                 final StructuredGraph graph = parse(snippet);
-                HighTierContext highTierContext = new HighTierContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
 
-                MidTierContext midTierContext = new MidTierContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements, getCodeCache().getTarget(), OptimisticOptimizations.ALL);
+                MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
 
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
                 new GuardLoweringPhase().apply(graph, midTierContext);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Oct 11 17:53:29 2013 +0200
@@ -42,6 +42,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 public final class CompilationTask implements Runnable {
 
@@ -154,8 +155,9 @@
                         InliningUtil.InlinedBytecodes.add(method.getCodeSize());
                         HotSpotRuntime runtime = graalRuntime.getRuntime();
                         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-                        return GraalCompiler.compileGraph(graph, cc, method, runtime, runtime, replacements, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan,
-                                        optimisticOpts, method.getSpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult());
+                        Providers providers = new Providers(runtime, runtime, runtime, runtime, replacements);
+                        return GraalCompiler.compileGraph(graph, cc, method, providers, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts,
+                                        method.getSpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult());
                     }
                 });
             } finally {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Fri Oct 11 17:53:29 2013 +0200
@@ -72,8 +72,7 @@
         super(runtime, runtime, target);
     }
 
-    @Override
-    public HotSpotRuntime runtime() {
-        return (HotSpotRuntime) super.runtime();
+    public HotSpotRuntime getRuntime() {
+        return (HotSpotRuntime) getCodeCache();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Oct 11 17:53:29 2013 +0200
@@ -144,7 +144,7 @@
         }
         TargetDescription target = graalRuntime().getTarget();
         JavaType returnType = asJavaType(descriptor.getResultType(), runtime);
-        return runtime.lookupRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false);
+        return runtime.getRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false);
     }
 
     private static JavaType asJavaType(Class type, HotSpotRuntime runtime) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Oct 11 17:53:29 2013 +0200
@@ -349,7 +349,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T getCapability(Class<T> clazz) {
-        if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class) {
+        if (clazz == LoweringProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class || clazz == ConstantReflectionProvider.class) {
             return (T) getRuntime();
         }
         if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class || clazz == SuitesProvider.class) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Fri Oct 11 17:53:29 2013 +0200
@@ -40,7 +40,7 @@
     private final HotSpotVMConfig config;
 
     public HotSpotReplacementsImpl(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
-        super(runtime, runtime, assumptions, target);
+        super(runtime, runtime, runtime, runtime, assumptions, target);
         this.config = runtime.config;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Fri Oct 11 17:53:29 2013 +0200
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.bridge.*;
 
 /**
@@ -47,20 +46,17 @@
     private final HotSpotResolvedJavaMethod method;
     private final boolean isDefault;
     private final boolean isExternal;
-    private final Graph graph;
 
-    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, Graph graph) {
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault) {
         this.method = method;
         this.isDefault = isDefault;
         this.isExternal = false;
-        this.graph = graph;
     }
 
-    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, boolean isExternal, Graph graph) {
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, boolean isExternal) {
         this.method = method;
         this.isDefault = isDefault;
         this.isExternal = isExternal;
-        this.graph = graph;
     }
 
     public boolean isDefault() {
@@ -71,10 +67,6 @@
         return isExternal;
     }
 
-    public Graph getGraph() {
-        return graph;
-    }
-
     @Override
     public ResolvedJavaMethod getMethod() {
         return method;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Oct 11 17:53:29 2013 +0200
@@ -91,14 +91,15 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
 
 /**
- * HotSpot implementation of {@link GraalCodeCacheProvider}.
+ * HotSpot implementation of {@link LoweringProvider}.
  */
-public abstract class HotSpotRuntime implements MetaAccessProvider, GraalCodeCacheProvider, DisassemblerProvider, BytecodeDisassemblerProvider, SuitesProvider {
+public abstract class HotSpotRuntime implements MetaAccessProvider, ConstantReflectionProvider, CodeCacheProvider, LoweringProvider, DisassemblerProvider, BytecodeDisassemblerProvider, SuitesProvider {
 
     public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class);
     public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class);
@@ -252,9 +253,9 @@
      *            cannot be re-executed.
      * @param killedLocations the memory locations killed by the foreign call
      */
-    private void linkForeignCall(Replacements replacements, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
+    private void linkForeignCall(Providers providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
                     LocationIdentity... killedLocations) {
-        ForeignCallStub stub = new ForeignCallStub(this, replacements, address, descriptor, prependThread, transition, reexecutable, killedLocations);
+        ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations);
         HotSpotForeignCallLinkage linkage = stub.getLinkage();
         HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage();
         linkage.setCompiledStub(stub);
@@ -291,29 +292,31 @@
         registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
         registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
 
-        link(new NewInstanceStub(this, r, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
-        link(new NewArrayStub(this, r, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION)));
-        link(new ExceptionHandlerStub(this, r, target, foreignCalls.get(EXCEPTION_HANDLER)));
-        link(new UnwindExceptionToCallerStub(this, r, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
-        link(new VerifyOopStub(this, r, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS)));
+        Providers providers = new Providers(this, this, this, this, r);
+
+        link(new NewInstanceStub(providers, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
+        link(new NewArrayStub(providers, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION)));
+        link(new ExceptionHandlerStub(providers, target, foreignCalls.get(EXCEPTION_HANDLER)));
+        link(new UnwindExceptionToCallerStub(providers, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
+        link(new VerifyOopStub(providers, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS)));
 
-        linkForeignCall(r, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION);
-        linkForeignCall(r, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
-        linkForeignCall(r, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
-        linkForeignCall(r, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION);
+        linkForeignCall(providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
+        linkForeignCall(providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
+        linkForeignCall(providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
 
         r.registerSubstitutions(ObjectSubstitutions.class);
         r.registerSubstitutions(SystemSubstitutions.class);
@@ -325,16 +328,16 @@
         r.registerSubstitutions(CRC32Substitutions.class);
         r.registerSubstitutions(ReflectionSubstitutions.class);
 
-        checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(this, this, r, graalRuntime.getTarget());
-        instanceofSnippets = new InstanceOfSnippets.Templates(this, this, r, graalRuntime.getTarget());
-        newObjectSnippets = new NewObjectSnippets.Templates(this, this, r, graalRuntime.getTarget());
-        monitorSnippets = new MonitorSnippets.Templates(this, this, r, graalRuntime.getTarget(), c.useFastLocking);
-        writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, this, r, graalRuntime.getTarget());
-        boxingSnippets = new BoxingSnippets.Templates(this, this, r, graalRuntime.getTarget());
-        exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(this, this, r, graalRuntime.getTarget());
-        unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(this, this, r, graalRuntime.getTarget());
+        checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(providers, graalRuntime.getTarget());
+        instanceofSnippets = new InstanceOfSnippets.Templates(providers, graalRuntime.getTarget());
+        newObjectSnippets = new NewObjectSnippets.Templates(providers, graalRuntime.getTarget());
+        monitorSnippets = new MonitorSnippets.Templates(providers, graalRuntime.getTarget(), c.useFastLocking);
+        writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, graalRuntime.getTarget());
+        boxingSnippets = new BoxingSnippets.Templates(providers, graalRuntime.getTarget());
+        exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, graalRuntime.getTarget());
+        unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, graalRuntime.getTarget());
 
-        r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(this, this, r, graalRuntime.getTarget()));
+        r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, graalRuntime.getTarget()));
     }
 
     public HotSpotGraalRuntime getGraalRuntime() {
@@ -469,7 +472,7 @@
     }
 
     @Override
-    public RegisterConfig lookupRegisterConfig() {
+    public RegisterConfig getRegisterConfig() {
         return regConfig;
     }
 
@@ -1048,7 +1051,7 @@
     private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
         StructuredGraph g = n.graph();
         ValueNode array = n.array();
-        ValueNode arrayLength = readArrayLength(array, tool.getMetaAccess());
+        ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection());
         if (arrayLength == null) {
             Stamp stamp = StampFactory.positiveInt();
             ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, g), stamp, BarrierType.NONE, false));
@@ -1095,20 +1098,15 @@
     }
 
     public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
-        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true, null);
+        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true);
         graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, entryBCI, compResult), installedCode, method.getSpeculationLog());
         return installedCode;
     }
 
     @Override
     public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
-        return addMethod(method, compResult, null);
-    }
-
-    @Override
-    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) {
         HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false, graph);
+        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false);
         CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null);
         if (result != CodeInstallResult.OK) {
             return null;
@@ -1116,12 +1114,10 @@
         return code;
     }
 
-    public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) {
-
-        // compResult.getTargetCode() == assembled PTX method string
+    public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
 
         HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true, graph);
+        HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true);
         HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, -1, compResult);
         CompilerToVM vm = graalRuntime.getCompilerToVM();
         CodeInstallResult result = vm.installCode(compiled, icode, null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -37,7 +37,7 @@
 public class StubForeignCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi {
 
     @Input private final NodeInputList<ValueNode> arguments;
-    private final MetaAccessProvider runtime;
+    private final MetaAccessProvider metaAccess;
 
     private final ForeignCallDescriptor descriptor;
 
@@ -45,7 +45,7 @@
         super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
         this.arguments = new NodeInputList<>(this, arguments);
         this.descriptor = descriptor;
-        this.runtime = metaAccess;
+        this.metaAccess = metaAccess;
     }
 
     public ForeignCallDescriptor getDescriptor() {
@@ -54,7 +54,7 @@
 
     @Override
     public LocationIdentity[] getLocationIdentities() {
-        return runtime.getKilledLocations(descriptor);
+        return metaAccess.getKilledLocations(descriptor);
     }
 
     protected Value[] operands(LIRGeneratorTool gen) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Fri Oct 11 17:53:29 2013 +0200
@@ -61,6 +61,6 @@
     @Override
     public void lower(LoweringTool tool) {
         assert graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA;
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -93,7 +93,7 @@
         }
         // the canonicalization before loop unrolling is needed to propagate the length into
         // additions, etc.
-        PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.assumptions(), tool.getReplacements());
+        PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getLowerer(), tool.assumptions(), tool.getReplacements());
         new CanonicalizerPhase(true).apply(snippetGraph, context);
         new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context);
         new CanonicalizerPhase(true).apply(snippetGraph, context);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -42,7 +42,7 @@
         return arguments.get(0);
     }
 
-    private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccessProvider, Assumptions assumptions) {
+    private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess, Assumptions assumptions) {
         if (getCallSite().isConstant() && !getCallSite().isNullConstant()) {
             CallSite callSite = (CallSite) getCallSite().asConstant().asObject();
             MethodHandle target = callSite.getTarget();
@@ -52,7 +52,7 @@
                 }
                 assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target));
             }
-            return ConstantNode.forObject(target, metaAccessProvider, graph());
+            return ConstantNode.forObject(target, metaAccess, graph());
         }
         return null;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -31,12 +31,11 @@
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -67,8 +66,8 @@
 
         private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic");
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(CheckCastDynamicNode checkcast) {
@@ -81,7 +80,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, args);
-            template.instantiate(metaAccess, checkcast, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), checkcast, DEFAULT_REPLACER, args);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -40,6 +40,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
@@ -200,8 +201,8 @@
         private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary");
         private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic");
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         @Override
@@ -211,13 +212,13 @@
                 ValueNode object = instanceOf.object();
                 TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), InstanceOfMinHintHitProbability.getValue(), InstanceOfMaxHints.getValue());
                 final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type();
-                ConstantNode hub = ConstantNode.forConstant(type.klass(), metaAccess, instanceOf.graph());
+                ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), instanceOf.graph());
 
                 Arguments args;
 
                 StructuredGraph graph = hub.graph();
                 if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) {
-                    Hints hints = createHints(hintInfo, metaAccess, false, graph);
+                    Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
                     args = new Arguments(instanceofWithProfile, graph.getGuardsStage());
                     args.add("object", object);
                     args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints.hubs);
@@ -225,14 +226,14 @@
                 } else if (hintInfo.exact != null) {
                     args = new Arguments(instanceofExact, graph.getGuardsStage());
                     args.add("object", object);
-                    args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), metaAccess, graph));
+                    args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph));
                 } else if (type.isPrimaryType()) {
                     args = new Arguments(instanceofPrimary, graph.getGuardsStage());
                     args.add("hub", hub);
                     args.add("object", object);
                     args.addConst("superCheckOffset", type.superCheckOffset());
                 } else {
-                    Hints hints = createHints(hintInfo, metaAccess, false, graph);
+                    Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
                     args = new Arguments(instanceofSecondary, graph.getGuardsStage());
                     args.add("hub", hub);
                     args.add("object", object);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -28,13 +28,12 @@
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -65,22 +64,22 @@
 
         private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException");
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(LoadExceptionObjectNode loadExceptionObject) {
             if (USE_C_RUNTIME) {
                 StructuredGraph graph = loadExceptionObject.graph();
-                HotSpotRuntime hsRuntime = (HotSpotRuntime) metaAccess;
+                HotSpotRuntime hsRuntime = (HotSpotRuntime) providers.getMetaAccess();
                 ReadRegisterNode thread = graph.add(new ReadRegisterNode(hsRuntime.threadRegister(), true, false));
                 graph.addBeforeFixed(loadExceptionObject, thread);
-                ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(metaAccess, LOAD_AND_CLEAR_EXCEPTION, thread));
+                ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(providers.getMetaAccess(), LOAD_AND_CLEAR_EXCEPTION, thread));
                 loadExceptionC.setStateAfter(loadExceptionObject.stateAfter());
                 graph.replaceFixedWithFixed(loadExceptionObject, loadExceptionC);
             } else {
                 Arguments args = new Arguments(loadException, loadExceptionObject.graph().getGuardsStage());
-                template(args).instantiate(metaAccess, loadExceptionObject, DEFAULT_REPLACER, args);
+                template(args).instantiate(providers.getMetaAccess(), loadExceptionObject, DEFAULT_REPLACER, args);
             }
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -48,6 +48,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -415,8 +416,8 @@
 
         private final boolean useFastLocking;
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target, boolean useFastLocking) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target, boolean useFastLocking) {
+            super(providers, target);
             this.useFastLocking = useFastLocking;
         }
 
@@ -436,7 +437,7 @@
             boolean tracingEnabledForMethod = stateAfter != null && (isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
             args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || tracingEnabledForMethod);
 
-            Map<Node, Node> nodes = template(args).instantiate(metaAccess, monitorenterNode, DEFAULT_REPLACER, args);
+            Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorenterNode, DEFAULT_REPLACER, args);
 
             for (Node n : nodes.values()) {
                 if (n instanceof BeginLockScopeNode) {
@@ -460,7 +461,7 @@
             args.addConst("lockDepth", monitorexitNode.getLockDepth());
             args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
 
-            Map<Node, Node> nodes = template(args).instantiate(metaAccess, monitorexitNode, DEFAULT_REPLACER, args);
+            Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args);
 
             for (Node n : nodes.values()) {
                 if (n instanceof EndLockScopeNode) {
@@ -514,14 +515,14 @@
                     invoke.setStateAfter(graph.start().stateAfter());
                     graph.addAfterFixed(graph.start(), invoke);
 
-                    StructuredGraph inlineeGraph = replacements.getSnippet(initCounter.getMethod());
+                    StructuredGraph inlineeGraph = providers.getReplacements().getSnippet(initCounter.getMethod());
                     InliningUtil.inline(invoke, inlineeGraph, false);
 
                     List<ReturnNode> rets = graph.getNodes().filter(ReturnNode.class).snapshot();
                     for (ReturnNode ret : rets) {
                         returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass());
                         String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d";
-                        ConstantNode errMsg = ConstantNode.forObject(msg, metaAccess, graph);
+                        ConstantNode errMsg = ConstantNode.forObject(msg, providers.getMetaAccess(), graph);
                         callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType));
                         invoke = graph.add(new InvokeNode(callTarget, 0));
                         List<ValueNode> stack = Collections.emptyList();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -43,9 +43,9 @@
 import com.oracle.graal.nodes.debug.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.options.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -296,8 +296,8 @@
         private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic");
         private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray");
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         /**
@@ -307,7 +307,7 @@
             StructuredGraph graph = newInstanceNode.graph();
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass();
             assert !type.isArray();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), metaAccess, graph);
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph);
             int size = instanceSize(type);
 
             Arguments args = new Arguments(allocateInstance, graph.getGuardsStage());
@@ -319,7 +319,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering allocateInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, args);
-            template.instantiate(metaAccess, newInstanceNode, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), newInstanceNode, DEFAULT_REPLACER, args);
         }
 
         /**
@@ -330,9 +330,9 @@
             ResolvedJavaType elementType = newArrayNode.elementType();
             HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass();
             Kind elementKind = elementType.getKind();
-            ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), metaAccess, graph);
+            ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), providers.getMetaAccess(), graph);
             final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
-            int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) metaAccess).getScalingFactor(elementKind));
+            int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) providers.getMetaAccess()).getScalingFactor(elementKind));
 
             Arguments args = new Arguments(allocateArray, graph.getGuardsStage());
             args.add("hub", hub);
@@ -345,7 +345,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args);
-            template.instantiate(metaAccess, newArrayNode, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args);
         }
 
         public void lower(DynamicNewArrayNode newArrayNode) {
@@ -355,7 +355,7 @@
             args.addConst("fillContents", newArrayNode.fillContents());
 
             SnippetTemplate template = template(args);
-            template.instantiate(metaAccess, newArrayNode, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args);
         }
 
         public void lower(NewMultiArrayNode newmultiarrayNode) {
@@ -366,13 +366,13 @@
                 dims[i] = newmultiarrayNode.dimension(i);
             }
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newmultiarrayNode.type();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), metaAccess, graph);
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph);
 
             Arguments args = new Arguments(newmultiarray, graph.getGuardsStage());
             args.add("hub", hub);
             args.addConst("rank", rank);
             args.addVarargs("dimensions", int.class, StampFactory.forKind(Kind.Int), dims);
-            template(args).instantiate(metaAccess, newmultiarrayNode, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), newmultiarrayNode, DEFAULT_REPLACER, args);
         }
 
         private static int instanceSize(HotSpotResolvedObjectType type) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -23,8 +23,8 @@
 package com.oracle.graal.hotspot.replacements;
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
@@ -32,7 +32,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -256,8 +256,8 @@
         private final SnippetInfo[] arraycopySnippets;
         private final SnippetInfo genericPrimitiveSnippet;
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
 
             arraycopySnippets = new SnippetInfo[Kind.values().length];
             arraycopySnippets[Kind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean");
@@ -288,7 +288,7 @@
             node.addSnippetArguments(args);
 
             SnippetTemplate template = template(args);
-            template.instantiate(metaAccess, node, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), node, DEFAULT_REPLACER, args);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -26,11 +26,11 @@
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -53,15 +53,15 @@
 
         private final SnippetInfo unsafeLoad = snippet(UnsafeLoadSnippets.class, "lowerUnsafeLoad");
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(UnsafeLoadNode load, @SuppressWarnings("unused") LoweringTool tool) {
             Arguments args = new Arguments(unsafeLoad, load.graph().getGuardsStage());
             args.add("object", load.object());
             args.add("offset", load.offset());
-            template(args).instantiate(metaAccess, load, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), load, DEFAULT_REPLACER, args);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -336,8 +337,8 @@
         private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier");
         private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier");
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(SerialWriteBarrier writeBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -346,7 +347,7 @@
             args.add("location", writeBarrier.getLocation());
             args.addConst("usePrecise", writeBarrier.usePrecise());
             args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrier.getValue()));
-            template(args).instantiate(metaAccess, writeBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), writeBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(SerialArrayRangeWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -354,7 +355,7 @@
             args.add("object", arrayRangeWriteBarrier.getObject());
             args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
             args.add("length", arrayRangeWriteBarrier.getLength());
-            template(args).instantiate(metaAccess, arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1PreWriteBarrier writeBarrierPre, @SuppressWarnings("unused") LoweringTool tool) {
@@ -365,7 +366,7 @@
             args.addConst("doLoad", writeBarrierPre.doLoad());
             args.addConst("nullCheck", writeBarrierPre.getNullCheck());
             args.addConst("trace", traceBarrier());
-            template(args).instantiate(metaAccess, writeBarrierPre, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), writeBarrierPre, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1ReferentFieldReadBarrier readBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -376,7 +377,7 @@
             args.addConst("doLoad", readBarrier.doLoad());
             args.addConst("nullCheck", false);
             args.addConst("trace", traceBarrier());
-            template(args).instantiate(metaAccess, readBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), readBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1PostWriteBarrier writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) {
@@ -387,7 +388,7 @@
             args.addConst("usePrecise", writeBarrierPost.usePrecise());
             args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrierPost.getValue()));
             args.addConst("trace", traceBarrier());
-            template(args).instantiate(metaAccess, writeBarrierPost, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), writeBarrierPost, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1ArrayRangePreWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -395,7 +396,7 @@
             args.add("object", arrayRangeWriteBarrier.getObject());
             args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
             args.add("length", arrayRangeWriteBarrier.getLength());
-            template(args).instantiate(metaAccess, arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1ArrayRangePostWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -403,7 +404,7 @@
             args.add("object", arrayRangeWriteBarrier.getObject());
             args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
             args.add("length", arrayRangeWriteBarrier.getLength());
-            template(args).instantiate(metaAccess, arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -32,9 +32,8 @@
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -49,8 +48,8 @@
  */
 public class ExceptionHandlerStub extends SnippetStub {
 
-    public ExceptionHandlerStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public ExceptionHandlerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -43,9 +43,9 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.word.*;
@@ -85,9 +85,9 @@
      *            be re-executed.
      * @param killedLocations the memory locations killed by the stub call
      */
-    public ForeignCallStub(HotSpotRuntime runtime, Replacements replacements, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable,
+    public ForeignCallStub(Providers providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable,
                     LocationIdentity... killedLocations) {
-        super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
+        super(providers, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
         this.prependThread = prependThread;
         Class[] targetParameterTypes = createTargetParameters(descriptor);
         ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes);
@@ -304,7 +304,7 @@
 
     private void inline(InvokeNode invoke) {
         ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
-        ReplacementsImpl repl = new ReplacementsImpl(runtime, runtime, new Assumptions(false), runtime.getTarget());
+        ReplacementsImpl repl = new ReplacementsImpl(runtime, runtime, runtime, runtime, new Assumptions(false), runtime.getTarget());
         StructuredGraph calleeGraph = repl.makeGraph(method, null, null, false);
         InliningUtil.inline(invoke, calleeGraph, false);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -37,7 +37,7 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.StructuredGraph.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -53,8 +53,8 @@
  */
 public class NewArrayStub extends SnippetStub {
 
-    public NewArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public NewArrayStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -38,7 +38,7 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.StructuredGraph.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -54,8 +54,8 @@
  */
 public class NewInstanceStub extends SnippetStub {
 
-    public NewInstanceStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public NewInstanceStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -27,10 +27,9 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -43,8 +42,8 @@
 
     static class Template extends AbstractTemplates {
 
-        Template(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, Class<? extends Snippets> declaringClass) {
-            super(runtime, runtime, replacements, target);
+        Template(Providers providers, TargetDescription target, Class<? extends Snippets> declaringClass) {
+            super(providers, target);
             this.info = snippet(declaringClass, null);
         }
 
@@ -66,9 +65,9 @@
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public SnippetStub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, linkage);
-        this.snippet = new Template(runtime, replacements, target, getClass());
+    public SnippetStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, linkage);
+        this.snippet = new Template(providers, target, getClass());
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -40,9 +40,9 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
+import com.oracle.graal.phases.util.*;
 
 //JaCoCo Exclude
 
@@ -93,17 +93,17 @@
 
     protected final HotSpotRuntime runtime;
 
-    protected final Replacements replacements;
+    protected final Providers providers;
 
     /**
      * Creates a new stub.
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public Stub(HotSpotRuntime runtime, Replacements replacements, HotSpotForeignCallLinkage linkage) {
+    public Stub(Providers providers, HotSpotForeignCallLinkage linkage) {
         this.linkage = linkage;
-        this.runtime = runtime;
-        this.replacements = replacements;
+        this.runtime = (HotSpotRuntime) providers.getMetaAccess();
+        this.providers = providers;
     }
 
     /**
@@ -156,8 +156,8 @@
                     phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                     // The stub itself needs the incoming calling convention.
                     CallingConvention incomingCc = linkage.getIncomingCallingConvention();
-                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), runtime, runtime, replacements, backend, runtime.getTarget(), null,
-                                    phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites(), new CompilationResult());
+                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, runtime.getTarget(), null, phasePlan,
+                                    OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites(), new CompilationResult());
 
                     assert destroyedRegisters != null;
                     code = Debug.scope("CodeInstall", new Callable<InstalledCode>() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -32,10 +32,9 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -46,8 +45,8 @@
  */
 public class UnwindExceptionToCallerStub extends SnippetStub {
 
-    public UnwindExceptionToCallerStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public UnwindExceptionToCallerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java	Fri Oct 11 17:53:29 2013 +0200
@@ -27,7 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 
 /**
@@ -35,8 +35,8 @@
  */
 public class VerifyOopStub extends SnippetStub {
 
-    public VerifyOopStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public VerifyOopStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     @Snippet
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Fri Oct 11 17:53:29 2013 +0200
@@ -32,26 +32,24 @@
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 public class TestUtil {
 
     public static void compileMethod(ResolvedJavaMethod method) {
-        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        GraalCodeCacheProvider codeCache = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
-        Replacements replacements = Graal.getRequiredCapability(Replacements.class);
+        Providers providers = GraalCompiler.getGraalProviders();
         Suites suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
         StructuredGraph graph = new StructuredGraph(method);
-        new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
         PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-        CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
+        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
         Backend backend = Graal.getRequiredCapability(Backend.class);
-        GraalCompiler.compileGraph(graph, cc, method, metaAccess, codeCache, replacements, backend, codeCache.getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(),
-                        suites, new CompilationResult());
+        GraalCompiler.compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites,
+                        new CompilationResult());
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/VerifyOptionsPhase.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/VerifyOptionsPhase.java	Fri Oct 11 17:53:29 2013 +0200
@@ -73,14 +73,14 @@
         }
     }
 
-    private final MetaAccessProvider runtime;
+    private final MetaAccessProvider metaAccess;
     private final ResolvedJavaType declaringClass;
     private final ResolvedJavaType optionValueType;
     private final Set<ResolvedJavaType> boxingTypes;
     private final OptionDescriptor option;
 
     public VerifyOptionsPhase(ResolvedJavaType declaringClass, MetaAccessProvider metaAccess, OptionDescriptor option) {
-        this.runtime = metaAccess;
+        this.metaAccess = metaAccess;
         this.declaringClass = declaringClass;
         this.optionValueType = metaAccess.lookupJavaType(OptionValue.class);
         this.option = option;
@@ -101,7 +101,7 @@
             }
         } else if (boxingTypes.contains(holder)) {
             return method.getName().equals("valueOf");
-        } else if (method.getDeclaringClass() == runtime.lookupJavaType(Class.class)) {
+        } else if (method.getDeclaringClass() == metaAccess.lookupJavaType(Class.class)) {
             return method.getName().equals("desiredAssertionStatus");
         } else if (method.getDeclaringClass().equals(declaringClass)) {
             return (method.getName().equals("$jacocoInit"));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -183,7 +183,7 @@
             if (this.trueSuccessorProbability < probabilityB) {
                 // Reordering of those two if statements is beneficial from the point of view of
                 // their probabilities.
-                if (prepareForSwap(tool.getMetaAccess(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) {
+                if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) {
                     // Reording is allowed from (if1 => begin => if2) to (if2 => begin => if1).
                     assert intermediateBegin.next() == nextIf;
                     AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor();
@@ -208,7 +208,7 @@
         }
     }
 
-    private static boolean prepareForSwap(MetaAccessProvider metaAccess, LogicNode a, LogicNode b, double probabilityA, double probabilityB) {
+    private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b, double probabilityA, double probabilityB) {
         if (a instanceof InstanceOfNode) {
             InstanceOfNode instanceOfA = (InstanceOfNode) a;
             if (b instanceof IsNullNode) {
@@ -297,13 +297,13 @@
                     }
                 } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) {
                     boolean canSwap = false;
-                    if ((compareA.x() == compareB.x() && valuesDistinct(metaAccess, compareA.y(), compareB.y()))) {
+                    if ((compareA.x() == compareB.x() && valuesDistinct(constantReflection, compareA.y(), compareB.y()))) {
                         canSwap = true;
-                    } else if ((compareA.x() == compareB.y() && valuesDistinct(metaAccess, compareA.y(), compareB.x()))) {
+                    } else if ((compareA.x() == compareB.y() && valuesDistinct(constantReflection, compareA.y(), compareB.x()))) {
                         canSwap = true;
-                    } else if ((compareA.y() == compareB.x() && valuesDistinct(metaAccess, compareA.x(), compareB.y()))) {
+                    } else if ((compareA.y() == compareB.x() && valuesDistinct(constantReflection, compareA.x(), compareB.y()))) {
                         canSwap = true;
-                    } else if ((compareA.y() == compareB.y() && valuesDistinct(metaAccess, compareA.x(), compareB.x()))) {
+                    } else if ((compareA.y() == compareB.y() && valuesDistinct(constantReflection, compareA.x(), compareB.x()))) {
                         canSwap = true;
                     }
 
@@ -318,9 +318,9 @@
         return false;
     }
 
-    private static boolean valuesDistinct(MetaAccessProvider metaAccess, ValueNode a, ValueNode b) {
+    private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) {
         if (a.isConstant() && b.isConstant()) {
-            return !metaAccess.constantEquals(a.asConstant(), b.asConstant());
+            return !constantReflection.constantEquals(a.asConstant(), b.asConstant());
         }
 
         Stamp stampA = a.stamp();
@@ -487,7 +487,7 @@
         for (int i = 0; i < xs.length; i++) {
             AbstractEndNode end = ends.next();
             phiValues.put(end, phi.valueAt(end));
-            if (compare.condition().foldCondition(xs[i], ys[i], tool.getMetaAccess(), compare.unorderedIsTrue())) {
+            if (compare.condition().foldCondition(xs[i], ys[i], tool.getConstantReflection(), compare.unorderedIsTrue())) {
                 trueEnds.add(end);
             } else {
                 falseEnds.add(end);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -109,7 +109,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -129,7 +129,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -77,13 +77,13 @@
     public void generate(LIRGeneratorTool gen) {
     }
 
-    private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, MetaAccessProvider metaAccess, Condition cond) {
+    private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) {
         Constant trueConstant = conditionalNode.trueValue().asConstant();
         Constant falseConstant = conditionalNode.falseValue().asConstant();
 
-        if (falseConstant != null && trueConstant != null && metaAccess != null) {
-            boolean trueResult = cond.foldCondition(trueConstant, constant, metaAccess, unorderedIsTrue());
-            boolean falseResult = cond.foldCondition(falseConstant, constant, metaAccess, unorderedIsTrue());
+        if (falseConstant != null && trueConstant != null && constantReflection != null) {
+            boolean trueResult = cond.foldCondition(trueConstant, constant, constantReflection, unorderedIsTrue());
+            boolean falseResult = cond.foldCondition(falseConstant, constant, constantReflection, unorderedIsTrue());
 
             if (trueResult == falseResult) {
                 return LogicConstantNode.forBoolean(trueResult, graph());
@@ -118,17 +118,17 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant() && tool.getMetaAccess() != null) {
-            return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.getMetaAccess(), unorderedIsTrue()), graph());
+            return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.getConstantReflection(), unorderedIsTrue()), graph());
         }
         if (x().isConstant()) {
             if (y() instanceof ConditionalNode) {
-                return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.getMetaAccess(), condition().mirror());
+                return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.getConstantReflection(), condition().mirror());
             } else if (y() instanceof NormalizeCompareNode) {
                 return optimizeNormalizeCmp(x().asConstant(), (NormalizeCompareNode) y(), true);
             }
         } else if (y().isConstant()) {
             if (x() instanceof ConditionalNode) {
-                return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.getMetaAccess(), condition());
+                return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.getConstantReflection(), condition());
             } else if (x() instanceof NormalizeCompareNode) {
                 return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x(), false);
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Fri Oct 11 17:53:29 2013 +0200
@@ -317,13 +317,13 @@
      * 
      * @param lt the constant on the left side of the comparison
      * @param rt the constant on the right side of the comparison
-     * @param metaAccess needed to compare runtime-specific types
+     * @param constantReflection needed to compare constants
      * @return {@link Boolean#TRUE} if the comparison is known to be true, {@link Boolean#FALSE} if
      *         the comparison is known to be false
      */
-    public boolean foldCondition(Constant lt, Constant rt, MetaAccessProvider metaAccess) {
+    public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection) {
         assert lt.getKind() != Kind.Double && lt.getKind() != Kind.Float && rt.getKind() != Kind.Double && rt.getKind() != Kind.Float;
-        return foldCondition(lt, rt, metaAccess, false);
+        return foldCondition(lt, rt, constantReflection, false);
     }
 
     /**
@@ -331,12 +331,12 @@
      * 
      * @param lt the constant on the left side of the comparison
      * @param rt the constant on the right side of the comparison
-     * @param metaAccess needed to compare runtime-specific types
+     * @param constantReflection needed to compare constants
      * @param unorderedIsTrue true if an undecided float comparison should result in "true"
      * @return true if the comparison is known to be true, false if the comparison is known to be
      *         false
      */
-    public boolean foldCondition(Constant lt, Constant rt, MetaAccessProvider metaAccess, boolean unorderedIsTrue) {
+    public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) {
         switch (lt.getKind()) {
             case Boolean:
             case Byte:
@@ -401,9 +401,9 @@
             case Object: {
                 switch (this) {
                     case EQ:
-                        return metaAccess.constantEquals(lt, rt);
+                        return constantReflection.constantEquals(lt, rt);
                     case NE:
-                        return !metaAccess.constantEquals(lt, rt);
+                        return !constantReflection.constantEquals(lt, rt);
                     default:
                         throw new GraalInternalError("expected condition: %s", this);
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -244,7 +244,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -112,7 +112,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -63,7 +63,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -64,7 +64,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -63,7 +63,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -68,7 +68,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public static void addCounterBefore(String group, String name, long increment, boolean withContext, FixedNode position) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -56,7 +56,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -62,7 +62,7 @@
     @Override
     public void lower(LoweringTool tool) {
         if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-            tool.getCodeCache().lower(this, tool);
+            tool.getLowerer().lower(this, tool);
         }
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -52,7 +52,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public ResolvedJavaMethod getMethod() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -30,7 +30,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public NodeIterable<OSRLocalNode> getOSRLocals() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -72,7 +72,7 @@
                 if (object.kind() == Kind.Object) {
                     Object base = object.asConstant().asObject();
                     if (base != null) {
-                        Constant constant = tool.getMetaAccess().readUnsafeConstant(kind, base, displacement, compressible);
+                        Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible);
                         if (constant != null) {
                             return ConstantNode.forConstant(constant, metaAccess, read.graph());
                         }
@@ -80,7 +80,7 @@
                 } else if (object.kind() == Kind.Long || object.kind().getStackKind() == Kind.Int) {
                     long base = object.asConstant().asLong();
                     if (base != 0L) {
-                        Constant constant = tool.getMetaAccess().readUnsafeConstant(kind, null, base + displacement, compressible);
+                        Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, null, base + displacement, compressible);
                         if (constant != null) {
                             return ConstantNode.forConstant(constant, metaAccess, read.graph());
                         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -47,7 +47,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -51,7 +51,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -52,7 +52,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -69,7 +69,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -89,7 +89,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -84,7 +84,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -65,6 +65,6 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -47,7 +47,7 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        ValueNode length = readArrayLength(array(), tool.getMetaAccess());
+        ValueNode length = readArrayLength(array(), tool.getConstantReflection());
         if (length != null) {
             return length;
         }
@@ -60,17 +60,17 @@
      * @param array an array
      * @return a node representing the length of {@code array} or null if it is not available
      */
-    public static ValueNode readArrayLength(ValueNode array, MetaAccessProvider metaAccess) {
+    public static ValueNode readArrayLength(ValueNode array, ConstantReflectionProvider constantReflection) {
         if (array instanceof ArrayLengthProvider) {
             ValueNode length = ((ArrayLengthProvider) array).length();
             if (length != null) {
                 return length;
             }
         }
-        if (metaAccess != null && array.isConstant() && !array.isNullConstant()) {
+        if (constantReflection != null && array.isConstant() && !array.isNullConstant()) {
             Constant constantValue = array.asConstant();
             if (constantValue != null && constantValue.isNonNull()) {
-                Integer constantLength = metaAccess.lookupArrayLength(constantValue);
+                Integer constantLength = constantReflection.lookupArrayLength(constantValue);
                 if (constantLength != null) {
                     return ConstantNode.forInt(constantLength, array.graph());
                 }
@@ -81,7 +81,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -61,7 +61,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -79,7 +79,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -53,7 +53,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -54,7 +54,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -45,6 +45,6 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -51,7 +51,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public int getLockDepth() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -52,7 +52,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public int getLockDepth() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -79,7 +79,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -63,7 +63,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public ResolvedJavaType type() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -86,7 +86,7 @@
             for (int i = 0; i < keyCount(); i++) {
                 Constant typeHub = keyAt(i);
                 assert constant.getKind() == typeHub.getKind();
-                if (tool.getMetaAccess().constantEquals(constant, typeHub)) {
+                if (tool.getConstantReflection().constantEquals(constant, typeHub)) {
                     survivingEdge = keySuccessorIndex(i);
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java	Fri Oct 11 17:52:33 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2011, 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.graal.nodes.spi;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-
-/**
- * A {@link GraalCodeCacheProvider} that delegates to another {@link GraalCodeCacheProvider}.
- */
-public class DelegatingGraalCodeCacheProvider extends DelegatingCodeCacheProvider implements GraalCodeCacheProvider {
-
-    public DelegatingGraalCodeCacheProvider(CodeCacheProvider delegate) {
-        super(delegate);
-    }
-
-    @Override
-    protected GraalCodeCacheProvider delegate() {
-        return (GraalCodeCacheProvider) super.delegate();
-    }
-
-    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) {
-        return delegate().addMethod(method, compResult, graph);
-    }
-
-    public void lower(Node n, LoweringTool tool) {
-        delegate().lower(n, tool);
-    }
-
-    public ValueNode reconstructArrayIndex(LocationNode location) {
-        return delegate().reconstructArrayIndex(location);
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Fri Oct 11 17:52:33 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2011, 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.graal.nodes.spi;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-
-/**
- * Graal-specific extensions for the code cache provider interface.
- */
-public interface GraalCodeCacheProvider extends CodeCacheProvider {
-
-    /**
-     * Adds the given compilation result as an implementation of the given method without making it
-     * the default implementation. The graph might be inlined later on.
-     * 
-     * @param method a method to which the executable code is begin added
-     * @param compResult the compilation result to be added
-     * @param graph the graph that represents the method
-     * @return a reference to the compiled and ready-to-run code or null if the code installation
-     *         failed
-     */
-    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph);
-
-    void lower(Node n, LoweringTool tool);
-
-    /**
-     * Reconstructs the array index from a location node that was created as a lowering of an indexed
-     * access to an array.
-     * 
-     * @param location a location pointing to an element in an array
-     * @return a node that gives the index of the element
-     */
-    ValueNode reconstructArrayIndex(LocationNode location);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java	Fri Oct 11 17:53:29 2013 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 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.graal.nodes.spi;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+
+/**
+ * Provides a capability for replacing a higher node with one or more lower level nodes.
+ */
+public interface LoweringProvider {
+
+    void lower(Node n, LoweringTool tool);
+
+    /**
+     * Reconstructs the array index from a location node that was created as a lowering of an
+     * indexed access to an array.
+     * 
+     * @param location a location pointing to an element in an array
+     * @return a node that gives the index of the element
+     */
+    ValueNode reconstructArrayIndex(LocationNode location);
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Fri Oct 11 17:53:29 2013 +0200
@@ -33,7 +33,11 @@
 
     MetaAccessProvider getMetaAccess();
 
-    GraalCodeCacheProvider getCodeCache();
+    CodeCacheProvider getCodeCache();
+
+    LoweringProvider getLowerer();
+
+    ConstantReflectionProvider getConstantReflection();
 
     Replacements getReplacements();
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -67,7 +67,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getCodeCache().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Oct 11 17:53:29 2013 +0200
@@ -67,7 +67,7 @@
 
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
-        new Instance(context.getMetaAccess(), context.getAssumptions(), canonicalizeReads, customCanonicalizer).run(graph);
+        new Instance(context, canonicalizeReads, customCanonicalizer).run(graph);
     }
 
     /**
@@ -79,7 +79,7 @@
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, int newNodesMark, boolean dumpGraph) {
-        new Instance(context.getMetaAccess(), context.getAssumptions(), canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
+        new Instance(context, canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
     }
 
     /**
@@ -91,7 +91,7 @@
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, boolean dumpGraph) {
-        new Instance(context.getMetaAccess(), context.getAssumptions(), canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph);
+        new Instance(context, canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph);
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, int newNodesMark) {
@@ -99,19 +99,18 @@
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, int newNodesMark, boolean dumpGraph) {
-        new Instance(context.getMetaAccess(), context.getAssumptions(), canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
+        new Instance(context, canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
     }
 
     @Deprecated
     public void addToPhasePlan(PhasePlan plan, PhaseContext context) {
-        plan.addPhase(PhasePosition.AFTER_PARSING, new Instance(context.getMetaAccess(), context.getAssumptions(), canonicalizeReads, customCanonicalizer));
+        plan.addPhase(PhasePosition.AFTER_PARSING, new Instance(context, canonicalizeReads, customCanonicalizer));
     }
 
     private static final class Instance extends Phase {
 
         private final int newNodesMark;
-        private final Assumptions assumptions;
-        private final MetaAccessProvider metaAccess;
+        private final PhaseContext context;
         private final CustomCanonicalizer customCanonicalizer;
         private final Iterable<Node> initWorkingSet;
         private final boolean canonicalizeReads;
@@ -119,23 +118,22 @@
         private NodeWorkList workList;
         private Tool tool;
 
-        private Instance(MetaAccessProvider metaAccess, Assumptions assumptions, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) {
-            this(metaAccess, assumptions, canonicalizeReads, null, 0, customCanonicalizer);
+        private Instance(PhaseContext context, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) {
+            this(context, canonicalizeReads, null, 0, customCanonicalizer);
         }
 
-        private Instance(MetaAccessProvider metaAccess, Assumptions assumptions, boolean canonicalizeReads, Iterable<Node> workingSet, CustomCanonicalizer customCanonicalizer) {
-            this(metaAccess, assumptions, canonicalizeReads, workingSet, 0, customCanonicalizer);
+        private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<Node> workingSet, CustomCanonicalizer customCanonicalizer) {
+            this(context, canonicalizeReads, workingSet, 0, customCanonicalizer);
         }
 
-        private Instance(MetaAccessProvider metaAccess, Assumptions assumptions, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
-            this(metaAccess, assumptions, canonicalizeReads, null, newNodesMark, customCanonicalizer);
+        private Instance(PhaseContext context, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
+            this(context, canonicalizeReads, null, newNodesMark, customCanonicalizer);
         }
 
-        private Instance(MetaAccessProvider metaAccess, Assumptions assumptions, boolean canonicalizeReads, Iterable<Node> workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
+        private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<Node> workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
             super("Canonicalizer");
             this.newNodesMark = newNodesMark;
-            this.assumptions = assumptions;
-            this.metaAccess = metaAccess;
+            this.context = context;
             this.canonicalizeReads = canonicalizeReads;
             this.customCanonicalizer = customCanonicalizer;
             this.initWorkingSet = workingSet;
@@ -192,7 +190,7 @@
                             boolean improvedStamp = tryInferStamp(valueNode);
                             Constant constant = valueNode.stamp().asConstant();
                             if (constant != null && !(node instanceof ConstantNode)) {
-                                performReplacement(valueNode, ConstantNode.forConstant(constant, metaAccess, valueNode.graph()));
+                                performReplacement(valueNode, ConstantNode.forConstant(constant, context.getMetaAccess(), valueNode.graph()));
                             } else if (improvedStamp) {
                                 // the improved stamp may enable additional canonicalization
                                 tryCanonicalize(valueNode, nodeClass);
@@ -372,12 +370,17 @@
              */
             @Override
             public Assumptions assumptions() {
-                return assumptions;
+                return context.getAssumptions();
             }
 
             @Override
             public MetaAccessProvider getMetaAccess() {
-                return metaAccess;
+                return context.getMetaAccess();
+            }
+
+            @Override
+            public ConstantReflectionProvider getConstantReflection() {
+                return context.getConstantReflection();
             }
 
             @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Oct 11 17:53:29 2013 +0200
@@ -52,12 +52,12 @@
     private static final DebugMetric metricObjectEqualsRemoved = Debug.metric("ObjectEqualsRemoved");
     private static final DebugMetric metricGuardsRemoved = Debug.metric("GuardsRemoved");
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
 
     private StructuredGraph graph;
 
-    public ConditionalEliminationPhase(MetaAccessProvider metaAccessProvider) {
-        this.metaAccessProvider = metaAccessProvider;
+    public ConditionalEliminationPhase(MetaAccessProvider metaAccess) {
+        this.metaAccess = metaAccess;
     }
 
     @Override
@@ -510,8 +510,8 @@
                     }
                     PiNode piNode;
                     if (isNull) {
-                        ConstantNode nullObject = ConstantNode.forObject(null, metaAccessProvider, graph);
-                        piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccessProvider), replacementAnchor.asNode()));
+                        ConstantNode nullObject = ConstantNode.forObject(null, metaAccess, graph);
+                        piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccess), replacementAnchor.asNode()));
                     } else {
                         piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode()));
                     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Oct 11 17:53:29 2013 +0200
@@ -184,7 +184,7 @@
         InlineInfo callee = calleeInfo.callee();
         try {
             List<Node> invokeUsages = callee.invoke().asNode().usages().snapshot();
-            callee.inline(context.getMetaAccess(), context.getCodeCache(), callerAssumptions, context.getReplacements());
+            callee.inline(context, callerAssumptions);
             callerAssumptions.record(calleeInfo.assumptions());
             metricInliningRuns.increment();
             Debug.dump(callerGraph, "after %s", callee);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Oct 11 17:53:29 2013 +0200
@@ -51,6 +51,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.InliningPhase.InliningData;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 public class InliningUtil {
 
@@ -293,7 +294,7 @@
          * return value of the inlined method (or null for void methods and methods that have no
          * non-exceptional exit).
          */
-        void inline(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements);
+        void inline(Providers providers, Assumptions assumptions);
 
         /**
          * Try to make the call static bindable to avoid interface and virtual method calls.
@@ -367,7 +368,7 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements) {
+        public void inline(Providers providers, Assumptions assumptions) {
             inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck);
         }
 
@@ -470,8 +471,8 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements) {
-            createGuard(graph(), metaAccess);
+        public void inline(Providers providers, Assumptions assumptions) {
+            createGuard(graph(), providers.getMetaAccess());
             inline(invoke, concrete, inlineableElement, assumptions, false);
         }
 
@@ -587,11 +588,11 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements) {
+        public void inline(Providers providers, Assumptions assumptions) {
             if (hasSingleMethod()) {
-                inlineSingleMethod(graph(), metaAccess, assumptions);
+                inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions);
             } else {
-                inlineMultipleMethods(graph(), metaAccess, assumptions, replacements, codeCache);
+                inlineMultipleMethods(graph(), providers, assumptions);
             }
         }
 
@@ -603,7 +604,7 @@
             return notRecordedTypeProbability > 0;
         }
 
-        private void inlineMultipleMethods(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions, Replacements replacements, GraalCodeCacheProvider codeCache) {
+        private void inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) {
             int numberOfMethods = concretes.size();
             FixedNode continuation = invoke.next();
 
@@ -658,7 +659,7 @@
             assert invoke.asNode().isAlive();
 
             // replace the invoke with a switch on the type of the actual receiver
-            boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, metaAccess);
+            boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getMetaAccess());
 
             assert invoke.next() == continuation;
             invoke.setNext(null);
@@ -713,8 +714,9 @@
                 if (opportunities > 0) {
                     metricInliningTailDuplication.increment();
                     Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities);
-                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new PhaseContext(metaAccess, codeCache, assumptions, replacements),
-                                    new CanonicalizerPhase(!AOTCompilation.getValue()));
+                    PhaseContext phaseContext = new PhaseContext(providers, assumptions);
+                    CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue());
+                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer);
                 }
             }
         }
@@ -1006,9 +1008,9 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements) {
+        public void inline(Providers providers, Assumptions assumptions) {
             assumptions.record(takenAssumption);
-            super.inline(metaAccess, codeCache, assumptions, replacements);
+            super.inline(providers, assumptions);
         }
 
         @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Fri Oct 11 17:53:29 2013 +0200
@@ -63,16 +63,26 @@
         }
 
         @Override
-        public GraalCodeCacheProvider getCodeCache() {
+        public CodeCacheProvider getCodeCache() {
             return context.getCodeCache();
         }
 
         @Override
+        public ConstantReflectionProvider getConstantReflection() {
+            return context.getConstantReflection();
+        }
+
+        @Override
         public MetaAccessProvider getMetaAccess() {
             return context.getMetaAccess();
         }
 
         @Override
+        public LoweringProvider getLowerer() {
+            return context.getLowerer();
+        }
+
+        @Override
         public Replacements getReplacements() {
             return context.getReplacements();
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Fri Oct 11 17:53:29 2013 +0200
@@ -23,9 +23,9 @@
 package com.oracle.graal.phases.tiers;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 
 public class HighTierContext extends PhaseContext {
 
@@ -34,9 +34,8 @@
     private final GraphCache cache;
     private final OptimisticOptimizations optimisticOpts;
 
-    public HighTierContext(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements, GraphCache cache, PhasePlan plan,
-                    OptimisticOptimizations optimisticOpts) {
-        super(metaAccess, codeCache, assumptions, replacements);
+    public HighTierContext(Providers copyFrom, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
+        super(copyFrom, assumptions);
         this.plan = plan;
         this.cache = cache;
         this.optimisticOpts = optimisticOpts;
@@ -55,6 +54,6 @@
     }
 
     public HighTierContext replaceAssumptions(Assumptions newAssumptions) {
-        return new HighTierContext(getMetaAccess(), getCodeCache(), newAssumptions, getReplacements(), getGraphCache(), getPhasePlan(), getOptimisticOptimizations());
+        return new HighTierContext(this, newAssumptions, getGraphCache(), getPhasePlan(), getOptimisticOptimizations());
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Fri Oct 11 17:53:29 2013 +0200
@@ -23,15 +23,14 @@
 package com.oracle.graal.phases.tiers;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 
 public class LowTierContext extends PhaseContext {
 
     private final TargetDescription target;
 
-    public LowTierContext(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements, TargetDescription target) {
-        super(metaAccess, codeCache, assumptions, replacements);
+    public LowTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target) {
+        super(copyFrom, assumptions);
         this.target = target;
     }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Fri Oct 11 17:53:29 2013 +0200
@@ -23,17 +23,16 @@
 package com.oracle.graal.phases.tiers;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 
 public class MidTierContext extends PhaseContext {
 
     private final TargetDescription target;
     private final OptimisticOptimizations optimisticOpts;
 
-    public MidTierContext(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements, TargetDescription target, OptimisticOptimizations optimisticOpts) {
-        super(metaAccess, codeCache, assumptions, replacements);
+    public MidTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target, OptimisticOptimizations optimisticOpts) {
+        super(copyFrom, assumptions);
         this.target = target;
         this.optimisticOpts = optimisticOpts;
     }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Fri Oct 11 17:53:29 2013 +0200
@@ -25,34 +25,24 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
-
-public class PhaseContext {
+import com.oracle.graal.phases.util.*;
 
-    private final MetaAccessProvider metaAccess;
-    private final GraalCodeCacheProvider codeCache;
+public class PhaseContext extends Providers {
+
     private final Assumptions assumptions;
-    private final Replacements replacements;
 
-    public PhaseContext(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, Replacements replacements) {
-        this.metaAccess = metaAccess;
-        this.codeCache = codeCache;
+    public PhaseContext(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Assumptions assumptions,
+                    Replacements replacements) {
+        super(metaAccess, codeCache, constantReflection, lowerer, replacements);
         this.assumptions = assumptions;
-        this.replacements = replacements;
     }
 
-    public MetaAccessProvider getMetaAccess() {
-        return metaAccess;
-    }
-
-    public GraalCodeCacheProvider getCodeCache() {
-        return codeCache;
+    public PhaseContext(Providers copyFrom, Assumptions assumptions) {
+        super(copyFrom);
+        this.assumptions = assumptions;
     }
 
     public Assumptions getAssumptions() {
         return assumptions;
     }
-
-    public Replacements getReplacements() {
-        return replacements;
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java	Fri Oct 11 17:53:29 2013 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.util;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * A set of providers, some of which may not be present (i.e., null).
+ */
+public class Providers {
+
+    private final MetaAccessProvider metaAccess;
+    private final CodeCacheProvider codeCache;
+    private final LoweringProvider lowerer;
+    private final ConstantReflectionProvider constantReflection;
+    private final Replacements replacements;
+
+    public Providers(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Replacements replacements) {
+        this.metaAccess = metaAccess;
+        this.codeCache = codeCache;
+        this.constantReflection = constantReflection;
+        this.lowerer = lowerer;
+        this.replacements = replacements;
+    }
+
+    public Providers(Providers copyFrom) {
+        this.metaAccess = copyFrom.metaAccess;
+        this.codeCache = copyFrom.codeCache;
+        this.constantReflection = copyFrom.constantReflection;
+        this.lowerer = copyFrom.lowerer;
+        this.replacements = copyFrom.replacements;
+    }
+
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccess;
+    }
+
+    public CodeCacheProvider getCodeCache() {
+        return codeCache;
+    }
+
+    public LoweringProvider getLowerer() {
+        return lowerer;
+    }
+
+    public ConstantReflectionProvider getConstantReflection() {
+        return constantReflection;
+    }
+
+    public Replacements getReplacements() {
+        return replacements;
+    }
+}
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Fri Oct 11 17:53:29 2013 +0200
@@ -144,9 +144,9 @@
             cfgPrinter.cfg = cfgPrinter.lir.cfg;
         }
 
-        CodeCacheProvider runtime = Debug.contextLookup(CodeCacheProvider.class);
-        if (runtime != null) {
-            cfgPrinter.target = runtime.getTarget();
+        CodeCacheProvider codeCache = Debug.contextLookup(CodeCacheProvider.class);
+        if (codeCache != null) {
+            cfgPrinter.target = codeCache.getTarget();
         }
 
         if (object instanceof BciBlockMapping) {
@@ -171,10 +171,10 @@
 
         } else if (object instanceof CompilationResult) {
             final CompilationResult compResult = (CompilationResult) object;
-            cfgPrinter.printMachineCode(runtime.disassemble(compResult, null), message);
+            cfgPrinter.printMachineCode(codeCache.disassemble(compResult, null), message);
         } else if (isCompilationResultAndInstalledCode(object)) {
             Object[] tuple = (Object[]) object;
-            cfgPrinter.printMachineCode(runtime.disassemble((CompilationResult) tuple[0], (InstalledCode) tuple[1]), message);
+            cfgPrinter.printMachineCode(codeCache.disassemble((CompilationResult) tuple[0], (InstalledCode) tuple[1]), message);
         } else if (object instanceof Interval[]) {
             cfgPrinter.printIntervals(message, (Interval[]) object);
 
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -28,12 +28,12 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.calc.ConvertNode.Op;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -149,8 +149,8 @@
 
         private final EnumMap<Op, SnippetInfo> snippets;
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
 
             snippets = new EnumMap<>(Op.class);
             snippets.put(Op.F2I, snippet(AMD64ConvertSnippets.class, "f2i"));
@@ -180,7 +180,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, args);
-            template.instantiate(metaAccess, replacee, DEFAULT_REPLACER, tool, args);
+            template.instantiate(providers.getMetaAccess(), replacee, DEFAULT_REPLACER, tool, args);
             graph.removeFloating(convert);
         }
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -51,7 +51,8 @@
                 StructuredGraph graph = parse(snippet);
                 PhasePlan phasePlan = getDefaultPhasePlan();
                 Assumptions assumptions = new Assumptions(true);
-                HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan,
+                                OptimisticOptimizations.ALL);
                 Debug.dump(graph, "Graph");
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -49,7 +49,7 @@
 
     public ObjectAccessTest() {
         target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(getMetaAccess(), getCodeCache(), new Assumptions(false), target);
+        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target);
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -53,7 +53,7 @@
 
     public PointerTest() {
         target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(getMetaAccess(), getCodeCache(), new Assumptions(false), target);
+        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target);
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
@@ -404,7 +404,7 @@
 
     private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
         Assumptions assumptions = new Assumptions(true);
-        HighTierContext context = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, null, OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, null, OptimisticOptimizations.ALL);
 
         StructuredGraph graph = parse(snippetName);
         new CanonicalizerPhase(false).apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -43,7 +43,7 @@
 
     public WordTest() {
         TargetDescription target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(getMetaAccess(), getCodeCache(), new Assumptions(false), target);
+        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target);
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Fri Oct 11 17:53:29 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -206,8 +207,8 @@
         private final EnumMap<Kind, SnippetInfo> boxSnippets = new EnumMap<>(Kind.class);
         private final EnumMap<Kind, SnippetInfo> unboxSnippets = new EnumMap<>(Kind.class);
 
-        public Templates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            super(metaAccess, codeCache, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
             for (Kind kind : new Kind[]{Kind.Boolean, Kind.Byte, Kind.Char, Kind.Double, Kind.Float, Kind.Int, Kind.Long, Kind.Short}) {
                 boxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "ValueOf"));
                 unboxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "Value"));
@@ -215,7 +216,7 @@
         }
 
         public void lower(BoxNode box, LoweringTool tool) {
-            FloatingNode canonical = canonicalizeBoxing(box, metaAccess);
+            FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess());
             // if in AOT mode, we don't want to embed boxed constants.
             if (canonical != null && !AOTCompilation.getValue()) {
                 box.graph().replaceFloating(box, canonical);
@@ -225,7 +226,7 @@
 
                 SnippetTemplate template = template(args);
                 Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", box.graph(), box, template, args);
-                template.instantiate(metaAccess, box, DEFAULT_REPLACER, tool, args);
+                template.instantiate(providers.getMetaAccess(), box, DEFAULT_REPLACER, tool, args);
                 GraphUtil.killWithUnusedFloatingInputs(box);
             }
         }
@@ -236,7 +237,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", unbox.graph(), unbox, template, args);
-            template.instantiate(metaAccess, unbox, DEFAULT_REPLACER, tool, args);
+            template.instantiate(providers.getMetaAccess(), unbox, DEFAULT_REPLACER, tool, args);
             GraphUtil.killWithUnusedFloatingInputs(unbox);
         }
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Fri Oct 11 17:53:29 2013 +0200
@@ -27,13 +27,13 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
 import com.oracle.graal.replacements.SnippetTemplate.UsageReplacer;
@@ -53,8 +53,8 @@
  */
 public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates {
 
-    public InstanceOfSnippetsTemplates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-        super(metaAccess, codeCache, replacements, target);
+    public InstanceOfSnippetsTemplates(Providers providers, TargetDescription target) {
+        super(providers, target);
     }
 
     /**
@@ -77,7 +77,7 @@
                 replacer.replaceUsingInstantiation();
             } else {
                 Arguments args = makeArguments(replacer, tool);
-                template(args).instantiate(metaAccess, instanceOf, replacer, tool, args);
+                template(args).instantiate(providers.getMetaAccess(), instanceOf, replacer, tool, args);
             }
         }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri Oct 11 17:53:29 2013 +0200
@@ -45,14 +45,14 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.Snippet.DefaultSnippetInliningPolicy;
 import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy;
 import com.oracle.graal.word.phases.*;
 
 public class ReplacementsImpl implements Replacements {
 
-    protected final MetaAccessProvider metaAccess;
-    protected final GraalCodeCacheProvider codeCache;
+    protected final Providers providers;
     protected final TargetDescription target;
     protected final Assumptions assumptions;
 
@@ -68,9 +68,9 @@
     private final Set<ResolvedJavaMethod> forcedSubstitutions;
     private final Map<Class<? extends SnippetTemplateCache>, SnippetTemplateCache> snippetTemplateCache;
 
-    public ReplacementsImpl(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, TargetDescription target) {
-        this.metaAccess = metaAccess;
-        this.codeCache = codeCache;
+    public ReplacementsImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, LoweringProvider lowerer, Assumptions assumptions,
+                    TargetDescription target) {
+        this.providers = new Providers(metaAccess, codeCache, constantReflection, lowerer, this);
         this.target = target;
         this.assumptions = assumptions;
         this.graphs = new ConcurrentHashMap<>();
@@ -169,6 +169,7 @@
      * @return the original method
      */
     protected ResolvedJavaMethod registerMethodSubstitution(Member originalMember, Method substituteMethod) {
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
         ResolvedJavaMethod substitute = metaAccess.lookupJavaMethod(substituteMethod);
         ResolvedJavaMethod original;
         if (originalMember instanceof Method) {
@@ -191,6 +192,7 @@
      */
     protected ResolvedJavaMethod registerMacroSubstitution(Member originalMethod, Class<? extends FixedWithNextNode> macro) {
         ResolvedJavaMethod originalJavaMethod;
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
         if (originalMethod instanceof Method) {
             originalJavaMethod = metaAccess.lookupJavaMethod((Method) originalMethod);
         } else {
@@ -207,7 +209,7 @@
             policyClass = snippet.inlining();
         }
         if (policyClass == SnippetInliningPolicy.class) {
-            return new DefaultSnippetInliningPolicy(metaAccess);
+            return new DefaultSnippetInliningPolicy(providers.getMetaAccess());
         }
         try {
             return policyClass.getConstructor().newInstance();
@@ -287,7 +289,7 @@
          * Does final processing of a snippet graph.
          */
         protected void finalizeGraph(StructuredGraph graph, boolean removeAllFrameStates) {
-            new NodeIntrinsificationPhase(metaAccess).apply(graph);
+            new NodeIntrinsificationPhase(providers.getMetaAccess()).apply(graph);
             if (!SnippetTemplate.hasConstantParameter(method)) {
                 NodeIntrinsificationVerificationPhase.verify(graph);
             }
@@ -333,12 +335,13 @@
 
                 @Override
                 public void run() {
+                    MetaAccessProvider metaAccess = providers.getMetaAccess();
                     new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
                     new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
                     new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
 
                     if (OptCanonicalizer.getValue()) {
-                        new CanonicalizerPhase(true).apply(graph, new PhaseContext(metaAccess, codeCache, assumptions, ReplacementsImpl.this));
+                        new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
                     }
                 }
             });
@@ -358,7 +361,7 @@
          */
         protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) {
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(caller, new PhaseContext(metaAccess, codeCache, assumptions, ReplacementsImpl.this));
+                new CanonicalizerPhase(true).apply(caller, new PhaseContext(providers, assumptions));
             }
         }
 
@@ -366,10 +369,10 @@
          * Called after all inlining for a given graph is complete.
          */
         protected void afterInlining(StructuredGraph graph) {
-            new NodeIntrinsificationPhase(metaAccess).apply(graph);
+            new NodeIntrinsificationPhase(providers.getMetaAccess()).apply(graph);
             new DeadCodeEliminationPhase().apply(graph);
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(graph, new PhaseContext(metaAccess, codeCache, assumptions, ReplacementsImpl.this));
+                new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
             }
         }
 
@@ -384,6 +387,7 @@
                         ResolvedJavaMethod callee = callTarget.targetMethod();
                         if (callee == method) {
                             final StructuredGraph originalGraph = new StructuredGraph(original);
+                            MetaAccessProvider metaAccess = providers.getMetaAccess();
                             new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph);
                             new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
                             new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
@@ -479,7 +483,7 @@
                 parameters = Arrays.copyOfRange(parameters, 1, parameters.length);
             }
         } else {
-            Signature signature = metaAccess.parseMethodDescriptor(methodSubstitution);
+            Signature signature = providers.getMetaAccess().parseMethodDescriptor(methodSubstitution);
             parameters = new Class[signature.getParameterCount(false)];
             for (int i = 0; i < parameters.length; i++) {
                 parameters[i] = resolveType(signature.getParameterType(i, null));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Oct 11 17:53:29 2013 +0200
@@ -47,6 +47,7 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.FloatingReadPhase.MemoryMapImpl;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
 import com.oracle.graal.replacements.nodes.*;
@@ -321,16 +322,12 @@
      */
     public abstract static class AbstractTemplates implements SnippetTemplateCache {
 
-        protected final MetaAccessProvider metaAccess;
-        protected final GraalCodeCacheProvider codeCache;
-        protected final Replacements replacements;
+        protected final Providers providers;
         protected final TargetDescription target;
         private final ConcurrentHashMap<CacheKey, SnippetTemplate> templates;
 
-        protected AbstractTemplates(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Replacements replacements, TargetDescription target) {
-            this.metaAccess = metaAccess;
-            this.codeCache = codeCache;
-            this.replacements = replacements;
+        protected AbstractTemplates(Providers providers, TargetDescription target) {
+            this.providers = providers;
             this.target = target;
             this.templates = new ConcurrentHashMap<>();
         }
@@ -349,7 +346,7 @@
                 }
             }
             assert found != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + (methodName == null ? "" : " named " + methodName);
-            return new SnippetInfo(metaAccess.lookupJavaMethod(found));
+            return new SnippetInfo(providers.getMetaAccess().lookupJavaMethod(found));
         }
 
         /**
@@ -363,7 +360,7 @@
 
                         @Override
                         public SnippetTemplate call() throws Exception {
-                            return new SnippetTemplate(metaAccess, codeCache, replacements, args);
+                            return new SnippetTemplate(providers, args);
                         }
                     });
                     templates.put(args.cacheKey, template);
@@ -394,19 +391,21 @@
     /**
      * Creates a snippet template.
      */
-    protected SnippetTemplate(final MetaAccessProvider metaAccess, final GraalCodeCacheProvider codeCache, final Replacements replacements, Arguments args) {
-        StructuredGraph snippetGraph = replacements.getSnippet(args.info.method);
+    protected SnippetTemplate(final Providers providers, Arguments args) {
+        StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method);
 
         ResolvedJavaMethod method = snippetGraph.method();
         Signature signature = method.getSignature();
 
-        PhaseContext context = new PhaseContext(metaAccess, codeCache, replacements.getAssumptions(), replacements);
+        Assumptions assumptions = providers.getReplacements().getAssumptions();
+        PhaseContext phaseContext = new PhaseContext(providers, assumptions);
 
         // Copy snippet graph, replacing constant parameters with given arguments
         final StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
         IdentityHashMap<Node, Node> nodeReplacements = new IdentityHashMap<>();
         nodeReplacements.put(snippetGraph.start(), snippetCopy.start());
 
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
         assert checkTemplate(metaAccess, args, method, signature);
 
         int parameterCount = args.info.getParameterCount();
@@ -437,7 +436,7 @@
         if (!nodeReplacements.isEmpty()) {
             // Do deferred intrinsification of node intrinsics
             new NodeIntrinsificationPhase(metaAccess).apply(snippetCopy);
-            new CanonicalizerPhase(true).apply(snippetCopy, context);
+            new CanonicalizerPhase(true).apply(snippetCopy, phaseContext);
         }
         NodeIntrinsificationVerificationPhase.verify(snippetCopy);
 
@@ -493,8 +492,8 @@
                 if (loopBegin != null) {
                     LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
                     int mark = snippetCopy.getMark();
-                    LoopTransformations.fullUnroll(loop, context, new CanonicalizerPhase(true));
-                    new CanonicalizerPhase(true).applyIncremental(snippetCopy, context, mark);
+                    LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true));
+                    new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark);
                 }
                 FixedNode explodeLoopNext = explodeLoop.next();
                 explodeLoop.clearSuccessors();
@@ -510,7 +509,7 @@
         Debug.scope("LoweringSnippetTemplate", snippetCopy, new Runnable() {
 
             public void run() {
-                PhaseContext c = new PhaseContext(metaAccess, codeCache, new Assumptions(false), replacements);
+                PhaseContext c = new PhaseContext(providers, new Assumptions(false));
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(snippetCopy, c);
             }
         });
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -96,7 +96,7 @@
      */
     protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
         replacementGraph.setGuardsStage(graph().getGuardsStage());
-        final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.assumptions(), tool.getReplacements());
+        final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getLowerer(), tool.assumptions(), tool.getReplacements());
         Debug.scope("LoweringReplacement", replacementGraph, new Runnable() {
 
             public void run() {
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Oct 11 17:53:29 2013 +0200
@@ -36,10 +36,12 @@
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.printer.*;
@@ -56,8 +58,10 @@
     public PartialEvaluationTest() {
         // Make sure Truffle runtime is initialized.
         Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime);
-        this.partialEvaluator = new PartialEvaluator(getMetaAccess(), getCodeCache(), ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(), new TruffleCache(getMetaAccess(), getCodeCache(),
-                        GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations, ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements()));
+        Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
+        Providers providers = new Providers(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), truffleReplacements);
+        TruffleCache truffleCache = new TruffleCache(providers, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations);
+        this.partialEvaluator = new PartialEvaluator(providers, truffleCache);
 
         DebugEnvironment.initialize(System.out);
     }
@@ -105,7 +109,7 @@
             public StructuredGraph call() {
                 StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads);
-                PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements);
+                PhaseContext context = new PhaseContext(getProviders(), assumptions);
 
                 if (resultGraph.hasLoops()) {
                     boolean unrolled;
@@ -160,7 +164,7 @@
             frameState.replaceAtUsages(null);
             frameState.safeDelete();
         }
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getMetaAccess(), getCodeCache(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         new DeadCodeEliminationPhase().apply(graph);
     }
 
@@ -172,7 +176,7 @@
             public StructuredGraph call() {
                 Assumptions assumptions = new Assumptions(false);
                 StructuredGraph graph = parse(methodName);
-                PhaseContext context = new PhaseContext(getMetaAccess(), getCodeCache(), assumptions, replacements);
+                PhaseContext context = new PhaseContext(getProviders(), assumptions);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
                 canonicalizer.apply(graph, context);
 
@@ -187,7 +191,8 @@
                 canonicalizer.apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
 
-                HighTierContext highTierContext = new HighTierContext(getMetaAccess(), getCodeCache(), assumptions, replacements, null, plan, OptimisticOptimizations.NONE);
+                HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, plan,
+                                OptimisticOptimizations.NONE);
                 InliningPhase inliningPhase = new InliningPhase(canonicalizer);
                 inliningPhase.apply(graph, highTierContext);
                 removeFrameStates(graph);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Oct 11 17:53:29 2013 +0200
@@ -50,6 +50,7 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode;
@@ -66,28 +67,24 @@
  */
 public class PartialEvaluator {
 
-    private final MetaAccessProvider metaAccess;
-    private final GraalCodeCacheProvider codeCache;
+    private final Providers providers;
     private final ResolvedJavaMethod executeHelperMethod;
     private final CanonicalizerPhase canonicalizer;
     private final ResolvedJavaType[] skippedExceptionTypes;
-    private final Replacements replacements;
     private Set<Constant> constantReceivers;
     private final HotSpotGraphCache cache;
     private final TruffleCache truffleCache;
 
-    public PartialEvaluator(MetaAccessProvider metaAccessProvider, GraalCodeCacheProvider codeCache, Replacements replacements, TruffleCache truffleCache) {
-        this.metaAccess = metaAccessProvider;
-        this.codeCache = codeCache;
-        CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(metaAccessProvider);
+    public PartialEvaluator(Providers providers, TruffleCache truffleCache) {
+        this.providers = providers;
+        CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection());
         this.canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue(), customCanonicalizer);
-        this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(metaAccessProvider);
-        this.replacements = replacements;
+        this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess());
         this.cache = HotSpotGraalRuntime.graalRuntime().getCache();
         this.truffleCache = truffleCache;
 
         try {
-            executeHelperMethod = metaAccessProvider.lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class));
+            executeHelperMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class));
         } catch (NoSuchMethodException ex) {
             throw new RuntimeException(ex);
         }
@@ -118,18 +115,18 @@
 
             @Override
             public void run() {
-                new GraphBuilderPhase(metaAccess, config, TruffleCompilerImpl.Optimizations).apply(graph);
+                new GraphBuilderPhase(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations).apply(graph);
 
                 // Replace thisNode with constant.
                 LocalNode thisNode = graph.getLocal(0);
-                thisNode.replaceAndDelete(ConstantNode.forObject(node, metaAccess, graph));
+                thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph));
 
                 // Canonicalize / constant propagate.
-                PhaseContext baseContext = new PhaseContext(metaAccess, codeCache, assumptions, replacements);
+                PhaseContext baseContext = new PhaseContext(providers, assumptions);
                 canonicalizer.apply(graph, baseContext);
 
                 // Intrinsify methods.
-                new ReplaceIntrinsicsPhase(replacements).apply(graph);
+                new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
 
                 NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first();
                 if (newFrameNode == null) {
@@ -159,7 +156,7 @@
                 // Additional inlining.
                 final PhasePlan plan = new PhasePlan();
                 canonicalizer.apply(graph, baseContext);
-                HighTierContext context = new HighTierContext(metaAccess, codeCache, assumptions, replacements, cache, plan, OptimisticOptimizations.NONE);
+                HighTierContext tierContext = new HighTierContext(providers, assumptions, cache, plan, OptimisticOptimizations.NONE);
 
                 for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) {
                     Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage());
@@ -167,7 +164,7 @@
                 }
 
                 // EA frame and clean up.
-                new PartialEscapePhase(false, canonicalizer).apply(graph, context);
+                new PartialEscapePhase(false, canonicalizer).apply(graph, tierContext);
                 new VerifyNoIntrinsicsLeftPhase().apply(graph, false);
                 for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) {
                     materializeNode.replaceAtUsages(materializeNode.getFrame());
@@ -192,7 +189,7 @@
     }
 
     private void expandTree(StructuredGraph graph, Assumptions assumptions) {
-        PhaseContext context = new PhaseContext(metaAccess, codeCache, assumptions, replacements);
+        PhaseContext phaseContext = new PhaseContext(providers, assumptions);
         boolean changed;
         do {
             changed = false;
@@ -206,6 +203,7 @@
                         ConstantNode constantNode = (ConstantNode) methodCallTargetNode.arguments().first();
                         constantReceivers.add(constantNode.asConstant());
                     }
+                    Replacements replacements = providers.getReplacements();
                     StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
 
                     if (inlineGraph == null) {
@@ -219,7 +217,7 @@
 
                     if (inlineGraph == null && !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers()) &&
                                     methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.SlowPath.class) == null) {
-                        inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, context);
+                        inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext);
                     }
 
                     if (inlineGraph != null) {
@@ -230,7 +228,7 @@
                             int nodeCountAfter = graph.getNodeCount();
                             Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter);
                         }
-                        canonicalizer.applyIncremental(graph, context, mark);
+                        canonicalizer.applyIncremental(graph, phaseContext, mark);
                         changed = true;
                     }
                 }
@@ -242,7 +240,7 @@
         } while (changed);
     }
 
-    private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext context) {
+    private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext) {
 
         StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer);
 
@@ -254,7 +252,7 @@
                 ValueNode arg = arguments.get(local.index());
                 if (arg.isConstant()) {
                     Constant constant = arg.asConstant();
-                    ConstantNode constantNode = ConstantNode.forConstant(constant, metaAccess, graphCopy);
+                    ConstantNode constantNode = ConstantNode.forConstant(constant, phaseContext.getMetaAccess(), graphCopy);
                     local.replaceAndDelete(constantNode);
                     for (Node usage : constantNode.usages()) {
                         if (usage instanceof Canonicalizable) {
@@ -268,7 +266,7 @@
                 @Override
                 public void run() {
 
-                    canonicalizer.applyIncremental(graphCopy, context, modifiedNodes);
+                    canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes);
                     boolean unrolled;
                     do {
                         unrolled = false;
@@ -277,7 +275,7 @@
                         for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) {
                             if (ex.counted().isConstantMaxTripCount()) {
                                 long constant = ex.counted().constantMaxTripCount();
-                                LoopTransformations.fullUnroll(ex, context, canonicalizer);
+                                LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer);
                                 Debug.dump(graphCopy, "After loop unrolling %d times", constant);
                                 unrolled = true;
                                 break;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Fri Oct 11 17:53:29 2013 +0200
@@ -36,10 +36,12 @@
 
 final class PartialEvaluatorCanonicalizer implements CanonicalizerPhase.CustomCanonicalizer {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
+    private final ConstantReflectionProvider constantReflection;
 
-    PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccessProvider) {
-        this.metaAccessProvider = metaAccessProvider;
+    PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
+        this.metaAccess = metaAccess;
+        this.constantReflection = constantReflection;
     }
 
     @Override
@@ -51,7 +53,7 @@
                                 loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) {
                     Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant());
                     assert verifyFieldValue(loadFieldNode.field(), constant);
-                    return ConstantNode.forConstant(constant, metaAccessProvider, node.graph());
+                    return ConstantNode.forConstant(constant, metaAccess, node.graph());
                 }
             }
         } else if (node instanceof LoadIndexedNode) {
@@ -62,9 +64,9 @@
                 if (index >= 0 && index < Array.getLength(array)) {
                     int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass());
                     int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass());
-                    Constant constant = metaAccessProvider.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale,
+                    Constant constant = constantReflection.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale,
                                     loadIndexedNode.elementKind() == Kind.Object);
-                    return ConstantNode.forConstant(constant, metaAccessProvider, loadIndexedNode.graph());
+                    return ConstantNode.forConstant(constant, metaAccess, loadIndexedNode.graph());
                 }
             }
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Fri Oct 11 17:53:29 2013 +0200
@@ -38,12 +38,12 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.truffle.phases.*;
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
@@ -54,23 +54,19 @@
  */
 public final class TruffleCache {
 
-    private final MetaAccessProvider metaAccess;
-    private final GraalCodeCacheProvider codeCache;
+    private final Providers providers;
     private final GraphBuilderConfiguration config;
     private final OptimisticOptimizations optimisticOptimizations;
-    private final Replacements replacements;
 
     private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>();
     private final StructuredGraph markerGraph = new StructuredGraph();
     private final ResolvedJavaType stringBuilderClass;
 
-    public TruffleCache(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations, Replacements replacements) {
-        this.metaAccess = metaAccess;
-        this.codeCache = codeCache;
+    public TruffleCache(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) {
+        this.providers = providers;
         this.config = config;
         this.optimisticOptimizations = optimisticOptimizations;
-        this.replacements = replacements;
-        this.stringBuilderClass = metaAccess.lookupJavaType(StringBuilder.class);
+        this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class);
     }
 
     @SuppressWarnings("unused")
@@ -94,13 +90,13 @@
         }
 
         cache.put(key, markerGraph);
-        resultGraph = Debug.scope("TruffleCache", new Object[]{metaAccess, method}, new Callable<StructuredGraph>() {
+        resultGraph = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method}, new Callable<StructuredGraph>() {
 
             public StructuredGraph call() {
 
                 final StructuredGraph graph = new StructuredGraph(method);
-                PhaseContext context = new PhaseContext(metaAccess, codeCache, new Assumptions(false), replacements);
-                new GraphBuilderPhase(metaAccess, config, optimisticOptimizations).apply(graph);
+                PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
+                new GraphBuilderPhase(phaseContext.getMetaAccess(), config, optimisticOptimizations).apply(graph);
 
                 for (LocalNode l : graph.getNodes(LocalNode.class)) {
                     if (l.kind() == Kind.Object) {
@@ -110,7 +106,7 @@
                 }
 
                 // Intrinsify methods.
-                new ReplaceIntrinsicsPhase(replacements).apply(graph);
+                new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
 
                 // Convert deopt to guards.
                 new ConvertDeoptimizeToGuardPhase().apply(graph);
@@ -121,14 +117,14 @@
                 int mark = 0;
                 while (true) {
 
-                    partialEscapePhase.apply(graph, context);
+                    partialEscapePhase.apply(graph, phaseContext);
 
                     // Conditional elimination.
-                    ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(metaAccess);
+                    ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(phaseContext.getMetaAccess());
                     conditionalEliminationPhase.apply(graph);
 
                     // Canonicalize / constant propagate.
-                    canonicalizerPhase.apply(graph, context);
+                    canonicalizerPhase.apply(graph, phaseContext);
 
                     boolean inliningProgress = false;
                     for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) {
@@ -138,7 +134,7 @@
                             for (Node newNode : graph.getNewNodes(mark)) {
                                 if (newNode instanceof MethodCallTargetNode) {
                                     MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode;
-                                    Class<? extends FixedWithNextNode> macroSubstitution = replacements.getMacroSubstitution(methodCallTargetNode.targetMethod());
+                                    Class<? extends FixedWithNextNode> macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod());
                                     if (macroSubstitution != null) {
                                         InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution);
                                     } else {
@@ -168,14 +164,14 @@
                                     }
                                 }
                             }
-                            canonicalizerPhase.applyIncremental(graph, context, canonicalizerUsages);
+                            canonicalizerPhase.applyIncremental(graph, phaseContext, canonicalizerUsages);
                         }
                     }
 
                     // Convert deopt to guards.
                     new ConvertDeoptimizeToGuardPhase().apply(graph);
 
-                    new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, context);
+                    new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, phaseContext);
 
                     if (!inliningProgress) {
                         break;
@@ -193,7 +189,7 @@
     }
 
     private void expandInvoke(MethodCallTargetNode methodCallTargetNode) {
-        StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
+        StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod());
         if (inlineGraph == null) {
             inlineGraph = TruffleCache.this.lookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), null, null);
         }
@@ -208,8 +204,8 @@
 
     private boolean tryCutOffRuntimeExceptions(MethodCallTargetNode methodCallTargetNode) {
         if (methodCallTargetNode.targetMethod().isConstructor()) {
-            ResolvedJavaType runtimeException = metaAccess.lookupJavaType(RuntimeException.class);
-            ResolvedJavaType controlFlowException = metaAccess.lookupJavaType(ControlFlowException.class);
+            ResolvedJavaType runtimeException = providers.getMetaAccess().lookupJavaType(RuntimeException.class);
+            ResolvedJavaType controlFlowException = providers.getMetaAccess().lookupJavaType(ControlFlowException.class);
             ResolvedJavaType exceptionType = Objects.requireNonNull(ObjectStamp.typeOrNull(methodCallTargetNode.receiver().stamp()));
             if (runtimeException.isAssignableFrom(methodCallTargetNode.targetMethod().getDeclaringClass()) && !controlFlowException.isAssignableFrom(exceptionType)) {
                 DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Oct 11 17:53:29 2013 +0200
@@ -43,6 +43,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.truffle.nodes.*;
 import com.oracle.truffle.api.*;
@@ -53,11 +54,9 @@
  */
 public class TruffleCompilerImpl implements TruffleCompiler {
 
-    private final MetaAccessProvider metaAccess;
-    private final GraalCodeCacheProvider codeCache;
+    private final Providers providers;
     private final Suites suites;
     private final PartialEvaluator partialEvaluator;
-    private final Replacements replacements;
     private final Backend backend;
     private final ResolvedJavaType[] skippedExceptionTypes;
     private final HotSpotGraalRuntime graalRuntime;
@@ -69,29 +68,29 @@
                     OptimisticOptimizations.Optimization.RemoveNeverExecutedCode, OptimisticOptimizations.Optimization.UseTypeCheckedInlining, OptimisticOptimizations.Optimization.UseTypeCheckHints);
 
     public TruffleCompilerImpl() {
-        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        this.codeCache = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+        this.providers = new Providers(Graal.getRequiredCapability(MetaAccessProvider.class), Graal.getRequiredCapability(CodeCacheProvider.class),
+                        Graal.getRequiredCapability(ConstantReflectionProvider.class), Graal.getRequiredCapability(LoweringProvider.class),
+                        ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements());
         this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
         this.backend = Graal.getRequiredCapability(Backend.class);
-        this.replacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
         this.graalRuntime = HotSpotGraalRuntime.graalRuntime();
-        this.skippedExceptionTypes = getSkippedExceptionTypes(metaAccess);
+        this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
 
         final GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault();
         config.setSkippedExceptionTypes(skippedExceptionTypes);
-        this.truffleCache = new TruffleCache(this.metaAccess, codeCache, config, TruffleCompilerImpl.Optimizations, this.replacements);
+        this.truffleCache = new TruffleCache(providers, config, TruffleCompilerImpl.Optimizations);
 
-        this.partialEvaluator = new PartialEvaluator(metaAccess, codeCache, replacements, truffleCache);
+        this.partialEvaluator = new PartialEvaluator(providers, truffleCache);
 
         if (Debug.isEnabled()) {
             DebugEnvironment.initialize(System.out);
         }
     }
 
-    static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccessProvider) {
+    static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccess) {
         ResolvedJavaType[] skippedExceptionTypes = new ResolvedJavaType[SKIPPED_EXCEPTION_CLASSES.length];
         for (int i = 0; i < SKIPPED_EXCEPTION_CLASSES.length; i++) {
-            skippedExceptionTypes[i] = metaAccessProvider.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]);
+            skippedExceptionTypes[i] = metaAccess.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]);
         }
         return skippedExceptionTypes;
     }
@@ -150,9 +149,10 @@
             @Override
             public CompilationResult call() {
                 try (TimerCloseable a = CompilationTime.start()) {
+                    CodeCacheProvider codeCache = providers.getCodeCache();
                     CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
-                    return GraalCompiler.compileGraph(graph, cc, graph.method(), metaAccess, codeCache, replacements, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL,
-                                    new SpeculationLog(), suites, new CompilationResult());
+                    return GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), suites,
+                                    new CompilationResult());
                 }
             }
         });
@@ -178,7 +178,7 @@
             @Override
             public InstalledCode call() throws Exception {
                 try (TimerCloseable a = CodeInstallationTime.start()) {
-                    InstalledCode installedCode = codeCache.addMethod(graph.method(), result);
+                    InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result);
                     if (installedCode != null) {
                         Debug.dump(new Object[]{result, installedCode}, "After code installation");
                     }
@@ -192,7 +192,7 @@
         }
 
         if (Debug.isLogEnabled()) {
-            Debug.log(codeCache.disassemble(result, compiledMethod));
+            Debug.log(providers.getCodeCache().disassemble(result, compiledMethod));
         }
         if (compilable != null) {
             compilable.codeSize = result.getTargetCodeSize();
@@ -202,7 +202,7 @@
 
     private PhasePlan createPhasePlan(final GraphBuilderConfiguration config) {
         final PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, config, TruffleCompilerImpl.Optimizations);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         return phasePlan;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Fri Oct 11 17:53:29 2013 +0200
@@ -41,17 +41,20 @@
 
     private final Replacements graalReplacements;
 
-    private TruffleReplacements(MetaAccessProvider metaAccess, GraalCodeCacheProvider codeCache, Assumptions assumptions, TargetDescription target, Replacements graalReplacements) {
-        super(metaAccess, codeCache, assumptions, target);
+    private TruffleReplacements(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, LoweringProvider lowerer, Assumptions assumptions,
+                    TargetDescription target, Replacements graalReplacements) {
+        super(metaAccess, constantReflection, codeCache, lowerer, assumptions, target);
         this.graalReplacements = graalReplacements;
     }
 
     static Replacements makeInstance() {
         MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        GraalCodeCacheProvider codeCache = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
+        ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
+        LoweringProvider lowerer = Graal.getRequiredCapability(LoweringProvider.class);
         TargetDescription targetDescription = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
         Replacements graalReplacements = Graal.getRequiredCapability(Replacements.class);
-        Replacements truffleReplacements = new TruffleReplacements(metaAccess, codeCache, graalReplacements.getAssumptions(), targetDescription, graalReplacements);
+        Replacements truffleReplacements = new TruffleReplacements(metaAccess, constantReflection, codeCache, lowerer, graalReplacements.getAssumptions(), targetDescription, graalReplacements);
 
         truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class);
         truffleReplacements.registerSubstitutions(CompilerDirectivesSubstitutions.class);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -58,7 +58,7 @@
             if (index >= 0 && index < Array.getLength(array)) {
                 int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass());
                 int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass());
-                Constant constant = tool.getMetaAccess().readUnsafeConstant(elementKind(), array, arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object);
+                Constant constant = tool.getConstantReflection().readUnsafeConstant(elementKind(), array().asConstant(), arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object);
                 return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
             }
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Fri Oct 11 17:52:33 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Fri Oct 11 17:53:29 2013 +0200
@@ -95,11 +95,11 @@
         }
     }
 
-    protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccessProvider) {
+    protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccess) {
         if (isConstantFrameSlot()) {
             return ConstantNode.forInt(getSlotIndex() * scale, graph());
         } else {
-            LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccessProvider.lookupJavaField(getFrameSlotIndexField())));
+            LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccess.lookupJavaField(getFrameSlotIndexField())));
             graph().addBeforeFixed(this, loadFrameSlotIndex);
             return scale == 1 ? loadFrameSlotIndex : IntegerArithmeticNode.mul(loadFrameSlotIndex, ConstantNode.forInt(scale, graph()));
         }
--- a/mx/commands.py	Fri Oct 11 17:52:33 2013 +0200
+++ b/mx/commands.py	Fri Oct 11 17:53:29 2013 +0200
@@ -951,12 +951,14 @@
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithGCVerification:product')
-        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
+        out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write
+        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithG1GCVerification:product')
-        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+UseNewCode', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
+        out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write
+        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+UseNewCode', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
--- a/mxtool/mx.py	Fri Oct 11 17:52:33 2013 +0200
+++ b/mxtool/mx.py	Fri Oct 11 17:53:29 2013 +0200
@@ -158,7 +158,7 @@
 _mainSuite = None
 _opts = None
 _java = None
-_check_global_structures = True # can be set False to allow suites with duplicate definitions to load without aborting
+_check_global_structures = True  # can be set False to allow suites with duplicate definitions to load without aborting
 
 
 """
@@ -1277,6 +1277,36 @@
     return name
 
 """
+Utility for filtering duplicate lines.
+"""
+class DuplicateSuppressingStream:
+    """
+    Creates an object that will suppress duplicate lines sent to 'out'.
+    The lines considered for suppression are those that contain one of the
+    strings in 'restrictTo' if it is not None.
+    """
+    def __init__(self, restrictTo=None, out=sys.stdout):
+        self.restrictTo = restrictTo
+        self.seen = set()
+        self.out = out
+
+    def isSuppressionCandidate(self, line):
+        if self.restrictTo:
+            for p in self.restrictTo:
+                if p in line:
+                    return True
+            return False
+        else:
+            return True
+
+    def write(self, line):
+        if self.isSuppressionCandidate(line):
+            if line in self.seen:
+                return
+            self.seen.add(line)
+        self.out.write(line)
+
+"""
 A JavaCompliance simplifies comparing Java compliance values extracted from a JDK version string.
 """
 class JavaCompliance:
@@ -2518,7 +2548,7 @@
         return
 
     if buildProcessorJars:
-        ## todo suite specific
+        # todo suite specific
         processorjars()
 
     projToDist = dict()
@@ -2810,7 +2840,7 @@
     if exists(md):
         return wsdir
     split = os.path.split(wsdir)
-    if split[0] == wsdir: # root directory
+    if split[0] == wsdir:  # root directory
         return None
     else:
         return _find_eclipse_wsroot(split[0])