changeset 12454:ce4836e0212d

Merge.
author Christian Humer <christian.humer@gmail.com>
date Wed, 16 Oct 2013 18:27:28 +0200
parents 8970574702a4 (current diff) d60cdea43920 (diff)
children d08accd58925 935dcd8ad8eb ce82cdbffe47
files graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRuntime.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/InlinePrinterProcessor.java graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/method/CallStackElement.java graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/method/MethodHolder.java graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/method/TruffleMethodNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java
diffstat 189 files changed, 3911 insertions(+), 4069 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/BytecodeDisassemblerProvider.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/BytecodeDisassemblerProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.api.meta;
 
 /**
- * Interface providing capability for disassembling bytecode.
+ * Interface for disassembling bytecode.
  */
 public interface BytecodeDisassemblerProvider {
 
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -86,8 +86,8 @@
         }
     }
 
-    public AMD64LIRGenerator(StructuredGraph graph, Providers providers, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, providers, target, frameMap, cc, lir);
+    public AMD64LIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
         lir.spillMoveFactory = new AMD64SpillMoveFactory();
     }
 
@@ -96,7 +96,7 @@
         // there is no immediate move of 64-bit constants on Intel
         switch (c.getKind()) {
             case Long:
-                return Util.isInt(c.asLong()) && !codeCache.needsDataPatch(c);
+                return Util.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
             case Double:
                 return false;
             case Object:
@@ -110,7 +110,7 @@
     public boolean canInlineConstant(Constant c) {
         switch (c.getKind()) {
             case Long:
-                return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c);
+                return NumUtil.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
             case Object:
                 return c.isNull();
             default:
@@ -147,7 +147,7 @@
         if (isConstant(base)) {
             if (asConstant(base).isNull()) {
                 baseRegister = Value.ILLEGAL;
-            } else if (asConstant(base).getKind() != Kind.Object && !codeCache.needsDataPatch(asConstant(base))) {
+            } else if (asConstant(base).getKind() != Kind.Object && !getCodeCache().needsDataPatch(asConstant(base))) {
                 finalDisp += asConstant(base).asLong();
                 baseRegister = Value.ILLEGAL;
             } else {
@@ -761,8 +761,8 @@
 
     @Override
     public void emitMembar(int barriers) {
-        int necessaryBarriers = target.arch.requiredBarriers(barriers);
-        if (target.isMP && necessaryBarriers != 0) {
+        int necessaryBarriers = target().arch.requiredBarriers(barriers);
+        if (target().isMP && necessaryBarriers != 0) {
             append(new MembarOp(necessaryBarriers));
         }
     }
@@ -874,14 +874,14 @@
         // Making a copy of the switch value is necessary because jump table destroys the input
         // value
         Variable tmp = emitMove(key);
-        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
+        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target().wordKind)));
     }
 
     @Override
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(metaAccess);
+            sig[i] = node.arguments().get(i).stamp().javaType(getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments());
--- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java	Wed Oct 16 18:27:28 2013 +0200
@@ -27,9 +27,11 @@
  * This class extends KernelTester and provides a base class
  * for which the HSAIL code comes from the Graal compiler.
  */
-import com.oracle.graal.compiler.hsail.HSAILCompilationResult;
+import com.oracle.graal.hotspot.hsail.*;
+
 import java.lang.reflect.Method;
 import java.io.*;
+
 import static com.oracle.graal.phases.GraalOptions.*;
 
 public abstract class GraalKernelTester extends KernelTester {
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -25,7 +25,7 @@
 import org.junit.*;
 
 import com.oracle.graal.compiler.test.GraalCompilerTest;
-import com.oracle.graal.compiler.hsail.HSAILCompilationResult;
+import com.oracle.graal.hotspot.hsail.*;
 import com.oracle.graal.nodes.StructuredGraph;
 
 /**
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.graal.compiler.hsail;
-
-import java.lang.reflect.*;
-
-import com.amd.okra.*;
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.iterators.*;
-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
- * JDK interception code that offloads to the GPU.
- */
-public class ForEachToGraal implements CompileAndDispatch {
-
-    private static CompilationResult getCompiledLambda(Class consumerClass) {
-        /**
-         * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
-         * that accept will call.
-         */
-        Method[] icMethods = consumerClass.getMethods();
-        Method acceptMethod = null;
-        for (Method m : icMethods) {
-            if (m.getName().equals("accept") && acceptMethod == null) {
-                acceptMethod = m;
-            }
-        }
-        HotSpotVMConfig config = HotSpotGraalRuntime.graalRuntime().getConfig();
-        AMD64HotSpotRuntime runtime = new AMD64HotSpotRuntime(config, HotSpotGraalRuntime.graalRuntime());
-        ResolvedJavaMethod rm = runtime.lookupJavaMethod(acceptMethod);
-        StructuredGraph graph = new StructuredGraph(rm);
-        new GraphBuilderPhase(runtime, runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-        NodeIterable<Node> nin = graph.getNodes();
-        ResolvedJavaMethod lambdaMethod = null;
-        for (Node n : nin) {
-            if (n instanceof MethodCallTargetNode) {
-                lambdaMethod = ((MethodCallTargetNode) n).targetMethod();
-                Debug.log("target ... " + lambdaMethod);
-                break;
-            }
-        }
-        if (lambdaMethod == null) {
-            // Did not find call in Consumer.accept.
-            Debug.log("Should not Reach here, did not find call in accept()");
-            return null;
-        }
-        // Now that we have the target lambda, compile it.
-        HSAILCompilationResult hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(lambdaMethod);
-        if (hsailCompResult != null) {
-            hsailCompResult.dumpCompilationResult();
-        }
-        return hsailCompResult.getCompilationResult();
-    }
-
-    // Implementations of the CompileAndDispatch interface.
-    @Override
-    public Object createKernel(Class<?> consumerClass) {
-        try {
-            CompilationResult result = getCompiledLambda(consumerClass);
-            if (result != null) {
-                String code = new String(new String(result.getTargetCode(), 0, result.getTargetCodeSize()));
-                OkraContext okraContext = new OkraContext();
-                OkraKernel okraKernel = new OkraKernel(okraContext, code, "&run");
-                if (okraKernel.isValid()) {
-                    return okraKernel;
-                }
-            }
-        } catch (Throwable e) {
-            // Note: Graal throws Errors. We want to revert to regular Java in these cases.
-            Debug.log("WARNING:Graal compilation failed.");
-            e.printStackTrace();
-            return null;
-        }
-        // If we got this far, return null.
-        return null;
-    }
-
-    @Override
-    public boolean dispatchKernel(Object kernel, int jobSize, Object[] args) {
-        if (!(kernel instanceof OkraKernel)) {
-            Debug.log("unknown kernel for dispatchKernel");
-            return false;
-        }
-        OkraKernel okraKernel = (OkraKernel) kernel;
-        okraKernel.setLaunchAttributes(jobSize);
-        int status = okraKernel.dispatchWithArgs(args);
-        return (status == 0);
-    }
-}
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +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.compiler.hsail;
-
-import static com.oracle.graal.api.code.CallingConvention.Type.*;
-import static com.oracle.graal.api.code.ValueUtil.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.asm.hsail.*;
-import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.lir.hsail.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.util.*;
-import com.oracle.graal.hsail.*;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-
-/**
- * HSAIL specific backend.
- */
-public class HSAILBackend extends Backend {
-
-    private Map<String, String> paramTypeMap = new HashMap<>();
-    private Buffer codeBuffer;
-
-    public HSAILBackend(Providers providers, TargetDescription target) {
-        super(providers, target);
-        paramTypeMap.put("HotSpotResolvedPrimitiveType<int>", "s32");
-        paramTypeMap.put("HotSpotResolvedPrimitiveType<float>", "f32");
-        paramTypeMap.put("HotSpotResolvedPrimitiveType<double>", "f64");
-        paramTypeMap.put("HotSpotResolvedPrimitiveType<long>", "s64");
-    }
-
-    @Override
-    public boolean shouldAllocateRegisters() {
-        return true;
-    }
-
-    /**
-     * Use the HSAIL register set when the compilation target is HSAIL.
-     */
-    @Override
-    public FrameMap newFrameMap() {
-        return new HSAILFrameMap(getCodeCache(), target, new HSAILRegisterConfig());
-    }
-
-    @Override
-    public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new HSAILLIRGenerator(graph, getProviders(), target, frameMap, cc, lir);
-    }
-
-    public String getPartialCodeString() {
-        return (codeBuffer == null ? "" : new String(codeBuffer.copyData(0, codeBuffer.position())));
-    }
-
-    class HotSpotFrameContext implements FrameContext {
-
-        @Override
-        public void enter(TargetMethodAssembler tasm) {
-            Debug.log("Nothing to do here");
-        }
-
-        @Override
-        public void leave(TargetMethodAssembler tasm) {
-            Debug.log("Nothing to do here");
-        }
-    }
-
-    @Override
-    protected AbstractAssembler createAssembler(FrameMap frameMap) {
-        return new HSAILAssembler(target);
-    }
-
-    @Override
-    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
-        FrameMap frameMap = lirGen.frameMap;
-        AbstractAssembler masm = new HSAILAssembler(target);
-        HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
-        tasm.setFrameSize(frameMap.frameSize());
-        return tasm;
-    }
-
-    @Override
-    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod method) {
-        assert method != null : lirGen.getGraph() + " is not associated with a method";
-        // Emit the prologue.
-        codeBuffer = tasm.asm.codeBuffer;
-        codeBuffer.emitString0("version 0:95: $full : $large;");
-        codeBuffer.emitString("");
-        Signature signature = method.getSignature();
-        int sigParamCount = signature.getParameterCount(false);
-        // We're subtracting 1 because we're not making the final gid as a parameter.
-        int nonConstantParamCount = sigParamCount - 1;
-        boolean isStatic = (Modifier.isStatic(method.getModifiers()));
-        // Determine if this is an object lambda.
-        boolean isObjectLambda = true;
-        if (signature.getParameterType(nonConstantParamCount, null).getKind() == Kind.Int) {
-            isObjectLambda = false;
-        } else {
-            // Add space for gid int reg.
-            nonConstantParamCount++;
-        }
-
-        // If this is an instance method, include mappings for the "this" parameter
-        // as the first parameter.
-        if (!isStatic) {
-            nonConstantParamCount++;
-        }
-        // Add in any "constant" parameters (currently none).
-        int totalParamCount = nonConstantParamCount;
-        JavaType[] paramtypes = new JavaType[totalParamCount];
-        String[] paramNames = new String[totalParamCount];
-        int pidx = 0;
-        for (int i = 0; i < totalParamCount; i++) {
-            MetaAccessProvider metaAccess = getProviders().getMetaAccess();
-            if (i == 0 && !isStatic) {
-                paramtypes[i] = metaAccess.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);
-                    paramNames[i] = "%_gid";
-                } else {
-                    paramtypes[i] = signature.getParameterType(pidx++, null);
-                    paramNames[i] = "%_arg" + i;
-                }
-            }
-        }
-        codeBuffer.emitString0("// " + (isStatic ? "static" : "instance") + " method " + method);
-        codeBuffer.emitString("");
-        codeBuffer.emitString0("kernel &run (");
-        codeBuffer.emitString("");
-        FrameMap frameMap = tasm.frameMap;
-        RegisterConfig regConfig = frameMap.registerConfig;
-        // Build list of param types which does include the gid (for cc register mapping query).
-        JavaType[] ccParamTypes = new JavaType[nonConstantParamCount + 1];
-        // Include the gid.
-        System.arraycopy(paramtypes, 0, ccParamTypes, 0, nonConstantParamCount);
-        // Last entry comes from the signature.
-        ccParamTypes[ccParamTypes.length - 1] = signature.getParameterType(sigParamCount - 1, null);
-        CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, ccParamTypes, target, false);
-        /**
-         * Compute the hsail size mappings up to but not including the last non-constant parameter
-         * (which is the gid).
-         * 
-         */
-        String[] paramHsailSizes = new String[totalParamCount];
-        for (int i = 0; i < totalParamCount; i++) {
-            String paramtypeStr = paramtypes[i].toString();
-            String sizeStr = paramTypeMap.get(paramtypeStr);
-            // Catch all for any unmapped paramtype that is u64 (address of an object).
-            paramHsailSizes[i] = (sizeStr != null ? sizeStr : "u64");
-        }
-        // Emit the kernel function parameters.
-        for (int i = 0; i < totalParamCount; i++) {
-            String str = "kernarg_" + paramHsailSizes[i] + " " + paramNames[i];
-            if (i != totalParamCount - 1) {
-                str += ",";
-            }
-            codeBuffer.emitString(str);
-        }
-        codeBuffer.emitString(") {");
-
-        /*
-         * End of parameters start of prolog code. Emit the load instructions for loading of the
-         * kernel non-constant parameters into registers. The constant class parameters will not be
-         * loaded up front but will be loaded as needed.
-         */
-        for (int i = 0; i < nonConstantParamCount; i++) {
-            codeBuffer.emitString("ld_kernarg_" + paramHsailSizes[i] + "  " + HSAIL.mapRegister(cc.getArgument(i)) + ", [" + paramNames[i] + "];");
-        }
-
-        /*
-         * Emit the workitemaid instruction for loading the hidden gid parameter. This is assigned
-         * the register as if it were the last of the nonConstant parameters.
-         */
-        String workItemReg = "$s" + Integer.toString(asRegister(cc.getArgument(nonConstantParamCount)).encoding());
-        codeBuffer.emitString("workitemabsid_u32 " + workItemReg + ", 0;");
-
-        /*
-         * Note the logic used for this spillseg size is to leave space and then go back and patch
-         * in the correct size once we have generated all the instructions. This should probably be
-         * done in a more robust way by implementing something like codeBuffer.insertString.
-         */
-        int spillsegDeclarationPosition = codeBuffer.position() + 1;
-        String spillsegTemplate = "align 4 spill_u8 %spillseg[123456];";
-        codeBuffer.emitString(spillsegTemplate);
-        // Emit object array load prologue here.
-        if (isObjectLambda) {
-            final int arrayElementsOffset = 24;
-            String iterationObjArgReg = HSAIL.mapRegister(cc.getArgument(nonConstantParamCount - 1));
-            String tmpReg = workItemReg.replace("s", "d"); // "$d1";
-            // Convert gid to long.
-            codeBuffer.emitString("cvt_u64_s32 " + tmpReg + ", " + workItemReg + "; // Convert gid to long");
-            // Adjust index for sizeof ref.
-            codeBuffer.emitString("mul_u64 " + tmpReg + ", " + tmpReg + ", " + 8 + "; // Adjust index for sizeof ref");
-            // Adjust for actual data start.
-            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + arrayElementsOffset + "; // Adjust for actual elements data start");
-            // Add to array ref ptr.
-            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + iterationObjArgReg + "; // Add to array ref ptr");
-            // Load the object into the parameter reg.
-            codeBuffer.emitString("ld_global_u64 " + iterationObjArgReg + ", " + "[" + tmpReg + "]" + "; // Load from array element into parameter reg");
-        }
-        // Prologue done, Emit code for the LIR.
-        lirGen.lir.emitCode(tasm);
-        // Now that code is emitted go back and figure out what the upper Bound stack size was.
-        long maxStackSize = ((HSAILAssembler) tasm.asm).upperBoundStackSize();
-        String spillsegStringFinal;
-        if (maxStackSize == 0) {
-            // If no spilling, get rid of spillseg declaration.
-            char[] array = new char[spillsegTemplate.length()];
-            Arrays.fill(array, ' ');
-            spillsegStringFinal = new String(array);
-        } else {
-            spillsegStringFinal = spillsegTemplate.replace("123456", String.format("%6d", maxStackSize));
-        }
-        codeBuffer.emitString(spillsegStringFinal, spillsegDeclarationPosition);
-        // Emit the epilogue.
-        codeBuffer.emitString0("};");
-        codeBuffer.emitString("");
-    }
-}
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.graal.compiler.hsail;
-
-import java.lang.reflect.*;
-import java.util.logging.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CallingConvention.Type;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hsail.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-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.
- */
-public class HSAILCompilationResult {
-
-    private CompilationResult compResult;
-    private static final String propPkgName = HSAILCompilationResult.class.getPackage().getName();
-    private static Level logLevel;
-    private static ConsoleHandler consoleHandler;
-    public static Logger logger;
-    static {
-        logger = Logger.getLogger(propPkgName);
-        logLevel = Level.FINE;
-        // This block configures the logger with handler and formatter.
-        consoleHandler = new ConsoleHandler();
-        logger.addHandler(consoleHandler);
-        logger.setUseParentHandlers(false);
-        SimpleFormatter formatter = new SimpleFormatter() {
-
-            @SuppressWarnings("sync-override")
-            @Override
-            public String format(LogRecord record) {
-                return (record.getMessage() + "\n");
-            }
-        };
-        consoleHandler.setFormatter(formatter);
-        logger.setLevel(logLevel);
-        consoleHandler.setLevel(logLevel);
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(Method meth) {
-        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(meth);
-        return getHSAILCompilationResult(javaMethod);
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(ResolvedJavaMethod javaMethod) {
-        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        ForeignCallsProvider foreignCalls = Graal.getRequiredCapability(ForeignCallsProvider.class);
-        StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-        return getHSAILCompilationResult(graph);
-    }
-
-    /**
-     * HSAIL doesn't have a calling convention as such. Function arguments are actually passed in
-     * memory but then loaded into registers in the function body. This routine makes sure that
-     * arguments to a kernel or function are loaded (by the kernel or function body) into registers
-     * of the appropriate sizes. For example, int and float parameters should appear in S registers,
-     * whereas double and long parameters should appear in d registers.
-     */
-    public static CallingConvention getHSAILCallingConvention(CallingConvention.Type type, TargetDescription target, ResolvedJavaMethod method, boolean stackOnly) {
-        Signature sig = method.getSignature();
-        JavaType retType = sig.getReturnType(null);
-        int sigCount = sig.getParameterCount(false);
-        JavaType[] argTypes;
-        int argIndex = 0;
-        if (!Modifier.isStatic(method.getModifiers())) {
-            argTypes = new JavaType[sigCount + 1];
-            argTypes[argIndex++] = method.getDeclaringClass();
-        } else {
-            argTypes = new JavaType[sigCount];
-        }
-        for (int i = 0; i < sigCount; i++) {
-            argTypes[argIndex++] = sig.getParameterType(i, null);
-        }
-
-        RegisterConfig registerConfig = new HSAILRegisterConfig();
-        return registerConfig.getCallingConvention(type, retType, argTypes, target, stackOnly);
-    }
-
-    public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
-        Debug.dump(graph, "Graph");
-        Providers providers = GraalCompiler.getGraalProviders();
-        TargetDescription target = new TargetDescription(new HSAIL(), true, 8, 0, true);
-        HSAILBackend hsailBackend = new HSAILBackend(providers, target);
-        PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), 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);
-        SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class);
-        try {
-            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();
-            if (partialCode != null && !partialCode.equals("")) {
-                logger.fine("-------------------\nPartial Code Generation:\n--------------------");
-                logger.fine(partialCode);
-                logger.fine("-------------------\nEnd of Partial Code Generation\n--------------------");
-            }
-            throw e;
-        }
-    }
-
-    private static class HSAILPhase extends Phase {
-
-        @Override
-        protected void run(StructuredGraph graph) {
-            for (LocalNode local : graph.getNodes(LocalNode.class)) {
-                if (local.stamp() instanceof ObjectStamp) {
-                    local.setStamp(StampFactory.declaredNonNull(((ObjectStamp) local.stamp()).type()));
-                }
-            }
-        }
-    }
-
-    protected HSAILCompilationResult(CompilationResult compResultInput) {
-        compResult = compResultInput;
-    }
-
-    public CompilationResult getCompilationResult() {
-        return compResult;
-    }
-
-    public String getHSAILCode() {
-        return new String(compResult.getTargetCode(), 0, compResult.getTargetCodeSize());
-    }
-
-    public void dumpCompilationResult() {
-        logger.fine("targetCodeSize=" + compResult.getTargetCodeSize());
-        logger.fine(getHSAILCode());
-    }
-
-}
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -34,7 +34,6 @@
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.hsail.*;
@@ -50,12 +49,8 @@
 import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoArgOp;
 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp;
 import com.oracle.graal.lir.hsail.HSAILMove.LeaOp;
-import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer;
-import com.oracle.graal.lir.hsail.HSAILMove.LoadOp;
 import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp;
 import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp;
-import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer;
-import com.oracle.graal.lir.hsail.HSAILMove.StoreOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
@@ -64,11 +59,7 @@
 /**
  * This class implements the HSAIL specific portion of the LIR generator.
  */
-public class HSAILLIRGenerator extends LIRGenerator {
-
-    private HotSpotRuntime runtime() {
-        return (HotSpotRuntime) codeCache;
-    }
+public abstract class HSAILLIRGenerator extends LIRGenerator {
 
     public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory {
 
@@ -84,8 +75,8 @@
         }
     }
 
-    public HSAILLIRGenerator(StructuredGraph graph, Providers providers, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, providers, target, frameMap, cc, lir);
+    public HSAILLIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
         lir.spillMoveFactory = new HSAILSpillMoveFactory();
     }
 
@@ -99,7 +90,7 @@
     public boolean canInlineConstant(Constant c) {
         switch (c.getKind()) {
             case Long:
-                return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c);
+                return NumUtil.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
             case Object:
                 return c.isNull();
             default:
@@ -171,38 +162,6 @@
         return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp);
     }
 
-    private static boolean isCompressCandidate(DeoptimizingNode access) {
-        return access != null && ((HeapAccess) access).isCompressible();
-    }
-
-    @Override
-    public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) {
-        HSAILAddressValue loadAddress = asAddressValue(address);
-        Variable result = newVariable(kind);
-        LIRFrameState state = access != null ? state(access) : null;
-        assert access == null || access instanceof HeapAccess;
-        if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
-            Variable scratch = newVariable(Kind.Long);
-            append(new LoadCompressedPointer(kind, result, scratch, loadAddress, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment));
-        } else {
-            append(new LoadOp(kind, result, loadAddress, state));
-        }
-        return result;
-    }
-
-    @Override
-    public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) {
-        HSAILAddressValue storeAddress = asAddressValue(address);
-        LIRFrameState state = access != null ? state(access) : null;
-        Variable input = load(inputVal);
-        if (runtime().config.useCompressedOops && isCompressCandidate(access)) {
-            Variable scratch = newVariable(Kind.Long);
-            append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment));
-        } else {
-            append(new StoreOp(kind, storeAddress, input, state));
-        }
-    }
-
     @Override
     public Variable emitAddress(StackSlot address) {
         throw new InternalError("NYI");
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Wed Oct 16 18:27:28 2013 +0200
@@ -55,12 +55,12 @@
     }
 
     protected CompilationResult compile(String test) {
-        if (getCodeCache() instanceof PTXHotSpotRuntime) {
+        if (getCodeCache() instanceof PTXHotSpotCodeCacheProvider) {
             StructuredGraph graph = parse(test);
             sg = graph;
             Debug.dump(graph, "Graph");
             TargetDescription target = new TargetDescription(new PTX(), true, 1, 0, true);
-            PTXBackend ptxBackend = new PTXBackend(getProviders(), target);
+            PTXBackend ptxBackend = new PTXBackend(getProviders());
             PhasePlan phasePlan = new PhasePlan();
             GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
@@ -102,8 +102,8 @@
             HotSpotResolvedJavaMethod compiledMethod = (HotSpotResolvedJavaMethod) sg.method();
             boolean isStatic = Modifier.isStatic(compiledMethod.getModifiers());
             Object[] executeArgs = argsWithReceiver((isStatic ? null : this), args);
-            HotSpotRuntime hsr = (HotSpotRuntime) getCodeCache();
-            InstalledCode installedCode = hsr.addExternalMethod(compiledMethod, result);
+            HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) getCodeCache();
+            InstalledCode installedCode = codeCache.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	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java	Wed Oct 16 18:27:28 2013 +0200
@@ -32,25 +32,25 @@
 import com.oracle.graal.asm.ptx.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.lir.ptx.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.cfg.Block;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.lir.LIRInstruction.OperandFlag;
 import com.oracle.graal.lir.LIRInstruction.OperandMode;
 import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
 import com.oracle.graal.lir.StandardOp.LabelOp;
-import com.oracle.graal.graph.GraalInternalError;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.ptx.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * PTX specific backend.
  */
 public class PTXBackend extends Backend {
 
-    public PTXBackend(Providers providers, TargetDescription target) {
-        super(providers, target);
+    public PTXBackend(Providers providers) {
+        super(providers);
     }
 
     @Override
@@ -60,15 +60,15 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new PTXFrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig());
+        return new PTXFrameMap(getCodeCache());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new PTXLIRGenerator(graph, getProviders(), target, frameMap, cc, lir);
+        return new PTXLIRGenerator(graph, getProviders(), frameMap, cc, lir);
     }
 
-    class HotSpotFrameContext implements FrameContext {
+    class PTXFrameContext implements FrameContext {
 
         @Override
         public void enter(TargetMethodAssembler tasm) {
@@ -82,7 +82,7 @@
 
     @Override
     protected AbstractAssembler createAssembler(FrameMap frameMap) {
-        return new PTXAssembler(target, frameMap.registerConfig);
+        return new PTXAssembler(getTarget(), frameMap.registerConfig);
     }
 
     @Override
@@ -94,8 +94,8 @@
         // - has no instructions with debug info
         FrameMap frameMap = lirGen.frameMap;
         AbstractAssembler masm = createAssembler(frameMap);
-        HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        TargetMethodAssembler tasm = new PTXTargetMethodAssembler(target, getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        PTXFrameContext frameContext = new PTXFrameContext();
+        TargetMethodAssembler tasm = new PTXTargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(0);
         return tasm;
     }
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -29,11 +29,13 @@
 import static com.oracle.graal.lir.ptx.PTXBitManipulationOp.IntrinsicOpcode.*;
 import static com.oracle.graal.lir.ptx.PTXCompare.*;
 
+import java.lang.annotation.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.gen.*;
-import com.oracle.graal.debug.Debug;
+import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
@@ -48,25 +50,23 @@
 import com.oracle.graal.lir.ptx.PTXControlFlow.BranchOp;
 import com.oracle.graal.lir.ptx.PTXControlFlow.CondMoveOp;
 import com.oracle.graal.lir.ptx.PTXControlFlow.FloatCondMoveOp;
+import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnNoValOp;
 import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp;
-import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnNoValOp;
 import com.oracle.graal.lir.ptx.PTXControlFlow.SequentialSwitchOp;
 import com.oracle.graal.lir.ptx.PTXControlFlow.TableSwitchOp;
+import com.oracle.graal.lir.ptx.PTXMemOp.LoadOp;
+import com.oracle.graal.lir.ptx.PTXMemOp.LoadParamOp;
+import com.oracle.graal.lir.ptx.PTXMemOp.LoadReturnAddrOp;
+import com.oracle.graal.lir.ptx.PTXMemOp.StoreOp;
+import com.oracle.graal.lir.ptx.PTXMemOp.StoreReturnValOp;
 import com.oracle.graal.lir.ptx.PTXMove.MoveFromRegOp;
 import com.oracle.graal.lir.ptx.PTXMove.MoveToRegOp;
-import com.oracle.graal.lir.ptx.PTXMemOp.LoadOp;
-import com.oracle.graal.lir.ptx.PTXMemOp.StoreOp;
-import com.oracle.graal.lir.ptx.PTXMemOp.LoadParamOp;
-import com.oracle.graal.lir.ptx.PTXMemOp.LoadReturnAddrOp;
-import com.oracle.graal.lir.ptx.PTXMemOp.StoreReturnValOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.calc.ConvertNode.Op;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.util.*;
 
-import java.lang.annotation.*;
-
 /**
  * This class implements the PTX specific portion of the LIR generator.
  */
@@ -88,8 +88,8 @@
         }
     }
 
-    public PTXLIRGenerator(StructuredGraph graph, Providers providers, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, providers, target, frameMap, cc, lir);
+    public PTXLIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
         lir.spillMoveFactory = new PTXSpillMoveFactory();
         int callVariables = cc.getArgumentCount() + (cc.getReturn() == Value.ILLEGAL ? 0 : 1);
         lir.setFirstVariableNumber(callVariables);
@@ -110,7 +110,7 @@
     public boolean canInlineConstant(Constant c) {
         switch (c.getKind()) {
             case Long:
-                return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c);
+                return NumUtil.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
             case Object:
                 return c.isNull();
             default:
@@ -217,7 +217,7 @@
         if (isConstant(base)) {
             if (asConstant(base).isNull()) {
                 baseRegister = Value.ILLEGAL;
-            } else if (asConstant(base).getKind() != Kind.Object && !codeCache.needsDataPatch(asConstant(base))) {
+            } else if (asConstant(base).getKind() != Kind.Object && !getCodeCache().needsDataPatch(asConstant(base))) {
                 finalDisp += asConstant(base).asLong();
                 baseRegister = Value.ILLEGAL;
             } else {
@@ -861,7 +861,7 @@
         // Making a copy of the switch value is necessary because jump table destroys the input
         // value
         Variable tmp = emitMove(key);
-        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind), nextPredRegNum++));
+        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target().wordKind), nextPredRegNum++));
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java	Wed Oct 16 18:27:28 2013 +0200
@@ -33,7 +33,7 @@
 
 public class PTXTargetMethodAssembler extends TargetMethodAssembler {
 
-    private static CompilerToGPU toGPU = HotSpotGraalRuntime.graalRuntime().getCompilerToGPU();
+    private static CompilerToGPU toGPU = HotSpotGraalRuntime.runtime().getCompilerToGPU();
 
     private static boolean validDevice = toGPU.deviceInit();
 
@@ -45,9 +45,9 @@
 
     // detach ??
 
-    public PTXTargetMethodAssembler(TargetDescription target, CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
+    public PTXTargetMethodAssembler(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
                     CompilationResult compilationResult) {
-        super(target, codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
+        super(codeCache, foreignCalls, frameMap, asm, frameContext, compilationResult);
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -78,8 +78,8 @@
         }
     }
 
-    public SPARCLIRGenerator(StructuredGraph graph, Providers providers, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, providers, target, frameMap, cc, lir);
+    public SPARCLIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
         lir.spillMoveFactory = new SPARCSpillMoveFactory();
     }
 
@@ -99,9 +99,9 @@
     public boolean canInlineConstant(Constant c) {
         switch (c.getKind()) {
             case Int:
-                return SPARCAssembler.isSimm13(c.asInt()) && !codeCache.needsDataPatch(c);
+                return SPARCAssembler.isSimm13(c.asInt()) && !getCodeCache().needsDataPatch(c);
             case Long:
-                return SPARCAssembler.isSimm13(c.asLong()) && !codeCache.needsDataPatch(c);
+                return SPARCAssembler.isSimm13(c.asLong()) && !getCodeCache().needsDataPatch(c);
             case Object:
                 return c.isNull();
             default:
@@ -377,7 +377,7 @@
         // Making a copy of the switch value is necessary because jump table destroys the input
         // value
         Variable tmp = emitMove(key);
-        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind)));
+        append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target().wordKind)));
     }
 
     @Override
@@ -831,8 +831,8 @@
 
     @Override
     public void emitMembar(int barriers) {
-        int necessaryBarriers = target.arch.requiredBarriers(barriers);
-        if (target.isMP && necessaryBarriers != 0) {
+        int necessaryBarriers = target().arch.requiredBarriers(barriers);
+        if (target().isMP && necessaryBarriers != 0) {
             append(new MembarOp(necessaryBarriers));
         }
     }
@@ -851,7 +851,7 @@
     public void visitBreakpointNode(BreakpointNode node) {
         JavaType[] sig = new JavaType[node.arguments().size()];
         for (int i = 0; i < sig.length; i++) {
-            sig[i] = node.arguments().get(i).stamp().javaType(metaAccess);
+            sig[i] = node.arguments().get(i).stamp().javaType(getMetaAccess());
         }
 
         Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -119,7 +119,7 @@
 
             @Override
             public LIR call() {
-                return GraalCompiler.emitHIR(getProviders(), backend.target, graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites);
+                return GraalCompiler.emitHIR(getProviders(), backend.getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites);
             }
         });
 
@@ -128,7 +128,7 @@
             @Override
             public RegisterStats call() {
                 CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
-                GraalCompiler.emitLIR(backend, backend.target, lir, graph, cc);
+                GraalCompiler.emitLIR(backend, backend.getTarget(), lir, graph, cc);
                 return new RegisterStats(lir);
             }
         });
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -60,10 +60,7 @@
     public final LIR lir;
 
     protected final StructuredGraph graph;
-    protected final MetaAccessProvider metaAccess;
-    protected final CodeCacheProvider codeCache;
-    protected final ForeignCallsProvider foreignCalls;
-    protected final TargetDescription target;
+    private final Providers providers;
     protected final CallingConvention cc;
 
     protected final DebugInfoBuilder debugInfoBuilder;
@@ -87,18 +84,15 @@
      */
     public abstract boolean canStoreConstant(Constant c);
 
-    public LIRGenerator(StructuredGraph graph, Providers providers, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+    public LIRGenerator(StructuredGraph graph, Providers providers, FrameMap frameMap, CallingConvention cc, LIR lir) {
         this.graph = graph;
-        this.metaAccess = providers.getMetaAccess();
-        this.codeCache = providers.getCodeCache();
-        this.foreignCalls = providers.getForeignCalls();
-        this.target = target;
+        this.providers = providers;
         this.frameMap = frameMap;
         if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) {
             this.cc = cc;
         } else {
-            JavaType[] parameterTypes = new JavaType[]{metaAccess.lookupJavaType(long.class)};
-            CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, metaAccess.lookupJavaType(void.class), parameterTypes, target, false);
+            JavaType[] parameterTypes = new JavaType[]{getMetaAccess().lookupJavaType(long.class)};
+            CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, getMetaAccess().lookupJavaType(void.class), parameterTypes, target(), false);
             this.cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0));
         }
         this.nodeOperands = graph.createNodeMap();
@@ -113,22 +107,26 @@
 
     @Override
     public TargetDescription target() {
-        return target;
+        return getCodeCache().getTarget();
+    }
+
+    protected Providers getProviders() {
+        return providers;
     }
 
     @Override
     public MetaAccessProvider getMetaAccess() {
-        return metaAccess;
+        return providers.getMetaAccess();
     }
 
     @Override
     public CodeCacheProvider getCodeCache() {
-        return codeCache;
+        return providers.getCodeCache();
     }
 
     @Override
     public ForeignCallsProvider getForeignCalls() {
-        return foreignCalls;
+        return providers.getForeignCalls();
     }
 
     public StructuredGraph getGraph() {
@@ -565,7 +563,7 @@
     @Override
     public void emitInvoke(Invoke x) {
         LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
-        CallingConvention invokeCc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(metaAccess), callTarget.signature(), target(), false);
+        CallingConvention invokeCc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(getMetaAccess()), callTarget.signature(), target(), false);
         frameMap.callsMethod(invokeCc);
 
         Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,11 +37,9 @@
 public abstract class Backend {
 
     private final Providers providers;
-    public final TargetDescription target;
 
-    protected Backend(Providers providers, TargetDescription target) {
+    protected Backend(Providers providers) {
         this.providers = providers;
-        this.target = target;
     }
 
     public Providers getProviders() {
@@ -56,6 +54,10 @@
         return providers.getForeignCalls();
     }
 
+    public TargetDescription getTarget() {
+        return providers.getCodeCache().getTarget();
+    }
+
     public abstract FrameMap newFrameMap();
 
     public abstract LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir);
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Wed Oct 16 18:27:28 2013 +0200
@@ -220,6 +220,7 @@
             return result;
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException();
         }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Wed Oct 16 18:27:28 2013 +0200
@@ -58,8 +58,8 @@
 
     private static final Unsafe unsafe = Unsafe.getUnsafe();
 
-    public AMD64HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) {
-        super(runtime, target);
+    public AMD64HotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
+        super(runtime, providers);
     }
 
     @Override
@@ -69,12 +69,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new AMD64FrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig());
+        return new AMD64FrameMap(getCodeCache());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new AMD64HotSpotLIRGenerator(graph, getProviders(), target, frameMap, cc, lir);
+        return new AMD64HotSpotLIRGenerator(graph, getProviders(), getRuntime().getConfig(), frameMap, cc, lir);
     }
 
     /**
@@ -154,7 +154,7 @@
 
     @Override
     protected AbstractAssembler createAssembler(FrameMap frameMap) {
-        return new AMD64MacroAssembler(target, frameMap.registerConfig);
+        return new AMD64MacroAssembler(getTarget(), frameMap.registerConfig);
     }
 
     @Override
@@ -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, getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
         StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot;
         if (deoptimizationRescueSlot != null && stub == null) {
@@ -235,23 +235,23 @@
         AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
         FrameMap frameMap = tasm.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
-        HotSpotVMConfig config = getRuntime().config;
+        HotSpotVMConfig config = getRuntime().getConfig();
         Label verifiedStub = new Label();
 
         // Emit the prefix
+        HotSpotProviders providers = getProviders();
         if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) {
             tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
-            CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{getRuntime().lookupJavaType(Object.class)}, target, false);
+            CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{providers.getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false);
             Register inlineCacheKlass = rax; // see definition of IC_Klass in
                                              // c1_LIRAssembler_x86.cpp
             Register receiver = asRegister(cc.getArgument(0));
             AMD64Address src = new AMD64Address(receiver, config.hubOffset);
 
-            AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen;
-            AMD64HotSpotRuntime hr = ((AMD64HotSpotRuntime) gen.getCodeCache());
-            if (hr.useCompressedKlassPointers()) {
+            if (config.useCompressedClassPointers) {
                 Register register = r10;
-                AMD64HotSpotMove.decodeKlassPointer(asm, register, hr.heapBaseRegister(), src, config.narrowKlassBase, config.narrowOopBase, config.narrowKlassShift, config.logKlassAlignment);
+                AMD64HotSpotMove.decodeKlassPointer(asm, register, providers.getRegisters().getHeapBaseRegister(), src, config.narrowKlassBase, config.narrowOopBase, config.narrowKlassShift,
+                                config.logKlassAlignment);
                 asm.cmpq(inlineCacheKlass, register);
             } else {
                 asm.cmpq(inlineCacheKlass, src);
@@ -269,10 +269,11 @@
 
         HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
         if (frameContext != null && !frameContext.isStub) {
+            HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls();
             tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            AMD64Call.directCall(tasm, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
             tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
+            AMD64Call.directCall(tasm, asm, foreignCalls.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/AMD64HotSpotCRuntimeCallEpilogueOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,8 +37,8 @@
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         // reset last Java frame:
-        HotSpotVMConfig config = graalRuntime().getConfig();
-        Register thread = graalRuntime().getRuntime().threadRegister();
+        HotSpotVMConfig config = runtime().getConfig();
+        Register thread = runtime().getProviders().getRegisters().getThreadRegister();
 
         masm.movslq(new AMD64Address(thread, config.threadLastJavaSpOffset), 0);
         masm.movslq(new AMD64Address(thread, config.threadLastJavaFpOffset), 0);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -38,7 +38,7 @@
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
 
         // save last Java frame
-        Register thread = graalRuntime().getRuntime().threadRegister();
-        masm.movq(new AMD64Address(thread, graalRuntime().getConfig().threadLastJavaSpOffset), rsp);
+        Register thread = runtime().getProviders().getRegisters().getThreadRegister();
+        masm.movq(new AMD64Address(thread, runtime().getConfig().threadLastJavaSpOffset), rsp);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCodeCacheProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+
+public class AMD64HotSpotCodeCacheProvider extends HotSpotCodeCacheProvider {
+
+    public AMD64HotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) {
+        super(runtime);
+
+    }
+
+    @Override
+    protected RegisterConfig createRegisterConfig() {
+        return new AMD64HotSpotRegisterConfig(runtime.getTarget().arch, runtime.getConfig());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.amd64;
+
+import static com.oracle.graal.amd64.AMD64.*;
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.api.meta.Value.*;
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
+import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.*;
+import static com.oracle.graal.hotspot.replacements.CRC32Substitutions.*;
+import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+
+public class AMD64HotSpotForeignCallsProvider extends HotSpotForeignCallsProvider {
+
+    public AMD64HotSpotForeignCallsProvider(HotSpotGraalRuntime runtime) {
+        super(runtime);
+    }
+
+    @Override
+    public void initialize(HotSpotProviders providers) {
+        Kind word = runtime.getTarget().wordKind;
+        HotSpotVMConfig config = runtime.getConfig();
+
+        // The calling convention for the exception handler stub is (only?) defined in
+        // TemplateInterpreterGenerator::generate_throw_exception()
+        // in templateInterpreter_x86_64.cpp around line 1923
+        RegisterValue exception = rax.asValue(Kind.Object);
+        RegisterValue exceptionPc = rdx.asValue(word);
+        CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc);
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, null, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, null, NOT_REEXECUTABLE, ANY_LOCATION));
+
+        // These stubs do callee saving
+        registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        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);
+
+        super.initialize(providers);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Wed Oct 16 18:27:28 2013 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * AMD64 specific implementation of {@link HotSpotGraalRuntime}.
@@ -44,17 +45,17 @@
      * Called from C++ code to retrieve the singleton instance, creating it first if necessary.
      */
     public static HotSpotGraalRuntime makeInstance() {
-        HotSpotGraalRuntime graalRuntime = graalRuntime();
-        if (graalRuntime == null) {
+        HotSpotGraalRuntime runtime = runtime();
+        if (runtime == null) {
             HotSpotGraalRuntimeFactory factory = findFactory("AMD64");
             if (factory != null) {
-                graalRuntime = factory.createRuntime();
+                runtime = factory.createRuntime();
             } else {
-                graalRuntime = new AMD64HotSpotGraalRuntime();
+                runtime = new AMD64HotSpotGraalRuntime();
             }
-            graalRuntime.completeInitialization();
+            runtime.completeInitialization();
         }
-        return graalRuntime;
+        return runtime;
     }
 
     protected Architecture createArchitecture() {
@@ -62,6 +63,24 @@
     }
 
     @Override
+    protected HotSpotProviders createProviders() {
+        HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(this);
+        HotSpotCodeCacheProvider codeCache = new AMD64HotSpotCodeCacheProvider(this);
+        HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(this);
+        HotSpotForeignCallsProvider foreignCalls = new AMD64HotSpotForeignCallsProvider(this);
+        HotSpotLoweringProvider lowerer = new AMD64HotSpotLoweringProvider(this, metaAccess, foreignCalls);
+        // Replacements cannot have speculative optimizations since they have
+        // to be valid for the entire run of the VM.
+        Assumptions assumptions = new Assumptions(false);
+        Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
+        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, getConfig(), assumptions);
+        HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(this);
+        HotSpotSuitesProvider suites = new HotSpotSuitesProvider(this);
+        HotSpotRegisters registers = new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp);
+        return new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
+    }
+
+    @Override
     protected TargetDescription createTarget() {
         final int stackFrameAlignment = 16;
         final int implicitNullCheckLimit = 4096;
@@ -71,18 +90,13 @@
 
     @Override
     protected HotSpotBackend createBackend() {
-        return new AMD64HotSpotBackend(getRuntime(), getTarget());
-    }
-
-    @Override
-    protected HotSpotRuntime createRuntime() {
-        return new AMD64HotSpotRuntime(config, this);
+        return new AMD64HotSpotBackend(this, getProviders());
     }
 
     @Override
     protected Value[] getNativeABICallerSaveRegisters() {
         if (nativeABICallerSaveRegisters == null) {
-            List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().getRegisterConfig().getAllocatableRegisters()));
+            List<Register> callerSave = new ArrayList<>(Arrays.asList(getProviders().getCodeCache().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/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -59,8 +59,8 @@
         masm.incrementq(rsp, 8);
 
         // Restore rsp from rbp if the exception PC is a method handle call site.
-        Register thread = graalRuntime().getRuntime().threadRegister();
-        int isMethodHandleReturnOffset = graalRuntime().getConfig().threadIsMethodHandleReturnOffset;
+        Register thread = runtime().getProviders().getRegisters().getThreadRegister();
+        int isMethodHandleReturnOffset = runtime().getConfig().threadIsMethodHandleReturnOffset;
         AMD64Address dst = new AMD64Address(thread, isMethodHandleReturnOffset);
         masm.cmpl(dst, 0);
         masm.cmovq(ConditionFlag.NotEqual, rsp, rbp);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -60,19 +60,23 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.phases.util.*;
 
 /**
  * LIR generator specialized for AMD64 HotSpot.
  */
 public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator {
 
-    private HotSpotRuntime runtime() {
-        return (HotSpotRuntime) codeCache;
+    private final HotSpotVMConfig config;
+
+    protected AMD64HotSpotLIRGenerator(StructuredGraph graph, HotSpotProviders providers, HotSpotVMConfig config, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
+        assert config.basicLockSize == 8;
+        this.config = config;
     }
 
-    protected AMD64HotSpotLIRGenerator(StructuredGraph graph, Providers providers, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, providers, target, frameMap, cc, lir);
+    @Override
+    protected HotSpotProviders getProviders() {
+        return (HotSpotProviders) super.getProviders();
     }
 
     /**
@@ -137,7 +141,6 @@
     @SuppressWarnings("hiding")
     @Override
     protected DebugInfoBuilder createDebugInfoBuilder(NodeMap<Value> nodeOperands) {
-        assert runtime().config.basicLockSize == 8;
         HotSpotLockStack lockStack = new HotSpotLockStack(frameMap, Kind.Long);
         return new HotSpotDebugInfoBuilder(nodeOperands, lockStack);
     }
@@ -232,7 +235,7 @@
                     Register[] savedRegisters = frameMap.registerConfig.getAllocatableRegisters();
                     savedRegisterLocations = new StackSlot[savedRegisters.length];
                     for (int i = 0; i < savedRegisters.length; i++) {
-                        PlatformKind kind = target.arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory());
+                        PlatformKind kind = target().arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory());
                         assert kind != Kind.Illegal;
                         StackSlot spillSlot = frameMap.allocateSpillSlot(kind);
                         savedRegisterLocations[i] = spillSlot;
@@ -279,7 +282,7 @@
         Register[] zappedRegisters = frameMap.registerConfig.getAllocatableRegisters();
         Constant[] zapValues = new Constant[zappedRegisters.length];
         for (int i = 0; i < zappedRegisters.length; i++) {
-            PlatformKind kind = target.arch.getLargestStorableKind(zappedRegisters[i].getRegisterCategory());
+            PlatformKind kind = target().arch.getLargestStorableKind(zappedRegisters[i].getRegisterCategory());
             assert kind != Kind.Illegal;
             zapValues[i] = zapValueForKind(kind);
         }
@@ -290,7 +293,7 @@
     @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
-        append(new AMD64HotSpotSafepointOp(info, runtime().config, this));
+        append(new AMD64HotSpotSafepointOp(info, config, this));
     }
 
     @SuppressWarnings("hiding")
@@ -306,7 +309,7 @@
         AMD64AddressValue address;
         Value index = operand(x.offset());
         if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) {
-            assert !codeCache.needsDataPatch(asConstant(index));
+            assert !getCodeCache().needsDataPatch(asConstant(index));
             disp += (int) ValueUtil.asConstant(index).asLong();
             address = new AMD64AddressValue(kind, load(operand(x.object())), disp);
         } else {
@@ -365,12 +368,13 @@
     }
 
     private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) {
-        int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset;
-        RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind());
+        int pendingDeoptimizationOffset = runtime().getConfig().pendingDeoptimizationOffset;
+        Kind wordKind = getProviders().getCodeCache().getTarget().wordKind;
+        RegisterValue thread = getProviders().getRegisters().getThreadRegister().asValue(wordKind);
         AMD64AddressValue pendingDeoptAddress = new AMD64AddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset);
-        if (actionAndReason instanceof Constant && !codeCache.needsDataPatch((Constant) actionAndReason)) {
+        if (actionAndReason instanceof Constant && !getCodeCache().needsDataPatch((Constant) actionAndReason)) {
             Constant constantActionAndReason = (Constant) actionAndReason;
-            assert !codeCache.needsDataPatch(constantActionAndReason);
+            assert !getCodeCache().needsDataPatch(constantActionAndReason);
             append(new StoreConstantOp(constantActionAndReason.getKind(), pendingDeoptAddress, constantActionAndReason, null));
         } else {
             append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, load(actionAndReason), null));
@@ -385,7 +389,7 @@
 
     @Override
     public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) {
-        moveDeoptimizationActionAndReasonToThread(metaAccess.encodeDeoptActionAndReason(action, reason));
+        moveDeoptimizationActionAndReasonToThread(getMetaAccess().encodeDeoptActionAndReason(action, reason));
         append(new AMD64HotSpotDeoptimizeCallerOp());
     }
 
@@ -444,12 +448,12 @@
          * algorithms may differ.
          */
         if (isCompressCandidate(access)) {
-            if (runtime().useCompressedOops() && kind == Kind.Object) {
-                append(new LoadCompressedPointer(kind, result, runtime().heapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, getNarrowKlassBase(), getNarrowOopBase(),
-                                getNarrowOopShift(), getLogMinObjectAlignment()));
-            } else if (runtime().useCompressedKlassPointers() && kind == Kind.Long) {
-                append(new LoadCompressedPointer(kind, result, runtime().heapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, getNarrowKlassBase(), getNarrowOopBase(),
-                                getNarrowKlassShift(), getLogKlassAlignment()));
+            if (config.useCompressedOops && kind == Kind.Object) {
+                append(new LoadCompressedPointer(kind, result, getProviders().getRegisters().getHeapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, getNarrowKlassBase(),
+                                getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment()));
+            } else if (config.useCompressedClassPointers && kind == Kind.Long) {
+                append(new LoadCompressedPointer(kind, result, getProviders().getRegisters().getHeapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, getNarrowKlassBase(),
+                                getNarrowOopBase(), getNarrowKlassShift(), getLogKlassAlignment()));
             } else {
                 append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null));
             }
@@ -466,9 +470,9 @@
         if (isConstant(inputVal)) {
             Constant c = asConstant(inputVal);
             if (canStoreConstant(c)) {
-                if (inputVal.getKind() == Kind.Object && runtime().useCompressedOops() && isCompressCandidate(access)) {
+                if (inputVal.getKind() == Kind.Object && config.useCompressedOops && isCompressCandidate(access)) {
                     append(new StoreCompressedConstantOp(kind, storeAddress, c, state));
-                } else if (inputVal.getKind() == Kind.Long && runtime().useCompressedKlassPointers() && isCompressCandidate(access)) {
+                } else if (inputVal.getKind() == Kind.Long && config.useCompressedClassPointers && isCompressCandidate(access)) {
                     append(new StoreCompressedConstantOp(kind, storeAddress, c, state));
                 } else {
                     append(new StoreConstantOp(kind, storeAddress, c, state));
@@ -478,17 +482,19 @@
         }
         Variable input = load(inputVal);
         if (isCompressCandidate(access)) {
-            if (runtime().useCompressedOops() && kind == Kind.Object) {
+            if (config.useCompressedOops && kind == Kind.Object) {
                 if (input.getKind() == Kind.Object) {
                     Variable scratch = newVariable(Kind.Long);
-                    append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, getNarrowKlassBase(), getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment()));
+                    Register heapBaseReg = getProviders().getRegisters().getHeapBaseRegister();
+                    append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, getNarrowKlassBase(), getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment(), heapBaseReg));
                 } else {
                     // the input oop is already compressed
                     append(new StoreOp(input.getKind(), storeAddress, input, state));
                 }
-            } else if (runtime().useCompressedKlassPointers() && kind == Kind.Long) {
+            } else if (config.useCompressedClassPointers && kind == Kind.Long) {
                 Variable scratch = newVariable(Kind.Long);
-                append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, getNarrowKlassBase(), getNarrowOopBase(), getNarrowKlassShift(), getLogKlassAlignment()));
+                Register heapBaseReg = getProviders().getRegisters().getHeapBaseRegister();
+                append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, getNarrowKlassBase(), getNarrowOopBase(), getNarrowKlassShift(), getLogKlassAlignment(), heapBaseReg));
             } else {
                 append(new StoreOp(kind, storeAddress, input, state));
             }
@@ -498,27 +504,27 @@
     }
 
     private int getLogMinObjectAlignment() {
-        return runtime().config.logMinObjAlignment;
+        return config.logMinObjAlignment;
     }
 
     private int getNarrowOopShift() {
-        return runtime().config.narrowOopShift;
+        return config.narrowOopShift;
     }
 
     private long getNarrowOopBase() {
-        return runtime().config.narrowOopBase;
+        return config.narrowOopBase;
     }
 
     private int getLogKlassAlignment() {
-        return runtime().config.logKlassAlignment;
+        return config.logKlassAlignment;
     }
 
     private int getNarrowKlassShift() {
-        return runtime().config.narrowKlassShift;
+        return config.narrowKlassShift;
     }
 
     private long getNarrowKlassBase() {
-        return runtime().config.narrowKlassBase;
+        return config.narrowKlassBase;
     }
 
     @Override
@@ -530,9 +536,10 @@
         AMD64AddressValue addressValue = asAddressValue(address);
         RegisterValue raxRes = AMD64.rax.asValue(kind);
         emitMove(raxRes, expected);
-        if (runtime().useCompressedOops() && node.isCompressible()) {
+        if (config.useCompressedOops && node.isCompressible()) {
             Variable scratch = newVariable(Kind.Long);
-            append(new CompareAndSwapCompressedOp(raxRes, addressValue, raxRes, newValue, scratch, getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment()));
+            Register heapBaseReg = getProviders().getRegisters().getHeapBaseRegister();
+            append(new CompareAndSwapCompressedOp(raxRes, addressValue, raxRes, newValue, scratch, getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment(), heapBaseReg));
         } else {
             append(new CompareAndSwapOp(raxRes, addressValue, raxRes, newValue));
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.amd64;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.replacements.amd64.*;
+
+public class AMD64HotSpotLoweringProvider extends HotSpotLoweringProvider {
+
+    private AMD64ConvertSnippets.Templates convertSnippets;
+
+    public AMD64HotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
+        super(runtime, metaAccess, foreignCalls);
+    }
+
+    @Override
+    public void initialize() {
+        HotSpotProviders providers = runtime.getProviders();
+        convertSnippets = new AMD64ConvertSnippets.Templates(providers, runtime.getTarget());
+        super.initialize();
+    }
+
+    @Override
+    public void lower(Node n, LoweringTool tool) {
+        if (n instanceof ConvertNode) {
+            convertSnippets.lower((ConvertNode) n, tool);
+        } else {
+            super.lower(n, tool);
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Wed Oct 16 18:27:28 2013 +0200
@@ -32,7 +32,6 @@
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
@@ -103,6 +102,7 @@
         protected final Kind kind;
         private final long klassBase;
         private final long heapBase;
+        private final Register heapBaseReg;
         private final int shift;
         private final int alignment;
         @Temp({REG}) private AllocatableValue scratch;
@@ -111,9 +111,10 @@
         @State protected LIRFrameState state;
 
         public StoreCompressedPointer(Kind kind, AMD64AddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, long klassBase, long heapBase, int shift,
-                        int alignment) {
+                        int alignment, Register heapBaseReg) {
             this.klassBase = klassBase;
             this.heapBase = heapBase;
+            this.heapBaseReg = heapBaseReg;
             this.shift = shift;
             this.alignment = alignment;
             this.scratch = scratch;
@@ -126,7 +127,6 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            Register heapBaseReg = ((HotSpotRuntime) tasm.codeCache).heapBaseRegister();
             masm.movq(asRegister(scratch), asRegister(input));
             if (kind == Kind.Object) {
                 encodePointer(masm, asRegister(scratch), heapBaseReg, heapBase, shift, alignment);
@@ -152,10 +152,12 @@
         private long base;
         private int shift;
         private int alignment;
+        private final Register heapBaseReg;
 
         public CompareAndSwapCompressedOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratch, long base, int shift,
-                        int alignment) {
+                        int alignment, Register heapBaseReg) {
             this.base = base;
+            this.heapBaseReg = heapBaseReg;
             this.shift = shift;
             this.alignment = alignment;
             this.scratch = scratch;
@@ -168,17 +170,17 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            compareAndSwapCompressed(tasm, masm, result, address, cmpValue, newValue, scratch, base, shift, alignment);
+            compareAndSwapCompressed(tasm, masm, result, address, cmpValue, newValue, scratch, base, shift, alignment, heapBaseReg);
         }
     }
 
     protected static void compareAndSwapCompressed(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue,
-                    AllocatableValue newValue, AllocatableValue scratch, long base, int shift, int alignment) {
+                    AllocatableValue newValue, AllocatableValue scratch, long base, int shift, int alignment, Register heapBaseReg) {
         assert AMD64.rax.equals(asRegister(cmpValue)) && AMD64.rax.equals(asRegister(result));
         final Register scratchRegister = asRegister(scratch);
         final Register cmpRegister = asRegister(cmpValue);
         final Register newRegister = asRegister(newValue);
-        Register heapBase = ((HotSpotRuntime) tasm.codeCache).heapBaseRegister();
+        Register heapBase = heapBaseReg;
         encodePointer(masm, cmpRegister, heapBase, base, shift, alignment);
         masm.movq(scratchRegister, newRegister);
         encodePointer(masm, scratchRegister, heapBase, base, shift, alignment);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -50,7 +50,7 @@
     }
 
     private static Register findPollOnReturnScratchRegister() {
-        RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().getRegisterConfig();
+        RegisterConfig config = HotSpotGraalRuntime.runtime().getProviders().getCodeCache().getRegisterConfig();
         for (Register r : config.getAllocatableRegisters(Kind.Long)) {
             if (r != config.getReturnRegister(Kind.Long) && r != AMD64.rbp) {
                 return r;
@@ -65,7 +65,7 @@
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         leaveFrameAndRestoreRbp(tasm, masm);
         if (!isStub && (tasm.frameContext != null || !OptEliminateSafepoints.getValue())) {
-            AMD64HotSpotSafepointOp.emitCode(tasm, masm, graalRuntime().getConfig(), true, null, scratchForSafepointOnReturn);
+            AMD64HotSpotSafepointOp.emitCode(tasm, masm, runtime().getConfig(), true, null, scratchForSafepointOnReturn);
         }
         masm.ret(0);
     }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.amd64;
-
-import static com.oracle.graal.amd64.AMD64.*;
-import static com.oracle.graal.api.code.CallingConvention.Type.*;
-import static com.oracle.graal.api.meta.LocationIdentity.*;
-import static com.oracle.graal.api.meta.Value.*;
-import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
-import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.*;
-import static com.oracle.graal.hotspot.replacements.CRC32Substitutions.*;
-import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-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 {
-
-    public AMD64HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) {
-        super(config, graalRuntime);
-
-    }
-
-    private AMD64ConvertSnippets.Templates convertSnippets;
-
-    @Override
-    public void registerReplacements(Replacements replacements) {
-        Kind word = graalRuntime.getTarget().wordKind;
-
-        // The calling convention for the exception handler stub is (only?) defined in
-        // TemplateInterpreterGenerator::generate_throw_exception()
-        // in templateInterpreter_x86_64.cpp around line 1923
-        RegisterValue exception = rax.asValue(Kind.Object);
-        RegisterValue exceptionPc = rdx.asValue(word);
-        CallingConvention exceptionCc = new CallingConvention(0, ILLEGAL, exception, exceptionPc);
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, null, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, null, NOT_REEXECUTABLE, ANY_LOCATION));
-
-        // These stubs do callee saving
-        registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        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);
-
-        Providers providers = new Providers(this, this, this, this, this, replacements);
-        convertSnippets = new AMD64ConvertSnippets.Templates(providers, graalRuntime.getTarget());
-        super.registerReplacements(replacements);
-    }
-
-    @Override
-    public void lower(Node n, LoweringTool tool) {
-        if (n instanceof ConvertNode) {
-            convertSnippets.lower((ConvertNode) n, tool);
-        } else {
-            super.lower(n, tool);
-        }
-    }
-
-    @Override
-    public Register threadRegister() {
-        return r15;
-    }
-
-    @Override
-    public Register stackPointerRegister() {
-        return rsp;
-    }
-
-    @Override
-    public Register heapBaseRegister() {
-        return r12;
-    }
-
-    @Override
-    protected RegisterConfig createRegisterConfig() {
-        return new AMD64HotSpotRegisterConfig(graalRuntime.getTarget().arch, config);
-    }
-}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -56,7 +56,7 @@
         // instruction that loads the Klass from the inline cache.
         AMD64Move.move(tasm, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod);
         tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
-        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.graalRuntime().getConfig().nonOopBits));
+        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.runtime().getConfig().nonOopBits));
         super.emitCode(tasm, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -55,7 +55,7 @@
         // The mark for an invocation that uses an inline cache must be placed at the
         // instruction that loads the Klass from the inline cache.
         tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
-        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.graalRuntime().getConfig().nonOopBits));
+        AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Long), Constant.forLong(HotSpotGraalRuntime.runtime().getConfig().nonOopBits));
         super.emitCode(tasm, masm);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.hotspot.hsail;
+
+import java.lang.reflect.*;
+
+import com.amd.okra.*;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.hsail.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+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
+ * JDK interception code that offloads to the GPU.
+ */
+public class ForEachToGraal implements CompileAndDispatch {
+
+    private static CompilationResult getCompiledLambda(Class consumerClass) {
+        /**
+         * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
+         * that accept will call.
+         */
+        Method[] icMethods = consumerClass.getMethods();
+        Method acceptMethod = null;
+        for (Method m : icMethods) {
+            if (m.getName().equals("accept") && acceptMethod == null) {
+                acceptMethod = m;
+            }
+        }
+        HotSpotGraalRuntime runtime = HotSpotGraalRuntime.runtime();
+        HotSpotProviders providers = runtime.getProviders();
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(acceptMethod);
+        StructuredGraph graph = new StructuredGraph(method);
+        ForeignCallsProvider foreignCalls = providers.getForeignCalls();
+        new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        NodeIterable<Node> nin = graph.getNodes();
+        ResolvedJavaMethod lambdaMethod = null;
+        for (Node n : nin) {
+            if (n instanceof MethodCallTargetNode) {
+                lambdaMethod = ((MethodCallTargetNode) n).targetMethod();
+                Debug.log("target ... " + lambdaMethod);
+                break;
+            }
+        }
+        if (lambdaMethod == null) {
+            // Did not find call in Consumer.accept.
+            Debug.log("Should not Reach here, did not find call in accept()");
+            return null;
+        }
+        // Now that we have the target lambda, compile it.
+        HSAILCompilationResult hsailCompResult = HSAILCompilationResult.getHSAILCompilationResult(lambdaMethod);
+        if (hsailCompResult != null) {
+            hsailCompResult.dumpCompilationResult();
+        }
+        return hsailCompResult.getCompilationResult();
+    }
+
+    // Implementations of the CompileAndDispatch interface.
+    @Override
+    public Object createKernel(Class<?> consumerClass) {
+        try {
+            CompilationResult result = getCompiledLambda(consumerClass);
+            if (result != null) {
+                String code = new String(new String(result.getTargetCode(), 0, result.getTargetCodeSize()));
+                OkraContext okraContext = new OkraContext();
+                OkraKernel okraKernel = new OkraKernel(okraContext, code, "&run");
+                if (okraKernel.isValid()) {
+                    return okraKernel;
+                }
+            }
+        } catch (Throwable e) {
+            // Note: Graal throws Errors. We want to revert to regular Java in these cases.
+            Debug.log("WARNING:Graal compilation failed.");
+            e.printStackTrace();
+            return null;
+        }
+        // If we got this far, return null.
+        return null;
+    }
+
+    @Override
+    public boolean dispatchKernel(Object kernel, int jobSize, Object[] args) {
+        if (!(kernel instanceof OkraKernel)) {
+            Debug.log("unknown kernel for dispatchKernel");
+            return false;
+        }
+        OkraKernel okraKernel = (OkraKernel) kernel;
+        okraKernel.setLaunchAttributes(jobSize);
+        int status = okraKernel.dispatchWithArgs(args);
+        return (status == 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.hotspot.hsail;
+
+import java.lang.reflect.*;
+import java.util.logging.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+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.
+ */
+public class HSAILCompilationResult {
+
+    private CompilationResult compResult;
+    private static final String propPkgName = HSAILCompilationResult.class.getPackage().getName();
+    private static Level logLevel;
+    private static ConsoleHandler consoleHandler;
+    public static Logger logger;
+    static {
+        logger = Logger.getLogger(propPkgName);
+        logLevel = Level.FINE;
+        // This block configures the logger with handler and formatter.
+        consoleHandler = new ConsoleHandler();
+        logger.addHandler(consoleHandler);
+        logger.setUseParentHandlers(false);
+        SimpleFormatter formatter = new SimpleFormatter() {
+
+            @SuppressWarnings("sync-override")
+            @Override
+            public String format(LogRecord record) {
+                return (record.getMessage() + "\n");
+            }
+        };
+        consoleHandler.setFormatter(formatter);
+        logger.setLevel(logLevel);
+        consoleHandler.setLevel(logLevel);
+    }
+
+    private static final HotSpotGraalRuntime runtime = new HSAILHotSpotGraalRuntime();
+
+    public static HSAILCompilationResult getHSAILCompilationResult(Method meth) {
+        HotSpotMetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess();
+        ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(meth);
+        return getHSAILCompilationResult(javaMethod);
+    }
+
+    public static HSAILCompilationResult getHSAILCompilationResult(ResolvedJavaMethod javaMethod) {
+        HotSpotMetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess();
+        ForeignCallsProvider foreignCalls = runtime.getProviders().getForeignCalls();
+        StructuredGraph graph = new StructuredGraph(javaMethod);
+        new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        return getHSAILCompilationResult(graph);
+    }
+
+    /**
+     * HSAIL doesn't have a calling convention as such. Function arguments are actually passed in
+     * memory but then loaded into registers in the function body. This routine makes sure that
+     * arguments to a kernel or function are loaded (by the kernel or function body) into registers
+     * of the appropriate sizes. For example, int and float parameters should appear in S registers,
+     * whereas double and long parameters should appear in d registers.
+     */
+    public static CallingConvention getHSAILCallingConvention(CallingConvention.Type type, TargetDescription target, ResolvedJavaMethod method, boolean stackOnly) {
+        Signature sig = method.getSignature();
+        JavaType retType = sig.getReturnType(null);
+        int sigCount = sig.getParameterCount(false);
+        JavaType[] argTypes;
+        int argIndex = 0;
+        if (!Modifier.isStatic(method.getModifiers())) {
+            argTypes = new JavaType[sigCount + 1];
+            argTypes[argIndex++] = method.getDeclaringClass();
+        } else {
+            argTypes = new JavaType[sigCount];
+        }
+        for (int i = 0; i < sigCount; i++) {
+            argTypes[argIndex++] = sig.getParameterType(i, null);
+        }
+
+        RegisterConfig registerConfig = runtime.getProviders().getCodeCache().getRegisterConfig();
+        return registerConfig.getCallingConvention(type, retType, argTypes, target, stackOnly);
+    }
+
+    public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
+        Debug.dump(graph, "Graph");
+        Providers providers = runtime.getProviders();
+        TargetDescription target = providers.getCodeCache().getTarget();
+        HSAILHotSpotBackend hsailBackend = (HSAILHotSpotBackend) runtime.getBackend();
+        PhasePlan phasePlan = new PhasePlan();
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), 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);
+        SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class);
+        try {
+            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();
+            if (partialCode != null && !partialCode.equals("")) {
+                logger.fine("-------------------\nPartial Code Generation:\n--------------------");
+                logger.fine(partialCode);
+                logger.fine("-------------------\nEnd of Partial Code Generation\n--------------------");
+            }
+            throw e;
+        }
+    }
+
+    private static class HSAILPhase extends Phase {
+
+        @Override
+        protected void run(StructuredGraph graph) {
+            for (LocalNode local : graph.getNodes(LocalNode.class)) {
+                if (local.stamp() instanceof ObjectStamp) {
+                    local.setStamp(StampFactory.declaredNonNull(((ObjectStamp) local.stamp()).type()));
+                }
+            }
+        }
+    }
+
+    protected HSAILCompilationResult(CompilationResult compResultInput) {
+        compResult = compResultInput;
+    }
+
+    public CompilationResult getCompilationResult() {
+        return compResult;
+    }
+
+    public String getHSAILCode() {
+        return new String(compResult.getTargetCode(), 0, compResult.getTargetCodeSize());
+    }
+
+    public void dumpCompilationResult() {
+        logger.fine("targetCodeSize=" + compResult.getTargetCodeSize());
+        logger.fine(getHSAILCode());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.hsail;
+
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.code.ValueUtil.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.asm.hsail.*;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hsail.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.hsail.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * HSAIL specific backend.
+ */
+public class HSAILHotSpotBackend extends HotSpotBackend {
+
+    private Map<String, String> paramTypeMap = new HashMap<>();
+    private Buffer codeBuffer;
+
+    public HSAILHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
+        super(runtime, providers);
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<int>", "s32");
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<float>", "f32");
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<double>", "f64");
+        paramTypeMap.put("HotSpotResolvedPrimitiveType<long>", "s64");
+
+    }
+
+    @Override
+    public boolean shouldAllocateRegisters() {
+        return true;
+    }
+
+    /**
+     * Use the HSAIL register set when the compilation target is HSAIL.
+     */
+    @Override
+    public FrameMap newFrameMap() {
+        return new HSAILFrameMap(getCodeCache());
+    }
+
+    @Override
+    public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        return new HSAILHotSpotLIRGenerator(graph, getProviders(), getRuntime().getConfig(), frameMap, cc, lir);
+    }
+
+    public String getPartialCodeString() {
+        return (codeBuffer == null ? "" : new String(codeBuffer.copyData(0, codeBuffer.position())));
+    }
+
+    class HotSpotFrameContext implements FrameContext {
+
+        @Override
+        public void enter(TargetMethodAssembler tasm) {
+            Debug.log("Nothing to do here");
+        }
+
+        @Override
+        public void leave(TargetMethodAssembler tasm) {
+            Debug.log("Nothing to do here");
+        }
+    }
+
+    @Override
+    protected AbstractAssembler createAssembler(FrameMap frameMap) {
+        return new HSAILAssembler(getTarget());
+    }
+
+    @Override
+    public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) {
+        FrameMap frameMap = lirGen.frameMap;
+        AbstractAssembler masm = createAssembler(frameMap);
+        HotSpotFrameContext frameContext = new HotSpotFrameContext();
+        TargetMethodAssembler tasm = new TargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult);
+        tasm.setFrameSize(frameMap.frameSize());
+        return tasm;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod method) {
+        assert method != null : lirGen.getGraph() + " is not associated with a method";
+        // Emit the prologue.
+        codeBuffer = tasm.asm.codeBuffer;
+        codeBuffer.emitString0("version 0:95: $full : $large;");
+        codeBuffer.emitString("");
+        Signature signature = method.getSignature();
+        int sigParamCount = signature.getParameterCount(false);
+        // We're subtracting 1 because we're not making the final gid as a parameter.
+        int nonConstantParamCount = sigParamCount - 1;
+        boolean isStatic = (Modifier.isStatic(method.getModifiers()));
+        // Determine if this is an object lambda.
+        boolean isObjectLambda = true;
+        if (signature.getParameterType(nonConstantParamCount, null).getKind() == Kind.Int) {
+            isObjectLambda = false;
+        } else {
+            // Add space for gid int reg.
+            nonConstantParamCount++;
+        }
+
+        // If this is an instance method, include mappings for the "this" parameter
+        // as the first parameter.
+        if (!isStatic) {
+            nonConstantParamCount++;
+        }
+        // Add in any "constant" parameters (currently none).
+        int totalParamCount = nonConstantParamCount;
+        JavaType[] paramtypes = new JavaType[totalParamCount];
+        String[] paramNames = new String[totalParamCount];
+        int pidx = 0;
+        for (int i = 0; i < totalParamCount; i++) {
+            MetaAccessProvider metaAccess = getProviders().getMetaAccess();
+            if (i == 0 && !isStatic) {
+                paramtypes[i] = metaAccess.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);
+                    paramNames[i] = "%_gid";
+                } else {
+                    paramtypes[i] = signature.getParameterType(pidx++, null);
+                    paramNames[i] = "%_arg" + i;
+                }
+            }
+        }
+        codeBuffer.emitString0("// " + (isStatic ? "static" : "instance") + " method " + method);
+        codeBuffer.emitString("");
+        codeBuffer.emitString0("kernel &run (");
+        codeBuffer.emitString("");
+        FrameMap frameMap = tasm.frameMap;
+        RegisterConfig regConfig = frameMap.registerConfig;
+        // Build list of param types which does include the gid (for cc register mapping query).
+        JavaType[] ccParamTypes = new JavaType[nonConstantParamCount + 1];
+        // Include the gid.
+        System.arraycopy(paramtypes, 0, ccParamTypes, 0, nonConstantParamCount);
+        // Last entry comes from the signature.
+        ccParamTypes[ccParamTypes.length - 1] = signature.getParameterType(sigParamCount - 1, null);
+        CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, ccParamTypes, getTarget(), false);
+        /**
+         * Compute the hsail size mappings up to but not including the last non-constant parameter
+         * (which is the gid).
+         * 
+         */
+        String[] paramHsailSizes = new String[totalParamCount];
+        for (int i = 0; i < totalParamCount; i++) {
+            String paramtypeStr = paramtypes[i].toString();
+            String sizeStr = paramTypeMap.get(paramtypeStr);
+            // Catch all for any unmapped paramtype that is u64 (address of an object).
+            paramHsailSizes[i] = (sizeStr != null ? sizeStr : "u64");
+        }
+        // Emit the kernel function parameters.
+        for (int i = 0; i < totalParamCount; i++) {
+            String str = "kernarg_" + paramHsailSizes[i] + " " + paramNames[i];
+            if (i != totalParamCount - 1) {
+                str += ",";
+            }
+            codeBuffer.emitString(str);
+        }
+        codeBuffer.emitString(") {");
+
+        /*
+         * End of parameters start of prolog code. Emit the load instructions for loading of the
+         * kernel non-constant parameters into registers. The constant class parameters will not be
+         * loaded up front but will be loaded as needed.
+         */
+        for (int i = 0; i < nonConstantParamCount; i++) {
+            codeBuffer.emitString("ld_kernarg_" + paramHsailSizes[i] + "  " + HSAIL.mapRegister(cc.getArgument(i)) + ", [" + paramNames[i] + "];");
+        }
+
+        /*
+         * Emit the workitemaid instruction for loading the hidden gid parameter. This is assigned
+         * the register as if it were the last of the nonConstant parameters.
+         */
+        String workItemReg = "$s" + Integer.toString(asRegister(cc.getArgument(nonConstantParamCount)).encoding());
+        codeBuffer.emitString("workitemabsid_u32 " + workItemReg + ", 0;");
+
+        /*
+         * Note the logic used for this spillseg size is to leave space and then go back and patch
+         * in the correct size once we have generated all the instructions. This should probably be
+         * done in a more robust way by implementing something like codeBuffer.insertString.
+         */
+        int spillsegDeclarationPosition = codeBuffer.position() + 1;
+        String spillsegTemplate = "align 4 spill_u8 %spillseg[123456];";
+        codeBuffer.emitString(spillsegTemplate);
+        // Emit object array load prologue here.
+        if (isObjectLambda) {
+            final int arrayElementsOffset = 24;
+            String iterationObjArgReg = HSAIL.mapRegister(cc.getArgument(nonConstantParamCount - 1));
+            String tmpReg = workItemReg.replace("s", "d"); // "$d1";
+            // Convert gid to long.
+            codeBuffer.emitString("cvt_u64_s32 " + tmpReg + ", " + workItemReg + "; // Convert gid to long");
+            // Adjust index for sizeof ref.
+            codeBuffer.emitString("mul_u64 " + tmpReg + ", " + tmpReg + ", " + 8 + "; // Adjust index for sizeof ref");
+            // Adjust for actual data start.
+            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + arrayElementsOffset + "; // Adjust for actual elements data start");
+            // Add to array ref ptr.
+            codeBuffer.emitString("add_u64 " + tmpReg + ", " + tmpReg + ", " + iterationObjArgReg + "; // Add to array ref ptr");
+            // Load the object into the parameter reg.
+            codeBuffer.emitString("ld_global_u64 " + iterationObjArgReg + ", " + "[" + tmpReg + "]" + "; // Load from array element into parameter reg");
+        }
+        // Prologue done, Emit code for the LIR.
+        lirGen.lir.emitCode(tasm);
+        // Now that code is emitted go back and figure out what the upper Bound stack size was.
+        long maxStackSize = ((HSAILAssembler) tasm.asm).upperBoundStackSize();
+        String spillsegStringFinal;
+        if (maxStackSize == 0) {
+            // If no spilling, get rid of spillseg declaration.
+            char[] array = new char[spillsegTemplate.length()];
+            Arrays.fill(array, ' ');
+            spillsegStringFinal = new String(array);
+        } else {
+            spillsegStringFinal = spillsegTemplate.replace("123456", String.format("%6d", maxStackSize));
+        }
+        codeBuffer.emitString(spillsegStringFinal, spillsegDeclarationPosition);
+        // Emit the epilogue.
+        codeBuffer.emitString0("};");
+        codeBuffer.emitString("");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotCodeCacheProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.hsail;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hsail.*;
+
+public class HSAILHotSpotCodeCacheProvider extends HotSpotCodeCacheProvider {
+
+    public HSAILHotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) {
+        super(runtime);
+
+    }
+
+    @Override
+    protected RegisterConfig createRegisterConfig() {
+        return new HSAILRegisterConfig();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotGraalRuntime.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.hsail;
+
+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.hsail.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * HSAIL specific implementation of {@link HotSpotGraalRuntime}.
+ */
+public class HSAILHotSpotGraalRuntime extends HotSpotGraalRuntime {
+
+    @Override
+    protected HotSpotProviders createProviders() {
+        HotSpotProviders host = HotSpotGraalRuntime.runtime().getProviders();
+
+        HotSpotMetaAccessProvider metaAccess = host.getMetaAccess();
+        HSAILHotSpotCodeCacheProvider codeCache = new HSAILHotSpotCodeCacheProvider(this);
+        ConstantReflectionProvider constantReflection = host.getConstantReflection();
+        HotSpotForeignCallsProvider foreignCalls = host.getForeignCalls();
+        LoweringProvider lowerer = new HSAILHotSpotLoweringProvider(host.getLowerer());
+        Replacements replacements = host.getReplacements();
+        HotSpotDisassemblerProvider disassembler = host.getDisassembler();
+        HotSpotSuitesProvider suites = host.getSuites();
+        HotSpotRegisters registers = new HotSpotRegisters(Register.None, Register.None, Register.None);
+        return new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
+    }
+
+    @Override
+    protected TargetDescription createTarget() {
+        final int stackFrameAlignment = 8;
+        final int implicitNullCheckLimit = 0;
+        final boolean inlineObjects = true;
+        return new TargetDescription(new HSAIL(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+    }
+
+    @Override
+    protected HotSpotBackend createBackend() {
+        return new HSAILHotSpotBackend(this, getProviders());
+    }
+
+    @Override
+    protected Value[] getNativeABICallerSaveRegisters() {
+        throw new InternalError("NYI");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.hotspot.hsail;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.hsail.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.hsail.*;
+import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer;
+import com.oracle.graal.lir.hsail.HSAILMove.LoadOp;
+import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer;
+import com.oracle.graal.lir.hsail.HSAILMove.StoreOp;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.util.*;
+
+/**
+ * The HotSpot specific portion of the HSAIL LIR generator.
+ */
+public class HSAILHotSpotLIRGenerator extends HSAILLIRGenerator {
+
+    private final HotSpotVMConfig config;
+
+    public HSAILHotSpotLIRGenerator(StructuredGraph graph, Providers providers, HotSpotVMConfig config, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
+        this.config = config;
+    }
+
+    private static boolean isCompressCandidate(DeoptimizingNode access) {
+        return access != null && ((HeapAccess) access).isCompressible();
+    }
+
+    @Override
+    public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) {
+        HSAILAddressValue loadAddress = asAddressValue(address);
+        Variable result = newVariable(kind);
+        LIRFrameState state = access != null ? state(access) : null;
+        assert access == null || access instanceof HeapAccess;
+        if (config.useCompressedOops && isCompressCandidate(access)) {
+            Variable scratch = newVariable(Kind.Long);
+            append(new LoadCompressedPointer(kind, result, scratch, loadAddress, state, config.narrowOopBase, config.narrowOopShift, config.logMinObjAlignment));
+        } else {
+            append(new LoadOp(kind, result, loadAddress, state));
+        }
+        return result;
+    }
+
+    @Override
+    public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) {
+        HSAILAddressValue storeAddress = asAddressValue(address);
+        LIRFrameState state = access != null ? state(access) : null;
+        Variable input = load(inputVal);
+        if (config.useCompressedOops && isCompressCandidate(access)) {
+            Variable scratch = newVariable(Kind.Long);
+            append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, config.narrowOopBase, config.narrowOopShift, config.logMinObjAlignment));
+        } else {
+            append(new StoreOp(kind, storeAddress, input, state));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.hsail;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class HSAILHotSpotLoweringProvider implements LoweringProvider {
+
+    private LoweringProvider hostLowerer;
+
+    public HSAILHotSpotLoweringProvider(LoweringProvider hostLowerer) {
+        this.hostLowerer = hostLowerer;
+    }
+
+    public void lower(Node n, LoweringTool tool) {
+        if (n instanceof ConvertNode) {
+            // TODO
+            return;
+        } else {
+            hostLowerer.lower(n, tool);
+        }
+    }
+
+    public ValueNode reconstructArrayIndex(LocationNode location) {
+        return hostLowerer.reconstructArrayIndex(location);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,8 +37,8 @@
  */
 public class PTXHotSpotBackend extends HotSpotBackend {
 
-    public PTXHotSpotBackend(HotSpotRuntime runtime, TargetDescription target) {
-        super(runtime, target);
+    public PTXHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
+        super(runtime, providers);
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotCodeCacheProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.ptx;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+
+public class PTXHotSpotCodeCacheProvider extends HotSpotCodeCacheProvider {
+
+    public PTXHotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) {
+        super(runtime);
+
+    }
+
+    @Override
+    protected RegisterConfig createRegisterConfig() {
+        return new PTXHotSpotRegisterConfig();
+    }
+}
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime.java	Wed Oct 16 18:27:28 2013 +0200
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.hotspot.ptx;
 
-import com.oracle.graal.ptx.*;
 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.phases.util.*;
+import com.oracle.graal.ptx.*;
 
 /**
  * PTX specific implementation of {@link HotSpotGraalRuntime}.
@@ -40,17 +41,35 @@
      * Called from C++ code to retrieve the singleton instance, creating it first if necessary.
      */
     public static HotSpotGraalRuntime makeInstance() {
-        HotSpotGraalRuntime graalRuntime = graalRuntime();
-        if (graalRuntime == null) {
+        HotSpotGraalRuntime runtime = runtime();
+        if (runtime == null) {
             HotSpotGraalRuntimeFactory factory = findFactory("PTX");
             if (factory != null) {
-                graalRuntime = factory.createRuntime();
+                runtime = factory.createRuntime();
             } else {
-                graalRuntime = new PTXHotSpotGraalRuntime();
+                runtime = new PTXHotSpotGraalRuntime();
             }
-            graalRuntime.completeInitialization();
+            runtime.completeInitialization();
         }
-        return graalRuntime;
+        return runtime;
+    }
+
+    @Override
+    protected HotSpotProviders createProviders() {
+        HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(this);
+        PTXHotSpotCodeCacheProvider codeCache = new PTXHotSpotCodeCacheProvider(this);
+        HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(this);
+        HotSpotForeignCallsProvider foreignCalls = new HotSpotForeignCallsProvider(this);
+        HotSpotLoweringProvider lowerer = new PTXHotSpotLoweringProvider(this, metaAccess, foreignCalls);
+        // Replacements cannot have speculative optimizations since they have
+        // to be valid for the entire run of the VM.
+        Assumptions assumptions = new Assumptions(false);
+        Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
+        HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, getConfig(), assumptions);
+        HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(this);
+        HotSpotSuitesProvider suites = new HotSpotSuitesProvider(this);
+        HotSpotRegistersProvider registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None);
+        return new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers);
     }
 
     protected Architecture createArchitecture() {
@@ -67,12 +86,7 @@
 
     @Override
     protected HotSpotBackend createBackend() {
-        return new PTXHotSpotBackend(getRuntime(), getTarget());
-    }
-
-    @Override
-    protected HotSpotRuntime createRuntime() {
-        return new PTXHotSpotRuntime(config, this);
+        return new PTXHotSpotBackend(this, getProviders());
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.ptx;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class PTXHotSpotLoweringProvider extends HotSpotLoweringProvider {
+
+    public PTXHotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
+        super(runtime, metaAccess, foreignCalls);
+    }
+
+    @Override
+    public void lower(Node n, LoweringTool tool) {
+        if (n instanceof ConvertNode) {
+            // PTX has a cvt instruction that "takes a variety of
+            // operand types and sizes, as its job is to convert from
+            // nearly any data type to any other data type (and
+            // size)." [Section 6.2 of PTX ISA manual]
+            // So, there is no need to lower the operation.
+            return;
+        } else {
+            super.lower(n, tool);
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.ptx;
-
-import static com.oracle.graal.ptx.PTX.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.debug.Debug;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.graph.Node;
-import com.oracle.graal.nodes.calc.ConvertNode;
-
-public class PTXHotSpotRuntime extends HotSpotRuntime {
-
-    public PTXHotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) {
-        super(config, graalRuntime);
-
-    }
-
-    @Override
-    public void lower(Node n, LoweringTool tool) {
-        if (n instanceof ConvertNode) {
-            // PTX has a cvt instruction that "takes a variety of
-            // operand types and sizes, as its job is to convert from
-            // nearly any data type to any other data type (and
-            // size)." [Section 6.2 of PTX ISA manual]
-            // So, there is no need to lower the operation.
-            return;
-        } else {
-            super.lower(n, tool);
-        }
-    }
-
-    @Override
-    public void registerReplacements(Replacements replacements) {
-        Debug.log("PTXHotSpotRuntime.registerReplacements unimplemented");
-    }
-
-    // PTX code does not use stack or stack pointer
-    @Override
-    public Register stackPointerRegister() {
-        return Register.None;
-    }
-
-    // PTX code does not have heap register
-    @Override
-    public Register heapBaseRegister() {
-        return Register.None;
-    }
-
-    // Thread register is %tid.
-    @Override
-    public Register threadRegister() {
-        return tid;
-    }
-
-    @Override
-    protected RegisterConfig createRegisterConfig() {
-        return new PTXHotSpotRegisterConfig();
-    }
-}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Wed Oct 16 18:27:28 2013 +0200
@@ -55,8 +55,8 @@
 
     private static final Unsafe unsafe = Unsafe.getUnsafe();
 
-    public SPARCHotSpotBackend(HotSpotRuntime runtime, TargetDescription target) {
-        super(runtime, target);
+    public SPARCHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
+        super(runtime, providers);
     }
 
     @Override
@@ -66,12 +66,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new SPARCFrameMap(getRuntime(), target, getRuntime().getRegisterConfig());
+        return new SPARCFrameMap(getProviders().getCodeCache());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new SPARCHotSpotLIRGenerator(graph, getProviders(), target, frameMap, cc, lir);
+        return new SPARCHotSpotLIRGenerator(graph, getProviders(), getRuntime().getConfig(), frameMap, cc, lir);
     }
 
     /**
@@ -142,7 +142,7 @@
 
     @Override
     protected AbstractAssembler createAssembler(FrameMap frameMap) {
-        return new SPARCMacroAssembler(target, frameMap.registerConfig);
+        return new SPARCMacroAssembler(getTarget(), frameMap.registerConfig);
     }
 
     @Override
@@ -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, getRuntime(), getRuntime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(getProviders().getCodeCache(), getProviders().getForeignCalls(), 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 = getRuntime().config;
+        HotSpotVMConfig config = getRuntime().getConfig();
         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[]{getRuntime().lookupJavaType(Object.class)}, target, false);
+            CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getProviders().getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false);
             Register inlineCacheKlass = g5; // see MacroAssembler::ic_call
             Register scratch = g3;
             Register receiver = asRegister(cc.getArgument(0));
@@ -204,11 +204,12 @@
         lirGen.lir.emitCode(tasm);
 
         HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
+        HotSpotForeignCallsProvider foreignCalls = getProviders().getForeignCalls();
         if (frameContext != null && !frameContext.isStub) {
             tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            SPARCCall.directCall(tasm, masm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
             tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
+            SPARCCall.directCall(tasm, masm, foreignCalls.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 +219,7 @@
         if (unverifiedStub != null) {
             masm.bind(unverifiedStub);
             Register scratch = g3;
-            SPARCCall.indirectJmp(tasm, masm, scratch, getRuntime().lookupForeignCall(IC_MISS_HANDLER));
+            SPARCCall.indirectJmp(tasm, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER));
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -38,8 +38,8 @@
 
     @Override
     public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        Register thread = graalRuntime().getRuntime().threadRegister();
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        Register thread = runtime().getProviders().getRegisters().getThreadRegister();
+        HotSpotVMConfig config = runtime().getConfig();
 
         // Restore the thread register when coming back from the runtime.
         new Mov(l7, thread).emit(masm);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -39,10 +39,10 @@
 
     @Override
     public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        HotSpotRuntime runtime = graalRuntime().getRuntime();
-        HotSpotVMConfig config = graalRuntime().getConfig();
-        Register thread = runtime.threadRegister();
-        Register stackPointer = runtime.stackPointerRegister();
+        HotSpotRegistersProvider registers = runtime().getProviders().getRegisters();
+        HotSpotVMConfig config = runtime().getConfig();
+        Register thread = registers.getThreadRegister();
+        Register stackPointer = registers.getStackPointerRegister();
 
         // Save last Java frame.
         new Add(stackPointer, new SPARCAddress(stackPointer, 0).getDisplacement(), g4).emit(masm);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -42,7 +42,7 @@
         leaveFrame(tasm);
 
 // SPARCHotSpotBackend backend = (SPARCHotSpotBackend)
-// HotSpotGraalRuntime.graalRuntime().getBackend();
+// HotSpotGraalRuntime.runtime().getBackend();
 // final boolean isStub = true;
 // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub);
 // frameContext.enter(tasm);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.sparc;
+
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.api.meta.Value.*;
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
+import static com.oracle.graal.sparc.SPARC.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+
+public class SPARCHotSpotForeignCallsProvider extends HotSpotForeignCallsProvider {
+
+    public SPARCHotSpotForeignCallsProvider(HotSpotGraalRuntime runtime) {
+        super(runtime);
+    }
+
+    @Override
+    public void initialize(HotSpotProviders providers) {
+        Kind word = runtime.getTarget().wordKind;
+
+        // The calling convention for the exception handler stub is (only?) defined in
+        // TemplateInterpreterGenerator::generate_throw_exception()
+        // in templateInterpreter_sparc.cpp around line 1925
+        RegisterValue outgoingException = o0.asValue(Kind.Object);
+        RegisterValue outgoingExceptionPc = o1.asValue(word);
+        RegisterValue incomingException = i0.asValue(Kind.Object);
+        RegisterValue incomingExceptionPc = i1.asValue(word);
+        CallingConvention outgoingExceptionCc = new CallingConvention(0, ILLEGAL, outgoingException, outgoingExceptionPc);
+        CallingConvention incomingExceptionCc = new CallingConvention(0, ILLEGAL, incomingException, incomingExceptionPc);
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
+        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
+    }
+}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java	Wed Oct 16 18:27:28 2013 +0200
@@ -41,12 +41,18 @@
      * Called from C++ code to retrieve the singleton instance, creating it first if necessary.
      */
     public static HotSpotGraalRuntime makeInstance() {
-        HotSpotGraalRuntime graalRuntime = graalRuntime();
-        if (graalRuntime == null) {
-            graalRuntime = new SPARCHotSpotGraalRuntime();
-            graalRuntime.completeInitialization();
+        HotSpotGraalRuntime runtime = runtime();
+        if (runtime == null) {
+            runtime = new SPARCHotSpotGraalRuntime();
+            runtime.completeInitialization();
         }
-        return graalRuntime;
+        return runtime;
+    }
+
+    @Override
+    protected HotSpotProviders createProviders() {
+        // TODO Auto-generated method stub
+        return null;
     }
 
     protected static Architecture createArchitecture() {
@@ -63,12 +69,7 @@
 
     @Override
     protected HotSpotBackend createBackend() {
-        return new SPARCHotSpotBackend(getRuntime(), getTarget());
-    }
-
-    @Override
-    protected HotSpotRuntime createRuntime() {
-        return new SPARCHotSpotRuntime(config, this);
+        return new SPARCHotSpotBackend(this, getProviders());
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -56,8 +56,8 @@
         leaveFrame(tasm);
 
         // Restore SP from L7 if the exception PC is a method handle call site.
-        Register thread = graalRuntime().getRuntime().threadRegister();
-        int isMethodHandleReturnOffset = graalRuntime().getConfig().threadIsMethodHandleReturnOffset;
+        Register thread = runtime().getProviders().getRegisters().getThreadRegister();
+        int isMethodHandleReturnOffset = runtime().getConfig().threadIsMethodHandleReturnOffset;
         SPARCAddress dst = new SPARCAddress(thread, isMethodHandleReturnOffset);
         new Lduw(dst, o7).emit(masm);
         new Cmp(o7, o7).emit(masm);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -46,16 +46,19 @@
 import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.phases.util.*;
 
 public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator {
 
-    private HotSpotRuntime runtime() {
-        return (HotSpotRuntime) codeCache;
+    private final HotSpotVMConfig config;
+
+    public SPARCHotSpotLIRGenerator(StructuredGraph graph, HotSpotProviders providers, HotSpotVMConfig config, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, providers, frameMap, cc, lir);
+        this.config = config;
     }
 
-    public SPARCHotSpotLIRGenerator(StructuredGraph graph, Providers providers, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, providers, target, frameMap, cc, lir);
+    @Override
+    protected HotSpotProviders getProviders() {
+        return (HotSpotProviders) super.getProviders();
     }
 
     /**
@@ -68,7 +71,7 @@
     @SuppressWarnings("hiding")
     @Override
     protected DebugInfoBuilder createDebugInfoBuilder(NodeMap<Value> nodeOperands) {
-        assert runtime().config.basicLockSize == 8;
+        assert config.basicLockSize == 8;
         HotSpotLockStack lockStack = new HotSpotLockStack(frameMap, Kind.Long);
         return new HotSpotDebugInfoBuilder(nodeOperands, lockStack);
     }
@@ -115,7 +118,7 @@
     @Override
     public void visitSafepointNode(SafepointNode i) {
         LIRFrameState info = state(i);
-        append(new SPARCHotSpotSafepointOp(info, runtime().config, this));
+        append(new SPARCHotSpotSafepointOp(info, config, this));
     }
 
     @Override
@@ -129,7 +132,7 @@
         Variable newValue = load(operand(x.newValue()));
 
         if (ValueUtil.isConstant(offset)) {
-            assert !codeCache.needsDataPatch(asConstant(offset));
+            assert !getCodeCache().needsDataPatch(asConstant(offset));
             Variable longAddress = newVariable(Kind.Long);
             emitMove(longAddress, address);
             address = emitAdd(longAddress, asConstant(offset));
@@ -186,8 +189,9 @@
     }
 
     private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) {
-        int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset;
-        RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind());
+        int pendingDeoptimizationOffset = runtime().getConfig().pendingDeoptimizationOffset;
+        Kind wordKind = getProviders().getCodeCache().getTarget().wordKind;
+        RegisterValue thread = getProviders().getRegisters().getThreadRegister().asValue(wordKind);
         SPARCAddressValue pendingDeoptAddress = new SPARCAddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset);
         append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, emitMove(actionAndReason), null));
     }
@@ -200,7 +204,7 @@
 
     @Override
     public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) {
-        moveDeoptimizationActionAndReasonToThread(metaAccess.encodeDeoptActionAndReason(action, reason));
+        moveDeoptimizationActionAndReasonToThread(getMetaAccess().encodeDeoptActionAndReason(action, reason));
         append(new SPARCHotSpotDeoptimizeCallerOp());
     }
 
@@ -233,15 +237,15 @@
         Variable result = newVariable(kind);
         assert access == null || access instanceof HeapAccess;
         if (isCompressCandidate(access)) {
-            if (runtime().config.useCompressedOops && kind == Kind.Object) {
+            if (config.useCompressedOops && kind == Kind.Object) {
 // append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? state(access) :
-// null, runtime().config.narrowOopBase, runtime().config.narrowOopShift,
-// runtime().config.logMinObjAlignment));
+// null, config.narrowOopBase, config.narrowOopShift,
+// config.logMinObjAlignment));
                 throw GraalInternalError.unimplemented();
-            } else if (runtime().config.useCompressedClassPointers && kind == Kind.Long) {
+            } else if (config.useCompressedClassPointers && kind == Kind.Long) {
 // append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? state(access) :
-// null, runtime().config.narrowKlassBase, runtime().config.narrowKlassShift,
-// runtime().config.logKlassAlignment));
+// null, config.narrowKlassBase, config.narrowKlassShift,
+// config.logKlassAlignment));
                 throw GraalInternalError.unimplemented();
             } else {
                 append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null));
@@ -260,9 +264,9 @@
             Constant c = asConstant(inputVal);
             if (canStoreConstant(c)) {
                 if (inputVal.getKind() == Kind.Object) {
-                    append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedOops && isCompressCandidate(access)));
+                    append(new StoreConstantOp(kind, storeAddress, c, state, config.useCompressedOops && isCompressCandidate(access)));
                 } else if (inputVal.getKind() == Kind.Long) {
-                    append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedClassPointers && isCompressCandidate(access)));
+                    append(new StoreConstantOp(kind, storeAddress, c, state, config.useCompressedClassPointers && isCompressCandidate(access)));
                 } else {
                     append(new StoreConstantOp(kind, storeAddress, c, state, false));
                 }
@@ -271,22 +275,22 @@
         }
         Variable input = load(inputVal);
         if (isCompressCandidate(access)) {
-            if (runtime().config.useCompressedOops && kind == Kind.Object) {
+            if (config.useCompressedOops && kind == Kind.Object) {
 // if (input.getKind() == Kind.Object) {
 // Variable scratch = newVariable(Kind.Long);
 // append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state,
-// runtime().config.narrowOopBase, runtime().config.narrowOopShift,
-// runtime().config.logMinObjAlignment));
+// config.narrowOopBase, config.narrowOopShift,
+// config.logMinObjAlignment));
 // } else {
 // // the input oop is already compressed
 // append(new StoreOp(input.getKind(), storeAddress, input, state));
 // }
                 throw GraalInternalError.unimplemented();
-            } else if (runtime().config.useCompressedClassPointers && kind == Kind.Long) {
+            } else if (config.useCompressedClassPointers && kind == Kind.Long) {
 // Variable scratch = newVariable(Kind.Long);
 // append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state,
-// runtime().config.narrowKlassBase, runtime().config.narrowKlassShift,
-// runtime().config.logKlassAlignment));
+// config.narrowKlassBase, config.narrowKlassShift,
+// config.logKlassAlignment));
                 throw GraalInternalError.unimplemented();
             } else {
                 append(new StoreOp(kind, storeAddress, input, state));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.sparc;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class SPARCHotSpotLoweringProvider extends HotSpotLoweringProvider {
+
+    public SPARCHotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
+        super(runtime, metaAccess, foreignCalls);
+    }
+
+    @Override
+    public void lower(Node n, LoweringTool tool) {
+        if (n instanceof ConvertNode) {
+            // ConvertNodes are handled in SPARCLIRGenerator.emitConvert
+        } else {
+            super.lower(n, tool);
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotReturnOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -52,7 +52,7 @@
         if (!isStub && (tasm.frameContext != null || !OptEliminateSafepoints.getValue())) {
             // Using the same scratch register as LIR_Assembler::return_op
             // in c1_LIRAssembler_sparc.cpp
-            SPARCHotSpotSafepointOp.emitCode(tasm, masm, graalRuntime().getConfig(), true, null, SPARC.l0);
+            SPARCHotSpotSafepointOp.emitCode(tasm, masm, runtime().getConfig(), true, null, SPARC.l0);
         }
         ReturnOp.emitCodeHelper(tasm, masm);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.sparc;
-
-import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.api.meta.LocationIdentity.*;
-import static com.oracle.graal.api.meta.Value.*;
-import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-
-public class SPARCHotSpotRuntime extends HotSpotRuntime {
-
-    public SPARCHotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) {
-        super(config, graalRuntime);
-    }
-
-    @Override
-    public void registerReplacements(Replacements replacements) {
-        Kind word = graalRuntime.getTarget().wordKind;
-
-        // The calling convention for the exception handler stub is (only?) defined in
-        // TemplateInterpreterGenerator::generate_throw_exception()
-        // in templateInterpreter_sparc.cpp around line 1925
-        RegisterValue outgoingException = o0.asValue(Kind.Object);
-        RegisterValue outgoingExceptionPc = o1.asValue(word);
-        RegisterValue incomingException = i0.asValue(Kind.Object);
-        RegisterValue incomingExceptionPc = i1.asValue(word);
-        CallingConvention outgoingExceptionCc = new CallingConvention(0, ILLEGAL, outgoingException, outgoingExceptionPc);
-        CallingConvention incomingExceptionCc = new CallingConvention(0, ILLEGAL, incomingException, incomingExceptionPc);
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
-        register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION));
-
-        super.registerReplacements(replacements);
-    }
-
-    @Override
-    public void lower(Node n, LoweringTool tool) {
-        if (n instanceof ConvertNode) {
-            // ConvertNodes are handled in SPARCLIRGenerator.emitConvert
-        } else {
-            super.lower(n, tool);
-        }
-    }
-
-    @Override
-    public Register threadRegister() {
-        return g2;
-    }
-
-    @Override
-    public Register stackPointerRegister() {
-        return sp;
-    }
-
-    @Override
-    public Register heapBaseRegister() {
-        return r12;
-    }
-
-    @Override
-    protected RegisterConfig createRegisterConfig() {
-        return new SPARCHotSpotRegisterConfig(graalRuntime.getTarget().arch, config);
-    }
-}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -42,7 +42,7 @@
 @Opcode("CALL_DIRECT")
 final class SPARCHotspotDirectStaticCallOp extends DirectCallOp {
 
-    private static final long nonOopBits = HotSpotGraalRuntime.graalRuntime().getConfig().nonOopBits;
+    private static final long nonOopBits = HotSpotGraalRuntime.runtime().getConfig().nonOopBits;
     private final Constant metaspaceMethod;
     private final InvokeKind invokeKind;
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java	Wed Oct 16 18:27:28 2013 +0200
@@ -55,7 +55,7 @@
         // The mark for an invocation that uses an inline cache must be placed at the
         // instruction that loads the Klass from the inline cache.
         tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE);
-        new Setx(HotSpotGraalRuntime.graalRuntime().getConfig().nonOopBits, g3, true).emit(masm);
+        new Setx(HotSpotGraalRuntime.runtime().getConfig().nonOopBits, g3, true).emit(masm);
         super.emitCode(tasm, masm);
     }
 }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -50,7 +50,7 @@
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
         HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true);
         HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult);
-        CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(compiledNmethod, installedCode, null);
+        CodeInstallResult result = runtime().getCompilerToVM().installCode(compiledNmethod, installedCode, null);
         Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK);
 
         // HotSpotRuntime hsRuntime = (HotSpotRuntime) getCodeCache();
@@ -118,7 +118,7 @@
                     Assert.assertNotNull(getCode(installedCodeOwner, graph, true));
                     atLeastOneCompiled = true;
                 } else {
-                    Assert.assertFalse(graalRuntime().getConfig().useAESIntrinsics);
+                    Assert.assertFalse(runtime().getConfig().useAESIntrinsics);
                 }
             }
         }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -33,6 +33,11 @@
  */
 public class HotSpotMethodSubstitutionTest extends MethodSubstitutionTest {
 
+    /*
+     * We have to ignore this test for now because currently there is no way to read uncompressed
+     * pointers in a compressed world via JNI.
+     */
+    @Ignore
     @Test
     public void testObjectSubstitutions() {
         test("getClass0");
@@ -54,6 +59,11 @@
         return obj.hashCode();
     }
 
+    /*
+     * We have to ignore this test for now because currently there is no way to read uncompressed
+     * pointers in a compressed world via JNI.
+     */
+    @Ignore
     @Test
     public void testClassSubstitutions() {
         test("getModifiers");
@@ -112,6 +122,11 @@
         return clazz.getComponentType();
     }
 
+    /*
+     * We have to ignore this test for now because currently there is no way to read uncompressed
+     * pointers in a compressed world via JNI.
+     */
+    @Ignore
     @Test
     public void testThreadSubstitutions() {
         test("currentThread");
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -32,7 +32,7 @@
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
-import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.nodes.*;
@@ -629,7 +629,8 @@
 
                 int barriers = 0;
                 // First, the total number of expected barriers is checked.
-                if (((HotSpotRuntime) getMetaAccess()).config.useG1GC) {
+                HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
+                if (config.useG1GC) {
                     barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() +
                                     graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count();
                     Assert.assertTrue(expectedBarriers * 2 == barriers);
@@ -691,10 +692,10 @@
                     }
                 };
 
-                DebugConfig config = DebugScope.getConfig();
+                DebugConfig debugConfig = DebugScope.getConfig();
                 try {
                     ReentrantNodeIterator.apply(closure, graph.start(), false, null);
-                    Debug.setConfig(Debug.fixedConfig(false, false, false, false, config.dumpHandlers(), config.output()));
+                    Debug.setConfig(Debug.fixedConfig(false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output()));
                     new WriteBarrierVerificationPhase().apply(graph);
                 } catch (AssertionError error) {
                     /*
@@ -704,7 +705,7 @@
                     Assert.assertTrue(error.getMessage().contains("Write barrier must be present"));
                     return error;
                 } finally {
-                    Debug.setConfig(config);
+                    Debug.setConfig(debugConfig);
                 }
                 return null;
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Oct 16 18:27:28 2013 +0200
@@ -58,7 +58,7 @@
         Queued, Running
     }
 
-    private final HotSpotGraalRuntime graalRuntime;
+    private final HotSpotGraalRuntime runtime;
     private final PhasePlan plan;
     private final SuitesProvider suitesProvider;
     private final OptimisticOptimizations optimisticOpts;
@@ -69,15 +69,15 @@
 
     private StructuredGraph graph;
 
-    public static CompilationTask create(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
-        return new CompilationTask(graalRuntime, plan, optimisticOpts, method, entryBCI, id);
+    public static CompilationTask create(HotSpotGraalRuntime runtime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
+        return new CompilationTask(runtime, plan, optimisticOpts, method, entryBCI, id);
     }
 
-    private CompilationTask(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
+    private CompilationTask(HotSpotGraalRuntime runtime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) {
         assert id >= 0;
-        this.graalRuntime = graalRuntime;
+        this.runtime = runtime;
         this.plan = plan;
-        this.suitesProvider = graalRuntime.getCapability(SuitesProvider.class);
+        this.suitesProvider = runtime.getCapability(SuitesProvider.class);
         this.method = method;
         this.optimisticOpts = optimisticOpts;
         this.entryBCI = entryBCI;
@@ -143,8 +143,9 @@
 
                     @Override
                     public CompilationResult call() throws Exception {
-                        graalRuntime.evictDeoptedGraphs();
-                        Replacements replacements = graalRuntime.getReplacements();
+                        runtime.evictDeoptedGraphs();
+                        Providers providers = runtime.getProviders();
+                        Replacements replacements = providers.getReplacements();
                         graph = replacements.getMethodSubstitution(method);
                         if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) {
                             graph = new StructuredGraph(method, entryBCI);
@@ -153,10 +154,8 @@
                             graph = graph.copy();
                         }
                         InliningUtil.InlinedBytecodes.add(method.getCodeSize());
-                        HotSpotRuntime runtime = graalRuntime.getRuntime();
-                        CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-                        Providers providers = new Providers(runtime, runtime, runtime, runtime, runtime, replacements);
-                        return GraalCompiler.compileGraph(graph, cc, method, providers, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts,
+                        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
+                        return GraalCompiler.compileGraph(graph, cc, method, providers, runtime.getBackend(), runtime.getTarget(), runtime.getCache(), plan, optimisticOpts,
                                         method.getSpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult());
                     }
                 });
@@ -213,16 +212,17 @@
     }
 
     private void installMethod(final CompilationResult compResult) {
-        Debug.scope("CodeInstall", new Object[]{new DebugDumpScope(String.valueOf(id), true), graalRuntime.getRuntime(), method}, new Runnable() {
+        final HotSpotCodeCacheProvider codeCache = runtime.getProviders().getCodeCache();
+        Debug.scope("CodeInstall", new Object[]{new DebugDumpScope(String.valueOf(id), true), codeCache, method}, new Runnable() {
 
             @Override
             public void run() {
-                HotSpotInstalledCode installedCode = graalRuntime.getRuntime().installMethod(method, entryBCI, compResult);
+                HotSpotInstalledCode installedCode = codeCache.installMethod(method, entryBCI, compResult);
                 if (Debug.isDumpEnabled()) {
                     Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
                 }
                 if (Debug.isLogEnabled()) {
-                    Debug.log("%s", graalRuntime.getRuntime().disassemble(installedCode));
+                    Debug.log("%s", runtime.getProviders().getDisassembler().disassemble(installedCode));
                 }
             }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Wed Oct 16 18:27:28 2013 +0200
@@ -25,16 +25,14 @@
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
+import java.io.*;
+import java.lang.reflect.*;
 import java.net.*;
-import java.util.Enumeration;
+import java.util.*;
 import java.util.jar.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.bytecode.Bytecodes;
+import com.oracle.graal.bytecode.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -53,8 +51,8 @@
     public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path";
 
     // Some runtime instances we need.
-    private final HotSpotGraalRuntime graalRuntime = graalRuntime();
-    private final VMToCompilerImpl vmToCompiler = (VMToCompilerImpl) graalRuntime.getVMToCompiler();
+    private final HotSpotGraalRuntime runtime = runtime();
+    private final VMToCompilerImpl vmToCompiler = (VMToCompilerImpl) runtime.getVMToCompiler();
 
     /** List of Zip/Jar files to compile (see {@link GraalOptions#CompileTheWorld}. */
     private final String files;
@@ -184,18 +182,19 @@
                     }
 
                     // Are we compiling this class?
+                    HotSpotMetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess();
                     if (classFileCounter >= startAt) {
                         TTY.println("CompileTheWorld (%d) : %s", classFileCounter, className);
 
                         // Enqueue each constructor/method in the class for compilation.
                         for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) {
-                            HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) graalRuntime.getRuntime().lookupJavaConstructor(constructor);
+                            HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaConstructor(constructor);
                             if (canBeCompiled(javaMethod, constructor.getModifiers())) {
                                 compileMethod(javaMethod);
                             }
                         }
                         for (Method method : javaClass.getDeclaredMethods()) {
-                            HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) graalRuntime.getRuntime().lookupJavaMethod(method);
+                            HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
                             if (canBeCompiled(javaMethod, method.getModifiers())) {
                                 compileMethod(javaMethod);
                             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java	Wed Oct 16 18:27:28 2013 +0200
@@ -52,7 +52,7 @@
     public void run() {
         GraalDebugConfig hotspotDebugConfig = null;
         if (Debug.isEnabled()) {
-            PrintStream log = graalRuntime().getVMToCompiler().log();
+            PrintStream log = runtime().getVMToCompiler().log();
             DebugEnvironment.initialize(log);
         }
         try {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed Oct 16 18:27:28 2013 +0200
@@ -22,14 +22,12 @@
  */
 package com.oracle.graal.hotspot;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.word.*;
 
 /**
@@ -69,11 +67,19 @@
      */
     public static final ForeignCallDescriptor EXCEPTION_HANDLER_IN_CALLER = new ForeignCallDescriptor("exceptionHandlerInCaller", void.class, Object.class, Word.class);
 
-    public HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) {
-        super(new Providers(runtime, runtime, runtime, runtime, runtime, null), target);
+    private final HotSpotGraalRuntime runtime;
+
+    public HotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) {
+        super(providers);
+        this.runtime = runtime;
     }
 
-    public HotSpotRuntime getRuntime() {
-        return (HotSpotRuntime) getCodeCache();
+    public HotSpotGraalRuntime getRuntime() {
+        return runtime;
+    }
+
+    @Override
+    public HotSpotProviders getProviders() {
+        return (HotSpotProviders) super.getProviders();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Wed Oct 16 18:27:28 2013 +0200
@@ -31,7 +31,6 @@
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.word.*;
 
@@ -126,7 +125,7 @@
         CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(descriptor, incomingCcType);
         HotSpotForeignCallLinkage linkage = new HotSpotForeignCallLinkage(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations);
         if (outgoingCcType == Type.NativeCall) {
-            linkage.temporaries = graalRuntime().getNativeABICallerSaveRegisters();
+            linkage.temporaries = runtime().getNativeABICallerSaveRegisters();
         }
         return linkage;
     }
@@ -136,22 +135,23 @@
      */
     public static CallingConvention createCallingConvention(ForeignCallDescriptor descriptor, Type ccType) {
         assert ccType != null;
-        HotSpotRuntime runtime = graalRuntime().getRuntime();
+        MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess();
         Class<?>[] argumentTypes = descriptor.getArgumentTypes();
         JavaType[] parameterTypes = new JavaType[argumentTypes.length];
         for (int i = 0; i < parameterTypes.length; ++i) {
-            parameterTypes[i] = asJavaType(argumentTypes[i], runtime);
+            parameterTypes[i] = asJavaType(argumentTypes[i], metaAccess);
         }
-        TargetDescription target = graalRuntime().getTarget();
-        JavaType returnType = asJavaType(descriptor.getResultType(), runtime);
-        return runtime.getRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false);
+        TargetDescription target = runtime().getTarget();
+        JavaType returnType = asJavaType(descriptor.getResultType(), metaAccess);
+        RegisterConfig regConfig = runtime().getProviders().getCodeCache().getRegisterConfig();
+        return regConfig.getCallingConvention(ccType, returnType, parameterTypes, target, false);
     }
 
-    private static JavaType asJavaType(Class type, HotSpotRuntime runtime) {
+    private static JavaType asJavaType(Class type, MetaAccessProvider metaAccess) {
         if (WordBase.class.isAssignableFrom(type)) {
-            return runtime.lookupJavaType(wordKind().toJavaClass());
+            return metaAccess.lookupJavaType(wordKind().toJavaClass());
         } else {
-            return runtime.lookupJavaType(type);
+            return metaAccess.lookupJavaType(type);
         }
     }
 
@@ -206,7 +206,7 @@
     }
 
     public long getMaxCallTargetOffset() {
-        return graalRuntime().getCompilerToVM().getMaxCallTargetOffset(address);
+        return runtime().getCompilerToVM().getMaxCallTargetOffset(address);
     }
 
     public ForeignCallDescriptor getDescriptor() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Oct 16 18:27:28 2013 +0200
@@ -28,6 +28,8 @@
 import java.lang.reflect.*;
 import java.util.*;
 
+import sun.misc.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
@@ -41,8 +43,6 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
 
-//import static com.oracle.graal.phases.GraalOptions.*;
-
 /**
  * Singleton class holding the instance of the {@link GraalRuntime}.
  * 
@@ -55,7 +55,7 @@
     /**
      * Gets the singleton {@link HotSpotGraalRuntime} object.
      */
-    public static HotSpotGraalRuntime graalRuntime() {
+    public static HotSpotGraalRuntime runtime() {
         return instance;
     }
 
@@ -174,9 +174,9 @@
     protected/* final */CompilerToGPU compilerToGpu;
     protected/* final */VMToCompiler vmToCompiler;
 
-    protected final HotSpotRuntime runtime;
+    protected final HotSpotProviders providers;
+
     protected final TargetDescription target;
-    protected final Replacements replacements;
 
     private HotSpotRuntimeInterpreterInterface runtimeInterpreterInterface;
     private volatile HotSpotGraphCache cache;
@@ -214,16 +214,10 @@
         }
 
         target = createTarget();
+        providers = createProviders();
         assert wordKind == null || wordKind.equals(target.wordKind);
         wordKind = target.wordKind;
 
-        runtime = createRuntime();
-
-        // Replacements cannot have speculative optimizations since they have
-        // to be valid for the entire run of the VM.
-        Assumptions assumptions = new Assumptions(false);
-        replacements = new HotSpotReplacementsImpl(runtime, assumptions, runtime.getGraalRuntime().getTarget());
-
         backend = createBackend();
         GraalOptions.StackShadowPages.setValue(config.stackShadowPages);
         if (GraalOptions.CacheGraphs.getValue()) {
@@ -246,12 +240,12 @@
         }
     }
 
+    protected abstract HotSpotProviders createProviders();
+
     protected abstract TargetDescription createTarget();
 
     protected abstract HotSpotBackend createBackend();
 
-    protected abstract HotSpotRuntime createRuntime();
-
     /**
      * Gets the registers that must be saved across a foreign call into the runtime.
      */
@@ -315,17 +309,13 @@
 
     public HotSpotRuntimeInterpreterInterface getRuntimeInterpreterInterface() {
         if (runtimeInterpreterInterface == null) {
-            runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(getRuntime());
+            runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(providers.getMetaAccess());
         }
         return runtimeInterpreterInterface;
     }
 
-    public HotSpotRuntime getRuntime() {
-        return runtime;
-    }
-
-    public Replacements getReplacements() {
-        return replacements;
+    public HotSpotProviders getProviders() {
+        return providers;
     }
 
     public void evictDeoptedGraphs() {
@@ -349,18 +339,35 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T getCapability(Class<T> clazz) {
-        if (clazz == LoweringProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class || clazz == ConstantReflectionProvider.class ||
-                        clazz == ForeignCallsProvider.class) {
-            return (T) getRuntime();
+        if (clazz == LoweringProvider.class) {
+            return (T) providers.getLowerer();
+        }
+        if (clazz == CodeCacheProvider.class) {
+            return (T) providers.getCodeCache();
+        }
+        if (clazz == MetaAccessProvider.class) {
+            return (T) providers.getMetaAccess();
+        }
+        if (clazz == ConstantReflectionProvider.class) {
+            return (T) providers.getConstantReflection();
         }
-        if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class || clazz == SuitesProvider.class) {
-            return (T) getRuntime();
+        if (clazz == ForeignCallsProvider.class) {
+            return (T) providers.getForeignCalls();
+        }
+        if (clazz == DisassemblerProvider.class) {
+            return (T) providers.getDisassembler();
         }
-        if (clazz == HotSpotRuntime.class) {
-            return (T) runtime;
+        if (clazz == BytecodeDisassemblerProvider.class) {
+            return (T) providers.getBytecodeDisassembler();
+        }
+        if (clazz == SuitesProvider.class) {
+            return (T) providers.getSuites();
         }
         if (clazz == Replacements.class) {
-            return (T) replacements;
+            return (T) providers.getReplacements();
+        }
+        if (clazz == HotSpotRegistersProvider.class) {
+            return (T) providers.getRegisters();
         }
         if (clazz == Backend.class) {
             return (T) getBackend();
@@ -371,4 +378,64 @@
     public HotSpotBackend getBackend() {
         return backend;
     }
+
+    /**
+     * The offset from the origin of an array to the first element.
+     * 
+     * @return the offset in bytes
+     */
+    public static int getArrayBaseOffset(Kind kind) {
+        switch (kind) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_BASE_OFFSET;
+            case Char:
+                return Unsafe.ARRAY_CHAR_BASE_OFFSET;
+            case Short:
+                return Unsafe.ARRAY_SHORT_BASE_OFFSET;
+            case Int:
+                return Unsafe.ARRAY_INT_BASE_OFFSET;
+            case Long:
+                return Unsafe.ARRAY_LONG_BASE_OFFSET;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    /**
+     * The scale used for the index when accessing elements of an array of this kind.
+     * 
+     * @return the scale in order to convert the index into a byte offset
+     */
+    public static int getArrayIndexScale(Kind kind) {
+        switch (kind) {
+            case Boolean:
+                return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
+            case Byte:
+                return Unsafe.ARRAY_BYTE_INDEX_SCALE;
+            case Char:
+                return Unsafe.ARRAY_CHAR_INDEX_SCALE;
+            case Short:
+                return Unsafe.ARRAY_SHORT_INDEX_SCALE;
+            case Int:
+                return Unsafe.ARRAY_INT_INDEX_SCALE;
+            case Long:
+                return Unsafe.ARRAY_LONG_INDEX_SCALE;
+            case Float:
+                return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
+            case Double:
+                return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
+            case Object:
+                return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Oct 16 18:27:28 2013 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 
 /**
@@ -39,9 +40,9 @@
 
     private final HotSpotVMConfig config;
 
-    public HotSpotReplacementsImpl(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
-        super(runtime, runtime, runtime, runtime, runtime, assumptions, target);
-        this.config = runtime.config;
+    public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions) {
+        super(providers, assumptions);
+        this.config = config;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java	Wed Oct 16 18:27:28 2013 +0200
@@ -33,10 +33,10 @@
 
 public class HotSpotRuntimeInterpreterInterface {
 
-    private final MetaAccessProvider metaProvider;
+    private final MetaAccessProvider metaAccess;
 
     public HotSpotRuntimeInterpreterInterface(MetaAccessProvider metaProvider) {
-        this.metaProvider = metaProvider;
+        this.metaAccess = metaProvider;
     }
 
     public Class<?> getMirror(ResolvedJavaType type) {
@@ -287,7 +287,7 @@
         if (arrayType == null) {
             return;
         }
-        ResolvedJavaType type = metaProvider.lookupJavaType(array.getClass()).getComponentType();
+        ResolvedJavaType type = metaAccess.lookupJavaType(array.getClass()).getComponentType();
         if (!getMirror(type).isAssignableFrom(arrayType)) {
             throw new ArrayStoreException(arrayType.getName());
         }
@@ -295,7 +295,7 @@
 
     private void checkArray(Object array, long index) {
         nullCheck(array);
-        ResolvedJavaType type = metaProvider.lookupJavaType(array.getClass());
+        ResolvedJavaType type = metaAccess.lookupJavaType(array.getClass());
         if (!type.isArray()) {
             throw new ArrayStoreException(array.getClass().getName());
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,6 +37,7 @@
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
@@ -80,7 +81,7 @@
 
     //@formatter:on
 
-    private final HotSpotGraalRuntime graalRuntime;
+    private final HotSpotGraalRuntime runtime;
 
     public final HotSpotResolvedPrimitiveType typeBoolean;
     public final HotSpotResolvedPrimitiveType typeChar;
@@ -101,8 +102,8 @@
 
     private long compilerStartTime;
 
-    public VMToCompilerImpl(HotSpotGraalRuntime compiler) {
-        this.graalRuntime = compiler;
+    public VMToCompilerImpl(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
 
         typeBoolean = new HotSpotResolvedPrimitiveType(Kind.Boolean);
         typeChar = new HotSpotResolvedPrimitiveType(Kind.Char);
@@ -127,7 +128,7 @@
 
         bootstrapRunning = bootstrapEnabled;
 
-        HotSpotVMConfig config = graalRuntime.getConfig();
+        HotSpotVMConfig config = runtime.getConfig();
         long offset = config.graalMirrorInClassOffset;
         initMirror(typeBoolean, offset);
         initMirror(typeChar, offset);
@@ -179,21 +180,25 @@
             }
         }
 
-        final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class);
-        assert VerifyOptionsPhase.checkOptions(runtime, runtime);
+        final HotSpotProviders providers = runtime.getProviders();
+        final MetaAccessProvider metaAccess = providers.getMetaAccess();
+        assert VerifyOptionsPhase.checkOptions(metaAccess, providers.getForeignCalls());
 
         // Install intrinsics.
-        final Replacements replacements = graalRuntime.getCapability(Replacements.class);
         if (Intrinsify.getValue()) {
             Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() {
 
                 @Override
                 public void run() {
+                    final Replacements replacements = providers.getReplacements();
                     ServiceLoader<ReplacementsProvider> serviceLoader = ServiceLoader.loadInstalled(ReplacementsProvider.class);
+                    TargetDescription target = providers.getCodeCache().getTarget();
+                    HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
                     for (ReplacementsProvider provider : serviceLoader) {
-                        provider.registerReplacements(runtime, replacements, runtime.getTarget());
+                        provider.registerReplacements(metaAccess, lowerer, replacements, target);
                     }
-                    runtime.registerReplacements(replacements);
+                    providers.getForeignCalls().initialize(providers);
+                    lowerer.initialize();
                     if (BootstrapReplacements.getValue()) {
                         for (ResolvedJavaMethod method : replacements.getAllReplacements()) {
                             replacements.getMacroSubstitution(method);
@@ -228,7 +233,7 @@
             t.start();
         }
 
-        BenchmarkCounters.initialize(graalRuntime.getCompilerToVM());
+        BenchmarkCounters.initialize(runtime.getCompilerToVM());
 
         compilerStartTime = System.nanoTime();
     }
@@ -265,7 +270,7 @@
      */
     protected void phaseTransition(String phase) {
         CompilationStatistics.clear(phase);
-        if (graalRuntime.getConfig().ciTime) {
+        if (runtime.getConfig().ciTime) {
             parsedBytecodesPerSecond = MetricRateInPhase.snapshot(phase, parsedBytecodesPerSecond, BytecodesParsed, CompilationTime, TimeUnit.SECONDS);
             inlinedBytecodesPerSecond = MetricRateInPhase.snapshot(phase, inlinedBytecodesPerSecond, InlinedBytecodes, CompilationTime, TimeUnit.SECONDS);
         }
@@ -329,8 +334,8 @@
         bootstrapRunning = false;
 
         TTY.println(" in %d ms (compiled %d methods)", System.currentTimeMillis() - startTime, compileQueue.getCompletedTaskCount());
-        if (graalRuntime.getCache() != null) {
-            graalRuntime.getCache().clear();
+        if (runtime.getCache() != null) {
+            runtime.getCache().clear();
         }
         System.gc();
         phaseTransition("bootstrap2");
@@ -345,7 +350,7 @@
     private MetricRateInPhase inlinedBytecodesPerSecond;
 
     private void enqueue(Method m) throws Throwable {
-        JavaMethod javaMethod = graalRuntime.getRuntime().lookupJavaMethod(m);
+        JavaMethod javaMethod = runtime.getProviders().getMetaAccess().lookupJavaMethod(m);
         assert !Modifier.isAbstract(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) && !Modifier.isNative(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) : javaMethod;
         compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, false);
     }
@@ -418,13 +423,13 @@
         }
         phaseTransition("final");
 
-        if (graalRuntime.getConfig().ciTime) {
+        if (runtime.getConfig().ciTime) {
             parsedBytecodesPerSecond.printAll("ParsedBytecodesPerSecond", System.out);
             inlinedBytecodesPerSecond.printAll("InlinedBytecodesPerSecond", System.out);
         }
 
         SnippetCounter.printGroups(TTY.out().out());
-        BenchmarkCounters.shutdown(graalRuntime.getCompilerToVM(), compilerStartTime);
+        BenchmarkCounters.shutdown(runtime.getCompilerToVM(), compilerStartTime);
     }
 
     private void flattenChildren(DebugValueMap map, DebugValueMap globalMap) {
@@ -552,7 +557,7 @@
 
                 final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method);
                 int id = compileTaskIds.incrementAndGet();
-                CompilationTask task = CompilationTask.create(graalRuntime, createPhasePlan(optimisticOpts, osrCompilation), optimisticOpts, method, entryBCI, id);
+                CompilationTask task = CompilationTask.create(runtime, createPhasePlan(optimisticOpts, osrCompilation), optimisticOpts, method, entryBCI, id);
 
                 if (blocking) {
                     task.runCompilation();
@@ -638,7 +643,7 @@
     public HotSpotResolvedObjectType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, int sizeOrSpecies) {
         HotSpotResolvedObjectType type = new HotSpotResolvedObjectType(metaspaceKlass, name, simpleName, javaMirror, sizeOrSpecies);
 
-        long offset = graalRuntime().getConfig().graalMirrorInClassOffset;
+        long offset = runtime().getConfig().graalMirrorInClassOffset;
         if (!unsafe.compareAndSwapObject(javaMirror, offset, null, type)) {
             // lost the race - return the existing value instead
             type = (HotSpotResolvedObjectType) unsafe.getObject(javaMirror, offset);
@@ -687,7 +692,9 @@
 
     public PhasePlan createPhasePlan(OptimisticOptimizations optimisticOpts, boolean onStackReplacement) {
         PhasePlan phasePlan = new PhasePlan();
-        phasePlan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(graalRuntime.getRuntime(), graalRuntime.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts));
+        MetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess();
+        ForeignCallsProvider foreignCalls = runtime.getProviders().getForeignCalls();
+        phasePlan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), optimisticOpts));
         if (onStackReplacement) {
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase());
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed Oct 16 18:27:28 2013 +0200
@@ -322,12 +322,11 @@
         }
     }
 
-    public static void lower(DynamicCounterNode counter, HotSpotRuntime runtime) {
+    public static void lower(DynamicCounterNode counter, HotSpotRegistersProvider registers, HotSpotVMConfig config, Kind wordKind) {
         StructuredGraph graph = counter.graph();
         if (excludedClassPrefix == null || !counter.graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) {
-            HotSpotVMConfig config = runtime.config;
 
-            ReadRegisterNode thread = graph.add(new ReadRegisterNode(runtime.threadRegister(), runtime.getTarget().wordKind, true, false));
+            ReadRegisterNode thread = graph.add(new ReadRegisterNode(registers.getThreadRegister(), wordKind, true, false));
 
             int index = BenchmarkCounters.getIndex(counter);
             if (index >= config.graalCountersSize) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java	Wed Oct 16 18:27:28 2013 +0200
@@ -40,9 +40,9 @@
         this.bciStart = bciStart;
         this.bciEnd = bciEnd;
         this.slot = slot;
-        JavaType t = graalRuntime().lookupType(type, holder, true);
+        JavaType t = runtime().lookupType(type, holder, true);
         if (t instanceof ResolvedJavaType) {
-            this.resolvedType = (ResolvedJavaType) graalRuntime().lookupType(type, holder, false);
+            this.resolvedType = (ResolvedJavaType) runtime().lookupType(type, holder, false);
         } else {
             throw new AssertionError(t.getClass() + " is not a ResolvedJavaType");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
+import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.Infopoint;
+import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
+import com.oracle.graal.java.*;
+import com.oracle.graal.printer.*;
+
+/**
+ * HotSpot implementation of {@link CodeCacheProvider}.
+ */
+public abstract class HotSpotCodeCacheProvider implements CodeCacheProvider {
+
+    protected final HotSpotGraalRuntime runtime;
+    protected final RegisterConfig regConfig;
+
+    public HotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
+        regConfig = createRegisterConfig();
+    }
+
+    protected abstract RegisterConfig createRegisterConfig();
+
+    @Override
+    public String disassemble(CompilationResult compResult, InstalledCode installedCode) {
+        byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode();
+        long start = installedCode == null ? 0L : installedCode.getStart();
+        TargetDescription target = runtime.getTarget();
+        HexCodeFile hcf = new HexCodeFile(code, start, target.arch.getName(), target.wordSize * 8);
+        if (compResult != null) {
+            HexCodeFile.addAnnotations(hcf, compResult.getAnnotations());
+            addExceptionHandlersComment(compResult, hcf);
+            Register fp = regConfig.getFrameRegister();
+            RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0);
+            for (Infopoint infopoint : compResult.getInfopoints()) {
+                if (infopoint instanceof Call) {
+                    Call call = (Call) infopoint;
+                    if (call.debugInfo != null) {
+                        hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
+                    }
+                    addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}");
+                } else {
+                    if (infopoint.debugInfo != null) {
+                        hcf.addComment(infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString());
+                    }
+                    addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}");
+                }
+            }
+            for (DataPatch site : compResult.getDataReferences()) {
+                hcf.addOperandComment(site.pcOffset, "{" + site.getDataString() + "}");
+            }
+            for (Mark mark : compResult.getMarks()) {
+                hcf.addComment(mark.pcOffset, getMarkName(mark));
+            }
+        }
+        return hcf.toEmbeddedString();
+    }
+
+    /**
+     * Decodes a call target to a mnemonic if possible.
+     */
+    private String getTargetName(Call call) {
+        Field[] fields = runtime.getConfig().getClass().getDeclaredFields();
+        for (Field f : fields) {
+            if (f.getName().endsWith("Stub")) {
+                f.setAccessible(true);
+                try {
+                    Object address = f.get(runtime.getConfig());
+                    if (address.equals(call.target)) {
+                        return f.getName() + ":0x" + Long.toHexString((Long) address);
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return String.valueOf(call.target);
+    }
+
+    /**
+     * Decodes a mark to a mnemonic if possible.
+     */
+    private static String getMarkName(Mark mark) {
+        Field[] fields = Marks.class.getDeclaredFields();
+        for (Field f : fields) {
+            if (Modifier.isStatic(f.getModifiers()) && f.getName().startsWith("MARK_")) {
+                f.setAccessible(true);
+                try {
+                    if (f.get(null).equals(mark.id)) {
+                        return f.getName();
+                    }
+                } catch (Exception e) {
+                }
+            }
+        }
+        return "MARK:" + mark.id;
+    }
+
+    private static void addExceptionHandlersComment(CompilationResult compResult, HexCodeFile hcf) {
+        if (!compResult.getExceptionHandlers().isEmpty()) {
+            String nl = HexCodeFile.NEW_LINE;
+            StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl);
+            for (CompilationResult.ExceptionHandler e : compResult.getExceptionHandlers()) {
+                buf.append("    ").append(e.pcOffset).append(" -> ").append(e.handlerPos).append(nl);
+                hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]");
+                hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]");
+            }
+            hcf.addComment(0, buf.toString());
+        }
+    }
+
+    private static void addOperandComment(HexCodeFile hcf, int pos, String comment) {
+        String oldValue = hcf.addOperandComment(pos, comment);
+        assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue;
+    }
+
+    @Override
+    public RegisterConfig getRegisterConfig() {
+        return regConfig;
+    }
+
+    @Override
+    public int getMinimumOutgoingSize() {
+        return runtime.getConfig().runtimeCallStackSize;
+    }
+
+    public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
+        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true);
+        runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, entryBCI, compResult), installedCode, method.getSpeculationLog());
+        return installedCode;
+    }
+
+    @Override
+    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
+        HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
+        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false);
+        CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null);
+        if (result != CodeInstallResult.OK) {
+            return null;
+        }
+        return code;
+    }
+
+    public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
+
+        HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
+        HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true);
+        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, -1, compResult);
+        CompilerToVM vm = runtime.getCompilerToVM();
+        CodeInstallResult result = vm.installCode(compiled, icode, null);
+        if (result != CodeInstallResult.OK) {
+            return null;
+        }
+        return icode;
+    }
+
+    public boolean needsDataPatch(Constant constant) {
+        return constant.getPrimitiveAnnotation() != null;
+    }
+
+    @Override
+    public TargetDescription getTarget() {
+        return runtime.getTarget();
+    }
+
+    public String disassemble(InstalledCode code) {
+        if (code.isValid()) {
+            long codeBlob = ((HotSpotInstalledCode) code).getCodeBlob();
+            return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob);
+        }
+        return null;
+    }
+
+    public String disassemble(ResolvedJavaMethod method) {
+        return new BytecodeDisassembler().disassemble(method);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Wed Oct 16 18:27:28 2013 +0200
@@ -43,13 +43,13 @@
 
     @Override
     public int length() {
-        return graalRuntime().getCompilerToVM().constantPoolLength(type);
+        return runtime().getCompilerToVM().constantPoolLength(type);
     }
 
     @Override
     public Object lookupConstant(int cpi) {
         assert cpi != 0;
-        Object constant = graalRuntime().getCompilerToVM().lookupConstantInPool(type, cpi);
+        Object constant = runtime().getCompilerToVM().lookupConstantInPool(type, cpi);
         return constant;
     }
 
@@ -61,26 +61,26 @@
     @Override
     public Object lookupAppendix(int cpi, int opcode) {
         assert Bytecodes.isInvoke(opcode);
-        return graalRuntime().getCompilerToVM().lookupAppendixInPool(type, cpi, (byte) opcode);
+        return runtime().getCompilerToVM().lookupAppendixInPool(type, cpi, (byte) opcode);
     }
 
     @Override
     public JavaMethod lookupMethod(int cpi, int opcode) {
-        return graalRuntime().getCompilerToVM().lookupMethodInPool(type, cpi, (byte) opcode);
+        return runtime().getCompilerToVM().lookupMethodInPool(type, cpi, (byte) opcode);
     }
 
     @Override
     public JavaType lookupType(int cpi, int opcode) {
-        return graalRuntime().getCompilerToVM().lookupTypeInPool(type, cpi);
+        return runtime().getCompilerToVM().lookupTypeInPool(type, cpi);
     }
 
     @Override
     public JavaField lookupField(int cpi, int opcode) {
-        return graalRuntime().getCompilerToVM().lookupFieldInPool(type, cpi, (byte) opcode);
+        return runtime().getCompilerToVM().lookupFieldInPool(type, cpi, (byte) opcode);
     }
 
     @Override
     public void loadReferencedType(int cpi, int opcode) {
-        graalRuntime().getCompilerToVM().lookupReferencedTypeInPool(type, cpi, (byte) opcode);
+        runtime().getCompilerToVM().lookupReferencedTypeInPool(type, cpi, (byte) opcode);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * HotSpot implementation of {@link ConstantReflectionProvider}.
+ */
+public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider {
+
+    protected final HotSpotGraalRuntime runtime;
+
+    public HotSpotConstantReflectionProvider(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    @Override
+    public boolean constantEquals(Constant x, Constant y) {
+        return x.equals(y);
+    }
+
+    @Override
+    public Integer lookupArrayLength(Constant array) {
+        if (array.getKind() != Kind.Object || array.isNull() || !array.asObject().getClass().isArray()) {
+            return null;
+        }
+        return Array.getLength(array.asObject());
+    }
+
+    @Override
+    public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) {
+        switch (kind) {
+            case Boolean:
+                return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement));
+            case Byte:
+                return Constant.forByte(base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement));
+            case Char:
+                return Constant.forChar(base == null ? unsafe.getChar(displacement) : unsafe.getChar(base, displacement));
+            case Short:
+                return Constant.forShort(base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement));
+            case Int:
+                return Constant.forInt(base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement));
+            case Long:
+                if (displacement == config().hubOffset && runtime.getConfig().useCompressedClassPointers) {
+                    if (base == null) {
+                        throw new GraalInternalError("Base of object must not be null");
+                    } else {
+                        return Constant.forLong(runtime.getCompilerToVM().readUnsafeKlassPointer(base));
+                    }
+                } else {
+                    return Constant.forLong(base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement));
+                }
+            case Float:
+                return Constant.forFloat(base == null ? unsafe.getFloat(displacement) : unsafe.getFloat(base, displacement));
+            case Double:
+                return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement));
+            case Object: {
+                Object o = null;
+                if (compressible) {
+                    o = unsafe.getObject(base, displacement);
+                } else {
+                    o = runtime.getCompilerToVM().readUnsafeUncompressedPointer(base, displacement);
+                }
+                return Constant.forObject(o);
+            }
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotDisassemblerProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.hotspot.*;
+
+/**
+ * HotSpot implementation of {@link DisassemblerProvider}.
+ */
+public class HotSpotDisassemblerProvider implements DisassemblerProvider {
+
+    protected final HotSpotGraalRuntime runtime;
+
+    public HotSpotDisassemblerProvider(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    public String disassemble(InstalledCode code) {
+        if (code.isValid()) {
+            long codeBlob = ((HotSpotInstalledCode) code).getCodeBlob();
+            return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob);
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
+import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*;
+import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*;
+import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
+import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
+import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.hotspot.replacements.MonitorSnippets.*;
+import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*;
+import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*;
+import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*;
+import static com.oracle.graal.hotspot.replacements.WriteBarrierSnippets.*;
+import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*;
+import static com.oracle.graal.hotspot.stubs.NewArrayStub.*;
+import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
+import static com.oracle.graal.hotspot.stubs.StubUtil.*;
+import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*;
+import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
+import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
+import static com.oracle.graal.replacements.Log.*;
+import static com.oracle.graal.replacements.MathSubstitutionsX86.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
+import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition;
+import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.word.*;
+
+/**
+ * HotSpot implementation of {@link ForeignCallsProvider}.
+ */
+public class HotSpotForeignCallsProvider implements ForeignCallsProvider {
+
+    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);
+    public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class);
+    public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class);
+
+    protected final HotSpotGraalRuntime runtime;
+
+    private final Map<ForeignCallDescriptor, HotSpotForeignCallLinkage> foreignCalls = new HashMap<>();
+
+    public HotSpotForeignCallsProvider(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    /**
+     * Registers the linkage for a foreign call.
+     */
+    protected HotSpotForeignCallLinkage register(HotSpotForeignCallLinkage linkage) {
+        assert !foreignCalls.containsKey(linkage.getDescriptor()) : "already registered linkage for " + linkage.getDescriptor();
+        foreignCalls.put(linkage.getDescriptor(), linkage);
+        return linkage;
+    }
+
+    /**
+     * Creates and registers the details for linking a foreign call to a {@link Stub}.
+     * 
+     * @param descriptor the signature of the call to the stub
+     * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side
+     *            effects. Deoptimization will not return to a point before a stub call that cannot
+     *            be re-executed.
+     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
+     * @param killedLocations the memory locations killed by the stub call
+     */
+    protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) {
+        return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
+    }
+
+    /**
+     * Creates and registers the linkage for a foreign call.
+     * 
+     * @param descriptor the signature of the foreign call
+     * @param address the address of the code to call
+     * @param outgoingCcType outgoing (caller) calling convention type
+     * @param effect specifies if the call destroys or preserves all registers (apart from
+     *            temporaries which are always destroyed)
+     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
+     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
+     *            side effects. Deoptimization will not return to a point before a foreign call that
+     *            cannot be re-executed.
+     * @param killedLocations the memory locations killed by the foreign call
+     */
+    protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type outgoingCcType, RegisterEffect effect, Transition transition,
+                    boolean reexecutable, LocationIdentity... killedLocations) {
+        Class<?> resultType = descriptor.getResultType();
+        assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor;
+        return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, outgoingCcType, null, transition, reexecutable, killedLocations));
+    }
+
+    private static void link(Stub stub) {
+        stub.getLinkage().setCompiledStub(stub);
+    }
+
+    /**
+     * Creates a {@linkplain ForeignCallStub stub} for a foreign call.
+     * 
+     * @param descriptor the signature of the call to the stub
+     * @param address the address of the foreign code to call
+     * @param prependThread true if the JavaThread value for the current thread is to be prepended
+     *            to the arguments for the call to {@code address}
+     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
+     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
+     *            side effects. Deoptimization will not return to a point before a foreign call that
+     *            cannot be re-executed.
+     * @param killedLocations the memory locations killed by the foreign call
+     */
+    private void linkForeignCall(HotSpotProviders providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
+                    LocationIdentity... killedLocations) {
+        ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations);
+        HotSpotForeignCallLinkage linkage = stub.getLinkage();
+        HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage();
+        linkage.setCompiledStub(stub);
+        register(linkage);
+        register(targetLinkage);
+    }
+
+    public static final boolean PREPEND_THREAD = true;
+    public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD;
+
+    public static final boolean REEXECUTABLE = true;
+    public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE;
+
+    public static final LocationIdentity[] NO_LOCATIONS = {};
+
+    public void initialize(HotSpotProviders providers) {
+        HotSpotVMConfig c = runtime.getConfig();
+        TargetDescription target = providers.getCodeCache().getTarget();
+
+        registerForeignCall(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+
+        registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+
+        registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        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(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(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);
+    }
+
+    public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
+        HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor);
+        assert foreignCalls != null : descriptor;
+        callTarget.finalizeAddress(runtime.getBackend());
+        return callTarget;
+    }
+
+    @Override
+    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
+        return foreignCalls.get(descriptor).isReexecutable();
+    }
+
+    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
+        return foreignCalls.get(descriptor).canDeoptimize();
+    }
+
+    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
+        return foreignCalls.get(descriptor).getKilledLocations();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.graal.api.code.MemoryBarriers.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationReason.*;
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*;
+import static com.oracle.graal.nodes.java.ArrayLengthNode.*;
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.debug.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.replacements.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.HeapAccess.BarrierType;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.debug.*;
+import com.oracle.graal.nodes.extended.*;
+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.virtual.*;
+import com.oracle.graal.replacements.*;
+
+/**
+ * HotSpot implementation of {@link LoweringProvider}.
+ */
+public class HotSpotLoweringProvider implements LoweringProvider {
+
+    protected final HotSpotGraalRuntime runtime;
+    protected final MetaAccessProvider metaAccess;
+    protected final ForeignCallsProvider foreignCalls;
+
+    private CheckCastDynamicSnippets.Templates checkcastDynamicSnippets;
+    private InstanceOfSnippets.Templates instanceofSnippets;
+    private NewObjectSnippets.Templates newObjectSnippets;
+    private MonitorSnippets.Templates monitorSnippets;
+    protected WriteBarrierSnippets.Templates writeBarrierSnippets;
+    private BoxingSnippets.Templates boxingSnippets;
+    private LoadExceptionObjectSnippets.Templates exceptionObjectSnippets;
+    private UnsafeLoadSnippets.Templates unsafeLoadSnippets;
+
+    public HotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) {
+        this.runtime = runtime;
+        this.metaAccess = metaAccess;
+        this.foreignCalls = foreignCalls;
+    }
+
+    public void initialize() {
+        HotSpotVMConfig c = runtime.getConfig();
+        HotSpotProviders providers = runtime.getProviders();
+        Replacements r = providers.getReplacements();
+
+        r.registerSubstitutions(ObjectSubstitutions.class);
+        r.registerSubstitutions(SystemSubstitutions.class);
+        r.registerSubstitutions(ThreadSubstitutions.class);
+        r.registerSubstitutions(UnsafeSubstitutions.class);
+        r.registerSubstitutions(ClassSubstitutions.class);
+        r.registerSubstitutions(AESCryptSubstitutions.class);
+        r.registerSubstitutions(CipherBlockChainingSubstitutions.class);
+        r.registerSubstitutions(CRC32Substitutions.class);
+        r.registerSubstitutions(ReflectionSubstitutions.class);
+
+        checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(providers, runtime.getTarget());
+        instanceofSnippets = new InstanceOfSnippets.Templates(providers, runtime.getTarget());
+        newObjectSnippets = new NewObjectSnippets.Templates(providers, runtime.getTarget());
+        monitorSnippets = new MonitorSnippets.Templates(providers, runtime.getTarget(), c.useFastLocking);
+        writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, runtime.getTarget());
+        boxingSnippets = new BoxingSnippets.Templates(providers, runtime.getTarget());
+        exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, runtime.getTarget());
+        unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, runtime.getTarget());
+
+        r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, runtime.getTarget()));
+    }
+
+    @Override
+    public void lower(Node n, LoweringTool tool) {
+        HotSpotVMConfig config = runtime.getConfig();
+        StructuredGraph graph = (StructuredGraph) n.graph();
+
+        Kind wordKind = runtime.getTarget().wordKind;
+        if (n instanceof ArrayLengthNode) {
+            ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
+            ValueNode array = arrayLengthNode.array();
+            ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt(),
+                            BarrierType.NONE, false));
+            tool.createNullCheckGuard(arrayLengthRead, array);
+            graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead);
+        } else if (n instanceof Invoke) {
+            Invoke invoke = (Invoke) n;
+            if (invoke.callTarget() instanceof MethodCallTargetNode) {
+
+                MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
+                NodeInputList<ValueNode> parameters = callTarget.arguments();
+                ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
+                GuardingNode receiverNullCheck = null;
+                if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !ObjectStamp.isObjectNonNull(receiver)) {
+                    receiverNullCheck = tool.createNullCheckGuard(invoke, receiver);
+                }
+                JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
+
+                LoweredCallTargetNode loweredCallTarget = null;
+                if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) {
+
+                    HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
+                    if (!hsMethod.getDeclaringClass().isInterface()) {
+                        if (hsMethod.isInVirtualMethodTable()) {
+                            int vtableEntryOffset = hsMethod.vtableEntryOffset();
+                            assert vtableEntryOffset > 0;
+                            FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck);
+
+                            ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod);
+                            // We use LocationNode.ANY_LOCATION for the reads that access the
+                            // compiled code entry as HotSpot does not guarantee they are final
+                            // values.
+                            ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph),
+                                            StampFactory.forKind(wordKind), BarrierType.NONE, false));
+
+                            loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(),
+                                            CallingConvention.Type.JavaCall));
+
+                            graph.addBeforeFixed(invoke.asNode(), metaspaceMethod);
+                            graph.addAfterFixed(metaspaceMethod, compiledEntry);
+                        }
+                    }
+                }
+
+                if (loweredCallTarget == null) {
+                    loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall,
+                                    callTarget.invokeKind()));
+                }
+                callTarget.replaceAndDelete(loweredCallTarget);
+            }
+        } else if (n instanceof LoadFieldNode) {
+            LoadFieldNode loadField = (LoadFieldNode) n;
+            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field();
+            ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : loadField.object();
+            assert loadField.kind() != Kind.Illegal;
+            BarrierType barrierType = getFieldLoadBarrierType(field);
+            ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object)));
+            graph.replaceFixedWithFixed(loadField, memoryRead);
+            tool.createNullCheckGuard(memoryRead, object);
+
+            if (loadField.isVolatile()) {
+                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
+                graph.addBeforeFixed(memoryRead, preMembar);
+                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
+                graph.addAfterFixed(memoryRead, postMembar);
+            }
+        } else if (n instanceof StoreFieldNode) {
+            StoreFieldNode storeField = (StoreFieldNode) n;
+            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
+            ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object();
+            BarrierType barrierType = getFieldStoreBarrierType(storeField);
+            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object));
+            tool.createNullCheckGuard(memoryWrite, object);
+            memoryWrite.setStateAfter(storeField.stateAfter());
+            graph.replaceFixedWithFixed(storeField, memoryWrite);
+            FixedWithNextNode last = memoryWrite;
+            FixedWithNextNode first = memoryWrite;
+
+            if (storeField.isVolatile()) {
+                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
+                graph.addBeforeFixed(first, preMembar);
+                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
+                graph.addAfterFixed(last, postMembar);
+            }
+        } else if (n instanceof CompareAndSwapNode) {
+            // Separate out GC barrier semantics
+            CompareAndSwapNode cas = (CompareAndSwapNode) n;
+            LocationNode location = IndexedLocationNode.create(ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1);
+            LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas),
+                            cas.expected().kind() == Kind.Object));
+            atomicNode.setStateAfter(cas.stateAfter());
+            graph.replaceFixedWithFixed(cas, atomicNode);
+        } else if (n instanceof LoadIndexedNode) {
+            LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
+            GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool);
+            Kind elementKind = loadIndexed.elementKind();
+            LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false);
+            ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object));
+            memoryRead.setGuard(boundsCheck);
+            graph.replaceFixedWithFixed(loadIndexed, memoryRead);
+        } else if (n instanceof StoreIndexedNode) {
+            StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
+            GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool);
+            Kind elementKind = storeIndexed.elementKind();
+            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false);
+            ValueNode value = storeIndexed.value();
+            ValueNode array = storeIndexed.array();
+
+            CheckCastNode checkcastNode = null;
+            CheckCastDynamicNode checkcastDynamicNode = null;
+            if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) {
+                // Store check!
+                ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array);
+                if (arrayType != null && ObjectStamp.isExactType(array)) {
+                    ResolvedJavaType elementType = arrayType.getComponentType();
+                    if (!MetaUtil.isJavaLangObject(elementType)) {
+                        checkcastNode = graph.add(new CheckCastNode(elementType, value, null, true));
+                        graph.addBeforeFixed(storeIndexed, checkcastNode);
+                        value = checkcastNode;
+                    }
+                } else {
+                    FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck);
+                    LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph);
+                    /*
+                     * Anchor the read of the element klass to the cfg, because it is only valid
+                     * when arrayClass is an object class, which might not be the case in other
+                     * parts of the compiled method.
+                     */
+                    FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind), BeginNode.prevBegin(storeIndexed)));
+                    checkcastDynamicNode = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true));
+                    graph.addBeforeFixed(storeIndexed, checkcastDynamicNode);
+                    value = checkcastDynamicNode;
+                }
+            }
+            BarrierType barrierType = getArrayStoreBarrierType(storeIndexed);
+            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object));
+            memoryWrite.setGuard(boundsCheck);
+            memoryWrite.setStateAfter(storeIndexed.stateAfter());
+            graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
+
+            // Lower the associated checkcast node.
+            if (checkcastNode != null) {
+                checkcastNode.lower(tool);
+            } else if (checkcastDynamicNode != null) {
+                checkcastDynamicSnippets.lower(checkcastDynamicNode);
+            }
+        } else if (n instanceof UnsafeLoadNode) {
+            UnsafeLoadNode load = (UnsafeLoadNode) n;
+            if (load.getGuardingCondition() != null) {
+                boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
+                ConditionAnchorNode valueAnchorNode = graph.add(new ConditionAnchorNode(load.getGuardingCondition()));
+                LocationNode location = createLocation(load);
+                ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), valueAnchorNode, BarrierType.NONE, compressible));
+                load.replaceAtUsages(memoryRead);
+                graph.replaceFixedWithFixed(load, valueAnchorNode);
+                graph.addAfterFixed(valueAnchorNode, memoryRead);
+            } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) {
+                assert load.kind() != Kind.Illegal;
+                boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
+                if (addReadBarrier(load)) {
+                    unsafeLoadSnippets.lower(load, tool);
+                } else {
+                    LocationNode location = createLocation(load);
+                    ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible));
+                    // An unsafe read must not float outside its block otherwise
+                    // it may float above an explicit null check on its object.
+                    memoryRead.setGuard(AbstractBeginNode.prevBegin(load));
+                    graph.replaceFixedWithFixed(load, memoryRead);
+                }
+            }
+        } else if (n instanceof UnsafeStoreNode) {
+            UnsafeStoreNode store = (UnsafeStoreNode) n;
+            LocationNode location = createLocation(store);
+            ValueNode object = store.object();
+            BarrierType barrierType = getUnsafeStoreBarrierType(store);
+            WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object));
+            write.setStateAfter(store.stateAfter());
+            graph.replaceFixedWithFixed(store, write);
+        } else if (n instanceof LoadHubNode) {
+            LoadHubNode loadHub = (LoadHubNode) n;
+            assert loadHub.kind() == wordKind;
+            ValueNode object = loadHub.object();
+            GuardingNode guard = loadHub.getGuard();
+            FloatingReadNode hub = createReadHub(graph, wordKind, object, guard);
+            graph.replaceFloating(loadHub, hub);
+        } else if (n instanceof LoadMethodNode) {
+            LoadMethodNode loadMethodNode = (LoadMethodNode) n;
+            ResolvedJavaMethod method = loadMethodNode.getMethod();
+            ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, loadMethodNode.getHub(), method);
+            graph.replaceFixed(loadMethodNode, metaspaceMethod);
+        } else if (n instanceof StoreHubNode) {
+            StoreHubNode storeHub = (StoreHubNode) n;
+            WriteNode hub = createWriteHub(graph, wordKind, storeHub.getObject(), storeHub.getValue());
+            graph.replaceFixed(storeHub, hub);
+        } else if (n instanceof CommitAllocationNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+                CommitAllocationNode commit = (CommitAllocationNode) n;
+
+                ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
+                    int entryCount = virtual.entryCount();
+
+                    FixedWithNextNode newObject;
+                    if (virtual instanceof VirtualInstanceNode) {
+                        newObject = graph.add(new NewInstanceNode(virtual.type(), true));
+                    } else {
+                        ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType();
+                        newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true));
+                    }
+                    graph.addBeforeFixed(commit, newObject);
+                    allocations[objIndex] = newObject;
+                }
+                int valuePos = 0;
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
+                    int entryCount = virtual.entryCount();
+
+                    ValueNode newObject = allocations[objIndex];
+                    if (virtual instanceof VirtualInstanceNode) {
+                        VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
+                        for (int i = 0; i < entryCount; i++) {
+                            ValueNode value = commit.getValues().get(valuePos++);
+                            if (value instanceof VirtualObjectNode) {
+                                value = allocations[commit.getVirtualObjects().indexOf(value)];
+                            }
+                            if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
+                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true),
+                                                (virtualInstance.field(i).getKind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.IMPRECISE : BarrierType.NONE,
+                                                virtualInstance.field(i).getKind() == Kind.Object);
+                                graph.addBeforeFixed(commit, graph.add(write));
+                            }
+                        }
+
+                    } else {
+                        VirtualArrayNode array = (VirtualArrayNode) virtual;
+                        ResolvedJavaType element = array.componentType();
+                        for (int i = 0; i < entryCount; i++) {
+                            ValueNode value = commit.getValues().get(valuePos++);
+                            if (value instanceof VirtualObjectNode) {
+                                int indexOf = commit.getVirtualObjects().indexOf(value);
+                                assert indexOf != -1 : commit + " " + value;
+                                value = allocations[indexOf];
+                            }
+                            if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
+                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph), true),
+                                                (value.kind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object);
+                                graph.addBeforeFixed(commit, graph.add(write));
+                            }
+                        }
+                    }
+                }
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex]));
+                    allocations[objIndex] = anchor;
+                    graph.addBeforeFixed(commit, anchor);
+                }
+                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
+                    for (int lockDepth : commit.getLocks().get(objIndex)) {
+                        MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth));
+                        graph.addBeforeFixed(commit, enter);
+                        enter.lower(tool);
+                    }
+                }
+                for (Node usage : commit.usages().snapshot()) {
+                    AllocatedObjectNode addObject = (AllocatedObjectNode) usage;
+                    int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject());
+                    graph.replaceFloating(addObject, allocations[index]);
+                }
+                graph.removeFixed(commit);
+            }
+        } else if (n instanceof OSRStartNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+                OSRStartNode osrStart = (OSRStartNode) n;
+                StartNode newStart = graph.add(new StartNode());
+                LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind)));
+                ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer));
+                migrationEnd.setStateAfter(osrStart.stateAfter());
+
+                newStart.setNext(migrationEnd);
+                FixedNode next = osrStart.next();
+                osrStart.setNext(null);
+                migrationEnd.setNext(next);
+                graph.setStart(newStart);
+
+                // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block)
+                int localsOffset = (graph.method().getMaxLocals() - 1) * 8;
+                for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) {
+                    int size = FrameStateBuilder.stackSlots(osrLocal.kind());
+                    int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
+                    IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1);
+                    ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false));
+                    osrLocal.replaceAndDelete(load);
+                    graph.addBeforeFixed(migrationEnd, load);
+                }
+                osrStart.replaceAtUsages(newStart);
+                osrStart.safeDelete();
+            }
+        } else if (n instanceof DynamicCounterNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+                BenchmarkCounters.lower((DynamicCounterNode) n, runtime.getProviders().getRegisters(), runtime.getConfig(), wordKind);
+            }
+        } else if (n instanceof CheckCastDynamicNode) {
+            checkcastDynamicSnippets.lower((CheckCastDynamicNode) n);
+        } else if (n instanceof InstanceOfNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+                instanceofSnippets.lower((InstanceOfNode) n, tool);
+            }
+        } else if (n instanceof InstanceOfDynamicNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+                instanceofSnippets.lower((InstanceOfDynamicNode) n, tool);
+            }
+        } else if (n instanceof NewInstanceNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+                newObjectSnippets.lower((NewInstanceNode) n);
+            }
+        } else if (n instanceof NewArrayNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+                newObjectSnippets.lower((NewArrayNode) n);
+            }
+        } else if (n instanceof DynamicNewArrayNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+                newObjectSnippets.lower((DynamicNewArrayNode) n);
+            }
+        } else if (n instanceof MonitorEnterNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+                monitorSnippets.lower((MonitorEnterNode) n, tool);
+            }
+        } else if (n instanceof MonitorExitNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+                monitorSnippets.lower((MonitorExitNode) n, tool);
+            }
+        } else if (n instanceof G1PreWriteBarrier) {
+            writeBarrierSnippets.lower((G1PreWriteBarrier) n, tool);
+        } else if (n instanceof G1PostWriteBarrier) {
+            writeBarrierSnippets.lower((G1PostWriteBarrier) n, tool);
+        } else if (n instanceof G1ReferentFieldReadBarrier) {
+            writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool);
+        } else if (n instanceof SerialWriteBarrier) {
+            writeBarrierSnippets.lower((SerialWriteBarrier) n, tool);
+        } else if (n instanceof SerialArrayRangeWriteBarrier) {
+            writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
+        } else if (n instanceof G1ArrayRangePreWriteBarrier) {
+            writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool);
+        } else if (n instanceof G1ArrayRangePostWriteBarrier) {
+            writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool);
+        } else if (n instanceof NewMultiArrayNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
+                newObjectSnippets.lower((NewMultiArrayNode) n);
+            }
+        } else if (n instanceof LoadExceptionObjectNode) {
+            exceptionObjectSnippets.lower((LoadExceptionObjectNode) n);
+        } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) {
+            // Nothing to do for division nodes. The HotSpot signal handler catches divisions by
+            // zero and the MIN_VALUE / -1 cases.
+        } else if (n instanceof BoxNode) {
+            boxingSnippets.lower((BoxNode) n, tool);
+        } else if (n instanceof UnboxNode) {
+            boxingSnippets.lower((UnboxNode) n, tool);
+        } else {
+            assert false : "Node implementing Lowerable not handled: " + n;
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static LocationNode createLocation(UnsafeAccessNode access) {
+        ValueNode offset = access.offset();
+        if (offset.isConstant()) {
+            long offsetValue = offset.asConstant().asLong();
+            return ConstantLocationNode.create(access.getLocationIdentity(), access.accessKind(), offsetValue, access.graph());
+        }
+
+        long displacement = 0;
+        int indexScaling = 1;
+        if (offset instanceof IntegerAddNode) {
+            IntegerAddNode integerAddNode = (IntegerAddNode) offset;
+            if (integerAddNode.y() instanceof ConstantNode) {
+                displacement = integerAddNode.y().asConstant().asLong();
+                offset = integerAddNode.x();
+            }
+        }
+
+        if (offset instanceof LeftShiftNode) {
+            LeftShiftNode leftShiftNode = (LeftShiftNode) offset;
+            if (leftShiftNode.y() instanceof ConstantNode) {
+                long shift = leftShiftNode.y().asConstant().asLong();
+                if (shift >= 1 && shift <= 3) {
+                    if (shift == 1) {
+                        indexScaling = 2;
+                    } else if (shift == 2) {
+                        indexScaling = 4;
+                    } else {
+                        indexScaling = 8;
+                    }
+                    offset = leftShiftNode.x();
+                }
+            }
+        }
+
+        return IndexedLocationNode.create(access.getLocationIdentity(), access.accessKind(), displacement, offset, access.graph(), indexScaling);
+    }
+
+    private static boolean addReadBarrier(UnsafeLoadNode load) {
+        if (useG1GC() && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object &&
+                        !ObjectStamp.isObjectAlwaysNull(load.object())) {
+            ResolvedJavaType type = ObjectStamp.typeOrNull(load.object());
+            if (type != null && !type.isArray()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) {
+        HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
+        assert !hsMethod.getDeclaringClass().isInterface();
+        assert hsMethod.isInVirtualMethodTable();
+
+        int vtableEntryOffset = hsMethod.vtableEntryOffset();
+        assert vtableEntryOffset > 0;
+        // We use LocationNode.ANY_LOCATION for the reads that access the vtable
+        // entry as HotSpot does not guarantee that this is a final value.
+        ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind), BarrierType.NONE, false));
+        return metaspaceMethod;
+    }
+
+    private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) {
+        HotSpotVMConfig config = runtime.getConfig();
+        LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph);
+        assert !object.isConstant() || object.asConstant().isNull();
+        return graph.unique(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind), guard, BarrierType.NONE, config.useCompressedClassPointers));
+    }
+
+    private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) {
+        HotSpotVMConfig config = runtime.getConfig();
+        LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph);
+        assert !object.isConstant() || object.asConstant().isNull();
+        return graph.add(new WriteNode(object, value, location, BarrierType.NONE, config.useCompressedClassPointers));
+    }
+
+    private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) {
+        BarrierType barrierType = BarrierType.NONE;
+        if (config().useG1GC && loadField.getKind() == Kind.Object && loadField.getDeclaringClass().mirror() == java.lang.ref.Reference.class && loadField.getName().equals("referent")) {
+            barrierType = BarrierType.PRECISE;
+        }
+        return barrierType;
+    }
+
+    private static BarrierType getFieldStoreBarrierType(StoreFieldNode storeField) {
+        BarrierType barrierType = BarrierType.NONE;
+        if (storeField.field().getKind() == Kind.Object && !deferInitBarrier(storeField.object())) {
+            barrierType = BarrierType.IMPRECISE;
+        }
+        return barrierType;
+    }
+
+    private static BarrierType getArrayStoreBarrierType(StoreIndexedNode store) {
+        BarrierType barrierType = BarrierType.NONE;
+        if (store.elementKind() == Kind.Object && !deferInitBarrier(store.array())) {
+            barrierType = BarrierType.PRECISE;
+        }
+        return barrierType;
+    }
+
+    private static boolean deferInitBarrier(ValueNode object) {
+        return useDeferredInitBarriers() && (object instanceof NewInstanceNode || object instanceof NewArrayNode);
+    }
+
+    private static BarrierType getUnsafeStoreBarrierType(UnsafeStoreNode store) {
+        BarrierType barrierType = BarrierType.NONE;
+        if (store.value().kind() == Kind.Object) {
+            ResolvedJavaType type = ObjectStamp.typeOrNull(store.object());
+            if (type != null && !type.isArray()) {
+                barrierType = BarrierType.IMPRECISE;
+            } else {
+                barrierType = BarrierType.PRECISE;
+            }
+        }
+        return barrierType;
+    }
+
+    private static BarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) {
+        BarrierType barrierType = BarrierType.NONE;
+        if (cas.expected().kind() == Kind.Object) {
+            ResolvedJavaType type = ObjectStamp.typeOrNull(cas.object());
+            if (type != null && !type.isArray()) {
+                barrierType = BarrierType.IMPRECISE;
+            } else {
+                barrierType = BarrierType.PRECISE;
+            }
+        }
+        return barrierType;
+    }
+
+    protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field, boolean initialization) {
+        LocationIdentity loc = initialization ? INIT_LOCATION : field;
+        return ConstantLocationNode.create(loc, field.getKind(), field.offset(), graph);
+    }
+
+    public int getScalingFactor(Kind kind) {
+        if (useCompressedOops() && kind == Kind.Object) {
+            return this.runtime.getTarget().arch.getSizeInBytes(Kind.Int);
+        } else {
+            return this.runtime.getTarget().arch.getSizeInBytes(kind);
+        }
+    }
+
+    protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) {
+        LocationIdentity loc = initialization ? INIT_LOCATION : NamedLocationIdentity.getArrayLocation(elementKind);
+        int scale = getScalingFactor(elementKind);
+        return IndexedLocationNode.create(loc, elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
+    }
+
+    @Override
+    public ValueNode reconstructArrayIndex(LocationNode location) {
+        Kind elementKind = location.getValueKind();
+        assert location.getLocationIdentity().equals(NamedLocationIdentity.getArrayLocation(elementKind));
+
+        long base;
+        ValueNode index;
+        int scale = getScalingFactor(elementKind);
+
+        if (location instanceof ConstantLocationNode) {
+            base = ((ConstantLocationNode) location).getDisplacement();
+            index = null;
+        } else if (location instanceof IndexedLocationNode) {
+            IndexedLocationNode indexedLocation = (IndexedLocationNode) location;
+            assert indexedLocation.getIndexScaling() == scale;
+            base = indexedLocation.getDisplacement();
+            index = indexedLocation.getIndex();
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+
+        base -= getArrayBaseOffset(elementKind);
+        assert base >= 0 && base % scale == 0;
+
+        base /= scale;
+        assert NumUtil.isInt(base);
+
+        if (index == null) {
+            return ConstantNode.forInt((int) base, location.graph());
+        } else {
+            if (base == 0) {
+                return index;
+            } else {
+                return IntegerArithmeticNode.add(ConstantNode.forInt((int) base, location.graph()), index);
+            }
+        }
+    }
+
+    private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
+        StructuredGraph g = n.graph();
+        ValueNode array = n.array();
+        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, runtime.getConfig().arrayLengthOffset, g), stamp, BarrierType.NONE, false));
+            g.addBeforeFixed(n, readArrayLength);
+            tool.createNullCheckGuard(readArrayLength, array);
+            arrayLength = readArrayLength;
+        }
+
+        return tool.createGuard(g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.*;
+
+/**
+ * HotSpot implementation of {@link MetaAccessProvider}.
+ */
+public class HotSpotMetaAccessProvider implements MetaAccessProvider {
+
+    protected final HotSpotGraalRuntime runtime;
+
+    public HotSpotMetaAccessProvider(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
+    }
+
+    public ResolvedJavaType lookupJavaType(Class<?> clazz) {
+        if (clazz == null) {
+            throw new IllegalArgumentException("Class parameter was null");
+        }
+        return HotSpotResolvedObjectType.fromClass(clazz);
+    }
+
+    public ResolvedJavaType lookupJavaType(Constant constant) {
+        if (constant.getKind() != Kind.Object || constant.isNull()) {
+            return null;
+        }
+        Object o = constant.asObject();
+        return HotSpotResolvedObjectType.fromClass(o.getClass());
+    }
+
+    public Signature parseMethodDescriptor(String signature) {
+        return new HotSpotSignature(signature);
+    }
+
+    public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) {
+        CompilerToVM c2vm = runtime.getCompilerToVM();
+        HotSpotResolvedObjectType[] resultHolder = {null};
+        long metaspaceMethod = c2vm.getMetaspaceMethod(reflectionMethod, resultHolder);
+        assert metaspaceMethod != 0L;
+        return resultHolder[0].createMethod(metaspaceMethod);
+    }
+
+    public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) {
+        CompilerToVM c2vm = runtime.getCompilerToVM();
+        HotSpotResolvedObjectType[] resultHolder = {null};
+        long metaspaceMethod = c2vm.getMetaspaceConstructor(reflectionConstructor, resultHolder);
+        assert metaspaceMethod != 0L;
+        return resultHolder[0].createMethod(metaspaceMethod);
+    }
+
+    public ResolvedJavaField lookupJavaField(Field reflectionField) {
+        return runtime.getCompilerToVM().getJavaField(reflectionField);
+    }
+
+    @Override
+    public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
+        final int actionShift = 0;
+        final int reasonShift = 3;
+
+        int actionValue = convertDeoptAction(action);
+        int reasonValue = convertDeoptReason(reason);
+        return Constant.forInt(~(((reasonValue) << reasonShift) + ((actionValue) << actionShift)));
+    }
+
+    public int convertDeoptAction(DeoptimizationAction action) {
+        switch (action) {
+            case None:
+                return runtime.getConfig().deoptActionNone;
+            case RecompileIfTooManyDeopts:
+                return runtime.getConfig().deoptActionMaybeRecompile;
+            case InvalidateReprofile:
+                return runtime.getConfig().deoptActionReinterpret;
+            case InvalidateRecompile:
+                return runtime.getConfig().deoptActionMakeNotEntrant;
+            case InvalidateStopCompiling:
+                return runtime.getConfig().deoptActionMakeNotCompilable;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    public int convertDeoptReason(DeoptimizationReason reason) {
+        switch (reason) {
+            case None:
+                return runtime.getConfig().deoptReasonNone;
+            case NullCheckException:
+                return runtime.getConfig().deoptReasonNullCheck;
+            case BoundsCheckException:
+                return runtime.getConfig().deoptReasonRangeCheck;
+            case ClassCastException:
+                return runtime.getConfig().deoptReasonClassCheck;
+            case ArrayStoreException:
+                return runtime.getConfig().deoptReasonArrayCheck;
+            case UnreachedCode:
+                return runtime.getConfig().deoptReasonUnreached0;
+            case TypeCheckedInliningViolated:
+                return runtime.getConfig().deoptReasonTypeCheckInlining;
+            case OptimizedTypeCheckViolated:
+                return runtime.getConfig().deoptReasonOptimizedTypeCheck;
+            case NotCompiledExceptionHandler:
+                return runtime.getConfig().deoptReasonNotCompiledExceptionHandler;
+            case Unresolved:
+                return runtime.getConfig().deoptReasonUnresolved;
+            case JavaSubroutineMismatch:
+                return runtime.getConfig().deoptReasonJsrMismatch;
+            case ArithmeticException:
+                return runtime.getConfig().deoptReasonDiv0Check;
+            case RuntimeConstraint:
+                return runtime.getConfig().deoptReasonConstraint;
+            case LoopLimitCheck:
+                return runtime.getConfig().deoptReasonLoopLimitCheck;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Wed Oct 16 18:27:28 2013 +0200
@@ -40,7 +40,7 @@
 
     private static final long serialVersionUID = -8873133496591225071L;
 
-    private static final HotSpotVMConfig config = graalRuntime().getConfig();
+    private static final HotSpotVMConfig config = runtime().getConfig();
     private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(TriState.FALSE);
     private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(TriState.UNKNOWN);
 
@@ -58,7 +58,7 @@
 
     HotSpotMethodData(long metaspaceMethodData) {
         this.metaspaceMethodData = metaspaceMethodData;
-        graalRuntime().getCompilerToVM().initializeMethodData(metaspaceMethodData, this);
+        runtime().getCompilerToVM().initializeMethodData(metaspaceMethodData, this);
     }
 
     public boolean hasNormalData() {
@@ -78,7 +78,7 @@
     }
 
     public int getDeoptimizationCount(DeoptimizationReason reason) {
-        int reasonIndex = graalRuntime().getRuntime().convertDeoptReason(reason);
+        int reasonIndex = runtime().getProviders().getMetaAccess().convertDeoptReason(reason);
         return unsafe.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Wed Oct 16 18:27:28 2013 +0200
@@ -79,7 +79,7 @@
 
     @Override
     public void invalidate() {
-        graalRuntime().getCompilerToVM().invalidateInstalledCode(this);
+        runtime().getCompilerToVM().invalidateInstalledCode(this);
     }
 
     @Override
@@ -120,7 +120,7 @@
 
         assert isExternal(); // for now
 
-        return graalRuntime().getCompilerToGPU().executeParallelMethodVarargs(dimX, dimY, dimZ, args, this);
+        return runtime().getCompilerToGPU().executeParallelMethodVarargs(dimX, dimY, dimZ, args, this);
 
     }
 
@@ -128,9 +128,9 @@
     public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
         assert checkArgs(args);
         if (isExternal()) {
-            return graalRuntime().getCompilerToGPU().executeExternalMethodVarargs(args, this);
+            return runtime().getCompilerToGPU().executeExternalMethodVarargs(args, this);
         } else {
-            return graalRuntime().getCompilerToVM().executeCompiledMethodVarargs(args, this);
+            return runtime().getCompilerToVM().executeCompiledMethodVarargs(args, this);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
+
+/**
+ * Extends {@link Providers} to include a number of extra capabilities used by the HotSpot parts of
+ * the compiler.
+ */
+public class HotSpotProviders extends Providers {
+
+    private final HotSpotDisassemblerProvider disassembler;
+    private final HotSpotSuitesProvider suites;
+    private final HotSpotRegistersProvider registers;
+
+    public HotSpotProviders(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls,
+                    LoweringProvider lowerer, Replacements replacements, HotSpotDisassemblerProvider disassembler, HotSpotSuitesProvider suites, HotSpotRegistersProvider registers) {
+        super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements);
+        this.disassembler = disassembler;
+        this.suites = suites;
+        this.registers = registers;
+    }
+
+    @Override
+    public HotSpotCodeCacheProvider getCodeCache() {
+        return (HotSpotCodeCacheProvider) super.getCodeCache();
+    }
+
+    @Override
+    public HotSpotMetaAccessProvider getMetaAccess() {
+        return (HotSpotMetaAccessProvider) super.getMetaAccess();
+    }
+
+    public HotSpotDisassemblerProvider getDisassembler() {
+        return disassembler;
+    }
+
+    public BytecodeDisassemblerProvider getBytecodeDisassembler() {
+        return new BytecodeDisassembler();
+    }
+
+    @Override
+    public HotSpotForeignCallsProvider getForeignCalls() {
+        return (HotSpotForeignCallsProvider) super.getForeignCalls();
+    }
+
+    public HotSpotSuitesProvider getSuites() {
+        return suites;
+    }
+
+    public HotSpotRegistersProvider getRegisters() {
+        return registers;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegisters.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.code.*;
+
+public class HotSpotRegisters implements HotSpotRegistersProvider {
+
+    private final Register threadRegister;
+    private final Register heapBaseRegister;
+    private final Register stackPointerRegister;
+
+    public HotSpotRegisters(Register threadRegister, Register heapBaseRegister, Register stackPointerRegister) {
+        this.threadRegister = threadRegister;
+        this.heapBaseRegister = heapBaseRegister;
+        this.stackPointerRegister = stackPointerRegister;
+    }
+
+    public Register getThreadRegister() {
+        return threadRegister;
+    }
+
+    public Register getHeapBaseRegister() {
+        return heapBaseRegister;
+    }
+
+    public Register getStackPointerRegister() {
+        return stackPointerRegister;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegistersProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import com.oracle.graal.api.code.*;
+
+/**
+ * Special registers reserved by HotSpot for frequently used values.
+ */
+public interface HotSpotRegistersProvider {
+
+    /**
+     * Gets the register holding the current thread.
+     */
+    Register getThreadRegister();
+
+    /**
+     * Gets the register holding the heap base address for compressed pointers.
+     */
+    Register getHeapBaseRegister();
+
+    /**
+     * Gets the stack pointer register.
+     */
+    Register getStackPointerRegister();
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed Oct 16 18:27:28 2013 +0200
@@ -20,7 +20,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package com.oracle.graal.hotspot.meta;
 
 import static com.oracle.graal.api.meta.MetaUtil.*;
@@ -93,14 +92,13 @@
      * only called for snippets or replacements.
      */
     private static boolean isCalledForSnippets() {
-        HotSpotRuntime runtime = graalRuntime().getRuntime();
-
+        MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess();
         ResolvedJavaMethod makeGraphMethod = null;
         ResolvedJavaMethod initMethod = null;
         try {
             Class<?> rjm = ResolvedJavaMethod.class;
-            makeGraphMethod = runtime.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class, boolean.class));
-            initMethod = runtime.lookupJavaMethod(SnippetTemplate.AbstractTemplates.class.getDeclaredMethod("template", Arguments.class));
+            makeGraphMethod = metaAccess.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class, boolean.class));
+            initMethod = metaAccess.lookupJavaMethod(SnippetTemplate.AbstractTemplates.class.getDeclaredMethod("template", Arguments.class));
         } catch (NoSuchMethodException | SecurityException e) {
             throw new GraalInternalError(e);
         }
@@ -121,8 +119,8 @@
     private static final Set<ResolvedJavaField> notEmbeddable = new HashSet<>();
 
     private static void addResolvedToSet(Field field) {
-        HotSpotRuntime runtime = graalRuntime().getRuntime();
-        notEmbeddable.add(runtime.lookupJavaField(field));
+        MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess();
+        notEmbeddable.add(metaAccess.lookupJavaField(field));
     }
 
     static {
@@ -218,12 +216,12 @@
         if (receiver == null) {
             assert Modifier.isStatic(flags);
             if (holder.isInitialized()) {
-                return graalRuntime().getRuntime().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object);
+                return runtime().getProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object);
             }
             return null;
         } else {
             assert !Modifier.isStatic(flags);
-            return graalRuntime().getRuntime().readUnsafeConstant(getKind(), receiver.asObject(), offset, getKind() == Kind.Object);
+            return runtime().getProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver.asObject(), offset, getKind() == Kind.Object);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Wed Oct 16 18:27:28 2013 +0200
@@ -73,7 +73,7 @@
      *         {@code metaspaceMethod}
      */
     public static HotSpotResolvedObjectType getHolder(long metaspaceMethod) {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         long constMethod = unsafe.getLong(metaspaceMethod + config.methodConstMethodOffset);
         assert constMethod != 0;
         long constantPool = unsafe.getLong(constMethod + config.constMethodConstantsOffset);
@@ -97,7 +97,7 @@
     HotSpotResolvedJavaMethod(HotSpotResolvedObjectType holder, long metaspaceMethod) {
         this.metaspaceMethod = metaspaceMethod;
         this.holder = holder;
-        graalRuntime().getCompilerToVM().initializeMethod(metaspaceMethod, this);
+        runtime().getCompilerToVM().initializeMethod(metaspaceMethod, this);
     }
 
     @Override
@@ -113,7 +113,7 @@
      * Gets the address of the C++ Method object for this method.
      */
     public Constant getMetaspaceMethodConstant() {
-        return Constant.forIntegerKind(graalRuntime().getTarget().wordKind, metaspaceMethod, this);
+        return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceMethod, this);
     }
 
     @Override
@@ -123,7 +123,7 @@
 
     @Override
     public int getModifiers() {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         return unsafe.getInt(metaspaceMethod + config.methodAccessFlagsOffset) & Modifier.methodModifiers();
     }
 
@@ -138,8 +138,8 @@
         if (codeSize == 0) {
             return null;
         }
-        if (code == null && graalRuntime().getCompilerToVM().isTypeLinked(holder)) {
-            code = graalRuntime().getCompilerToVM().initializeBytecode(metaspaceMethod, new byte[codeSize]);
+        if (code == null && runtime().getCompilerToVM().isTypeLinked(holder)) {
+            code = runtime().getCompilerToVM().initializeBytecode(metaspaceMethod, new byte[codeSize]);
             assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length;
         }
         return code;
@@ -159,7 +159,7 @@
         for (int i = 0; i < exceptionHandlerCount; i++) {
             handlers[i] = new ExceptionHandler(-1, -1, -1, -1, null);
         }
-        return graalRuntime().getCompilerToVM().initializeExceptionHandlers(metaspaceMethod, handlers);
+        return runtime().getCompilerToVM().initializeExceptionHandlers(metaspaceMethod, handlers);
     }
 
     /**
@@ -201,7 +201,7 @@
 
     public boolean hasBalancedMonitors() {
         if (hasBalancedMonitors == null) {
-            hasBalancedMonitors = graalRuntime().getCompilerToVM().hasBalancedMonitors(metaspaceMethod);
+            hasBalancedMonitors = runtime().getCompilerToVM().hasBalancedMonitors(metaspaceMethod);
         }
         return hasBalancedMonitors;
     }
@@ -222,7 +222,7 @@
         if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
             return 0;
         }
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         long metaspaceConstMethod = unsafe.getLong(metaspaceMethod + config.methodConstMethodOffset);
         return unsafe.getShort(metaspaceConstMethod + config.methodMaxLocalsOffset) & 0xFFFF;
     }
@@ -233,7 +233,7 @@
         if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
             return 0;
         }
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         long metaspaceConstMethod = unsafe.getLong(metaspaceMethod + config.methodConstMethodOffset);
         return config.extraStackEntries + (unsafe.getShort(metaspaceConstMethod + config.constMethodMaxStackOffset) & 0xFFFF);
     }
@@ -242,15 +242,15 @@
     public StackTraceElement asStackTraceElement(int bci) {
         if (bci < 0 || bci >= codeSize) {
             // HotSpot code can only construct stack trace elements for valid bcis
-            StackTraceElement ste = graalRuntime().getCompilerToVM().getStackTraceElement(metaspaceMethod, 0);
+            StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, 0);
             return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
         }
-        return graalRuntime().getCompilerToVM().getStackTraceElement(metaspaceMethod, bci);
+        return runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, bci);
     }
 
     public ResolvedJavaMethod uniqueConcreteMethod() {
         HotSpotResolvedObjectType[] resultHolder = {null};
-        long ucm = graalRuntime().getCompilerToVM().getUniqueConcreteMethod(metaspaceMethod, resultHolder);
+        long ucm = runtime().getCompilerToVM().getUniqueConcreteMethod(metaspaceMethod, resultHolder);
         if (ucm != 0L) {
             assert resultHolder[0] != null;
             return resultHolder[0].createMethod(ucm);
@@ -261,13 +261,13 @@
     @Override
     public HotSpotSignature getSignature() {
         if (signature == null) {
-            signature = new HotSpotSignature(graalRuntime().getCompilerToVM().getSignature(metaspaceMethod));
+            signature = new HotSpotSignature(runtime().getCompilerToVM().getSignature(metaspaceMethod));
         }
         return signature;
     }
 
     public int getCompiledCodeSize() {
-        return graalRuntime().getCompilerToVM().getCompiledCodeSize(metaspaceMethod);
+        return runtime().getCompilerToVM().getCompiledCodeSize(metaspaceMethod);
     }
 
     public boolean hasCompiledCode() {
@@ -279,7 +279,7 @@
         ProfilingInfo info;
 
         if (UseProfilingInformation.getValue() && methodData == null) {
-            long metaspaceMethodData = unsafeReadWord(metaspaceMethod + graalRuntime().getConfig().methodDataOffset);
+            long metaspaceMethodData = unsafeReadWord(metaspaceMethod + runtime().getConfig().methodDataOffset);
             if (metaspaceMethodData != 0) {
                 methodData = new HotSpotMethodData(metaspaceMethodData);
             }
@@ -297,7 +297,7 @@
 
     @Override
     public void reprofile() {
-        graalRuntime().getCompilerToVM().reprofile(metaspaceMethod);
+        runtime().getCompilerToVM().reprofile(metaspaceMethod);
     }
 
     @Override
@@ -343,11 +343,11 @@
         // Cannot use toJava() as it ignores the return type
         HotSpotSignature sig = getSignature();
         JavaType[] sigTypes = MetaUtil.signatureToTypes(sig, null);
-        HotSpotRuntime runtime = graalRuntime().getRuntime();
+        MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess();
         for (Method method : holder.mirror().getDeclaredMethods()) {
             if (method.getName().equals(name)) {
-                if (runtime.lookupJavaType(method.getReturnType()).equals(sig.getReturnType(holder))) {
-                    if (matches(runtime, sigTypes, method.getParameterTypes())) {
+                if (metaAccess.lookupJavaType(method.getReturnType()).equals(sig.getReturnType(holder))) {
+                    if (matches(metaAccess, sigTypes, method.getParameterTypes())) {
                         return method.isSynthetic();
                     }
                 }
@@ -376,10 +376,10 @@
         return result;
     }
 
-    private static boolean matches(HotSpotRuntime runtime, JavaType[] sigTypes, Class<?>[] parameterTypes) {
+    private static boolean matches(MetaAccessProvider metaAccess, JavaType[] sigTypes, Class<?>[] parameterTypes) {
         if (parameterTypes.length == sigTypes.length) {
             for (int i = 0; i < parameterTypes.length; i++) {
-                if (!runtime.lookupJavaType(parameterTypes[i]).equals(sigTypes[i])) {
+                if (!metaAccess.lookupJavaType(parameterTypes[i]).equals(sigTypes[i])) {
                     return false;
                 }
             }
@@ -409,12 +409,12 @@
         if (dontInline) {
             return false;
         }
-        return graalRuntime().getCompilerToVM().isMethodCompilable(metaspaceMethod);
+        return runtime().getCompilerToVM().isMethodCompilable(metaspaceMethod);
     }
 
     @Override
     public LineNumberTable getLineNumberTable() {
-        long[] values = graalRuntime().getCompilerToVM().getLineNumberTable(this);
+        long[] values = runtime().getCompilerToVM().getLineNumberTable(this);
         if (values == null) {
             return null;
         }
@@ -432,7 +432,7 @@
 
     @Override
     public LocalVariableTable getLocalVariableTable() {
-        Local[] locals = graalRuntime().getCompilerToVM().getLocalVariableTable(this);
+        Local[] locals = runtime().getCompilerToVM().getLocalVariableTable(this);
         if (locals == null) {
             return null;
         }
@@ -449,12 +449,12 @@
         if (!isInVirtualMethodTable() || !holder.isInitialized()) {
             throw new GraalInternalError("%s does not have a vtable entry", this);
         }
-        return graalRuntime().getCompilerToVM().getVtableEntryOffset(metaspaceMethod);
+        return runtime().getCompilerToVM().getVtableEntryOffset(metaspaceMethod);
     }
 
     @Override
     public boolean isInVirtualMethodTable() {
-        return graalRuntime().getCompilerToVM().hasVtableEntry(metaspaceMethod);
+        return runtime().getCompilerToVM().hasVtableEntry(metaspaceMethod);
     }
 
     public void setCurrentTask(CompilationTask task) {
@@ -473,7 +473,7 @@
     }
 
     public int intrinsicId() {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         return unsafe.getByte(metaspaceMethod + config.methodIntrinsicIdOffset) & 0xff;
     }
 
@@ -526,11 +526,11 @@
         do {
             long address = getAccessFlagsAddress();
             int actualValue = unsafe.getInt(address);
-            int expectedValue = actualValue & ~graalRuntime().getConfig().methodQueuedForCompilationBit;
+            int expectedValue = actualValue & ~runtime().getConfig().methodQueuedForCompilationBit;
             if (actualValue != expectedValue) {
                 return false;
             } else {
-                int newValue = expectedValue | graalRuntime().getConfig().methodQueuedForCompilationBit;
+                int newValue = expectedValue | runtime().getConfig().methodQueuedForCompilationBit;
                 boolean success = unsafe.compareAndSwapInt(null, address, expectedValue, newValue);
                 if (success) {
                     return true;
@@ -544,17 +544,17 @@
         boolean success;
         do {
             int actualValue = unsafe.getInt(address);
-            int newValue = actualValue & ~graalRuntime().getConfig().methodQueuedForCompilationBit;
+            int newValue = actualValue & ~runtime().getConfig().methodQueuedForCompilationBit;
             assert isQueuedForCompilation() : "queued for compilation must be set";
             success = unsafe.compareAndSwapInt(null, address, actualValue, newValue);
         } while (!success);
     }
 
     public boolean isQueuedForCompilation() {
-        return (unsafe.getInt(getAccessFlagsAddress()) & graalRuntime().getConfig().methodQueuedForCompilationBit) != 0;
+        return (unsafe.getInt(getAccessFlagsAddress()) & runtime().getConfig().methodQueuedForCompilationBit) != 0;
     }
 
     private long getAccessFlagsAddress() {
-        return metaspaceMethod + graalRuntime().getConfig().methodAccessFlagsOffset;
+        return metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Wed Oct 16 18:27:28 2013 +0200
@@ -38,6 +38,6 @@
 
     @Override
     public String getSourceFileName() {
-        return graalRuntime().getCompilerToVM().getFileName(this);
+        return runtime().getCompilerToVM().getFileName(this);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Oct 16 18:27:28 2013 +0200
@@ -105,7 +105,7 @@
      */
     public static ResolvedJavaType fromMetaspaceKlass(long metaspaceKlass) {
         assert metaspaceKlass != 0;
-        Class javaClass = (Class) unsafe.getObject(null, metaspaceKlass + graalRuntime().getConfig().classMirrorOffset);
+        Class javaClass = (Class) runtime().getCompilerToVM().readUnsafeUncompressedPointer(null, metaspaceKlass + runtime().getConfig().classMirrorOffset);
         assert javaClass != null;
         return fromClass(javaClass);
     }
@@ -117,9 +117,9 @@
      */
     public static ResolvedJavaType fromClass(Class javaClass) {
         assert javaClass != null;
-        ResolvedJavaType type = (ResolvedJavaType) unsafe.getObject(javaClass, (long) graalRuntime().getConfig().graalMirrorInClassOffset);
+        ResolvedJavaType type = (ResolvedJavaType) unsafe.getObject(javaClass, (long) runtime().getConfig().graalMirrorInClassOffset);
         if (type == null) {
-            type = graalRuntime().getCompilerToVM().getResolvedType(javaClass);
+            type = runtime().getCompilerToVM().getResolvedType(javaClass);
             assert type != null;
         }
         return type;
@@ -147,7 +147,7 @@
     }
 
     public int getAccessFlags() {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         return unsafe.getInt(metaspaceKlass + config.klassAccessFlagsOffset);
     }
 
@@ -167,11 +167,11 @@
 
     @Override
     public ResolvedJavaType findUniqueConcreteSubtype() {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         if (isArray()) {
             return isFinal(getElementalType(this).getModifiers()) ? this : null;
         } else if (isInterface()) {
-            return graalRuntime().getCompilerToVM().getUniqueImplementor(this);
+            return runtime().getCompilerToVM().getUniqueImplementor(this);
         } else {
             HotSpotResolvedObjectType type = this;
             while (isAbstract(type.getModifiers())) {
@@ -265,12 +265,12 @@
     @Override
     public boolean hasFinalizableSubclass() {
         assert !isArray();
-        return graalRuntime().getCompilerToVM().hasFinalizableSubclass(this);
+        return runtime().getCompilerToVM().hasFinalizableSubclass(this);
     }
 
     @Override
     public boolean hasFinalizer() {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
     }
 
@@ -287,7 +287,7 @@
     @Override
     public boolean isInitialized() {
         if (!isInitialized) {
-            isInitialized = graalRuntime().getCompilerToVM().isTypeInitialized(this);
+            isInitialized = runtime().getCompilerToVM().isTypeInitialized(this);
         }
         return isInitialized;
     }
@@ -295,7 +295,7 @@
     @Override
     public boolean isLinked() {
         if (!isLinked) {
-            isLinked = graalRuntime().getCompilerToVM().isTypeLinked(this);
+            isLinked = runtime().getCompilerToVM().isTypeLinked(this);
         }
         return isLinked;
     }
@@ -303,8 +303,8 @@
     @Override
     public void initialize() {
         if (!isInitialized) {
-            graalRuntime().getCompilerToVM().initializeType(this);
-            assert graalRuntime().getCompilerToVM().isTypeInitialized(this);
+            runtime().getCompilerToVM().initializeType(this);
+            assert runtime().getCompilerToVM().isTypeInitialized(this);
         }
         isInitialized = true;
     }
@@ -345,7 +345,7 @@
     @Override
     public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method) {
         assert method instanceof HotSpotMethod;
-        ResolvedJavaMethod res = (ResolvedJavaMethod) graalRuntime().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).getMethodDescriptor());
+        ResolvedJavaMethod res = (ResolvedJavaMethod) runtime().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).getMethodDescriptor());
         if (res == null || isAbstract(res.getModifiers())) {
             return null;
         }
@@ -432,7 +432,7 @@
             if (isArray() || isInterface()) {
                 instanceFields = new HotSpotResolvedJavaField[0];
             } else {
-                HotSpotResolvedJavaField[] myFields = graalRuntime().getCompilerToVM().getInstanceFields(this);
+                HotSpotResolvedJavaField[] myFields = runtime().getCompilerToVM().getInstanceFields(this);
                 Arrays.sort(myFields, new OffsetComparator());
                 if (javaMirror != Object.class) {
                     HotSpotResolvedJavaField[] superFields = (HotSpotResolvedJavaField[]) getSuperclass().getInstanceFields(true);
@@ -468,7 +468,7 @@
 
     @Override
     public String getSourceFileName() {
-        return graalRuntime().getCompilerToVM().getFileName(this);
+        return runtime().getCompilerToVM().getFileName(this);
     }
 
     @Override
@@ -485,20 +485,20 @@
      * Gets the address of the C++ Klass object for this type.
      */
     public Constant klass() {
-        return Constant.forIntegerKind(graalRuntime().getTarget().wordKind, metaspaceKlass, this);
+        return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceKlass, this);
     }
 
     public boolean isPrimaryType() {
-        return graalRuntime().getConfig().secondarySuperCacheOffset != superCheckOffset();
+        return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset();
     }
 
     public int superCheckOffset() {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         return unsafe.getInt(metaspaceKlass + config.superCheckOffsetOffset);
     }
 
     public long prototypeMarkWord() {
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         if (isArray()) {
             return config.arrayPrototypeMarkWord;
         } else {
@@ -544,7 +544,7 @@
         Constructor[] constructors = javaMirror.getDeclaredConstructors();
         ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
         for (int i = 0; i < constructors.length; i++) {
-            result[i] = graalRuntime().getRuntime().lookupJavaConstructor(constructors[i]);
+            result[i] = runtime().getProviders().getMetaAccess().lookupJavaConstructor(constructors[i]);
             assert result[i].isConstructor();
         }
         return result;
@@ -555,14 +555,14 @@
         Method[] methods = javaMirror.getDeclaredMethods();
         ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length];
         for (int i = 0; i < methods.length; i++) {
-            result[i] = graalRuntime().getRuntime().lookupJavaMethod(methods[i]);
+            result[i] = runtime().getProviders().getMetaAccess().lookupJavaMethod(methods[i]);
             assert !result[i].isConstructor();
         }
         return result;
     }
 
     public ResolvedJavaMethod getClassInitializer() {
-        ResolvedJavaMethod[] methods = graalRuntime().getCompilerToVM().getMethods(this);
+        ResolvedJavaMethod[] methods = runtime().getCompilerToVM().getMethods(this);
         for (ResolvedJavaMethod m : methods) {
             if (m.isClassInitializer()) {
                 return m;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1294 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot.meta;
-
-import static com.oracle.graal.api.code.CallingConvention.Type.*;
-import static com.oracle.graal.api.code.MemoryBarriers.*;
-import static com.oracle.graal.api.meta.DeoptimizationAction.*;
-import static com.oracle.graal.api.meta.DeoptimizationReason.*;
-import static com.oracle.graal.api.meta.LocationIdentity.*;
-import static com.oracle.graal.graph.UnsafeAccess.*;
-import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*;
-import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*;
-import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*;
-import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*;
-import static com.oracle.graal.hotspot.nodes.VMErrorNode.*;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-import static com.oracle.graal.hotspot.replacements.MonitorSnippets.*;
-import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*;
-import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*;
-import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*;
-import static com.oracle.graal.hotspot.replacements.WriteBarrierSnippets.*;
-import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*;
-import static com.oracle.graal.hotspot.stubs.NewArrayStub.*;
-import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
-import static com.oracle.graal.hotspot.stubs.StubUtil.*;
-import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*;
-import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
-import static com.oracle.graal.nodes.java.ArrayLengthNode.*;
-import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*;
-import static com.oracle.graal.phases.GraalOptions.*;
-import static com.oracle.graal.replacements.Log.*;
-import static com.oracle.graal.replacements.MathSubstitutionsX86.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
-import com.oracle.graal.api.code.CompilationResult.Call;
-import com.oracle.graal.api.code.CompilationResult.DataPatch;
-import com.oracle.graal.api.code.CompilationResult.Infopoint;
-import com.oracle.graal.api.code.CompilationResult.Mark;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
-import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition;
-import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
-import com.oracle.graal.hotspot.debug.*;
-import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.hotspot.phases.*;
-import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.hotspot.stubs.*;
-import com.oracle.graal.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.HeapAccess.BarrierType;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.debug.*;
-import com.oracle.graal.nodes.extended.*;
-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.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 LoweringProvider}.
- */
-public abstract class HotSpotRuntime implements MetaAccessProvider, ForeignCallsProvider, 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);
-    public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class);
-    public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class);
-
-    public final HotSpotVMConfig config;
-
-    protected final RegisterConfig regConfig;
-    protected final HotSpotGraalRuntime graalRuntime;
-    private final Suites defaultSuites;
-
-    private CheckCastDynamicSnippets.Templates checkcastDynamicSnippets;
-    private InstanceOfSnippets.Templates instanceofSnippets;
-    private NewObjectSnippets.Templates newObjectSnippets;
-    private MonitorSnippets.Templates monitorSnippets;
-    protected WriteBarrierSnippets.Templates writeBarrierSnippets;
-    private BoxingSnippets.Templates boxingSnippets;
-    private LoadExceptionObjectSnippets.Templates exceptionObjectSnippets;
-    private UnsafeLoadSnippets.Templates unsafeLoadSnippets;
-
-    private final Map<ForeignCallDescriptor, HotSpotForeignCallLinkage> foreignCalls = new HashMap<>();
-
-    /**
-     * The offset from the origin of an array to the first element.
-     * 
-     * @return the offset in bytes
-     */
-    public static int getArrayBaseOffset(Kind kind) {
-        switch (kind) {
-            case Boolean:
-                return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
-            case Byte:
-                return Unsafe.ARRAY_BYTE_BASE_OFFSET;
-            case Char:
-                return Unsafe.ARRAY_CHAR_BASE_OFFSET;
-            case Short:
-                return Unsafe.ARRAY_SHORT_BASE_OFFSET;
-            case Int:
-                return Unsafe.ARRAY_INT_BASE_OFFSET;
-            case Long:
-                return Unsafe.ARRAY_LONG_BASE_OFFSET;
-            case Float:
-                return Unsafe.ARRAY_FLOAT_BASE_OFFSET;
-            case Double:
-                return Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
-            case Object:
-                return Unsafe.ARRAY_OBJECT_BASE_OFFSET;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    /**
-     * The scale used for the index when accessing elements of an array of this kind.
-     * 
-     * @return the scale in order to convert the index into a byte offset
-     */
-    public static int getArrayIndexScale(Kind kind) {
-        switch (kind) {
-            case Boolean:
-                return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
-            case Byte:
-                return Unsafe.ARRAY_BYTE_INDEX_SCALE;
-            case Char:
-                return Unsafe.ARRAY_CHAR_INDEX_SCALE;
-            case Short:
-                return Unsafe.ARRAY_SHORT_INDEX_SCALE;
-            case Int:
-                return Unsafe.ARRAY_INT_INDEX_SCALE;
-            case Long:
-                return Unsafe.ARRAY_LONG_INDEX_SCALE;
-            case Float:
-                return Unsafe.ARRAY_FLOAT_INDEX_SCALE;
-            case Double:
-                return Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
-            case Object:
-                return Unsafe.ARRAY_OBJECT_INDEX_SCALE;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public HotSpotRuntime(HotSpotVMConfig c, HotSpotGraalRuntime graalRuntime) {
-        this.config = c;
-        this.graalRuntime = graalRuntime;
-        regConfig = createRegisterConfig();
-        defaultSuites = createSuites();
-    }
-
-    protected abstract RegisterConfig createRegisterConfig();
-
-    /**
-     * Registers the linkage for a foreign call.
-     */
-    protected HotSpotForeignCallLinkage register(HotSpotForeignCallLinkage linkage) {
-        assert !foreignCalls.containsKey(linkage.getDescriptor()) : "already registered linkage for " + linkage.getDescriptor();
-        foreignCalls.put(linkage.getDescriptor(), linkage);
-        return linkage;
-    }
-
-    /**
-     * Creates and registers the details for linking a foreign call to a {@link Stub}.
-     * 
-     * @param descriptor the signature of the call to the stub
-     * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side
-     *            effects. Deoptimization will not return to a point before a stub call that cannot
-     *            be re-executed.
-     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
-     * @param killedLocations the memory locations killed by the stub call
-     */
-    protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) {
-        return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
-    }
-
-    /**
-     * Creates and registers the linkage for a foreign call.
-     * 
-     * @param descriptor the signature of the foreign call
-     * @param address the address of the code to call
-     * @param outgoingCcType outgoing (caller) calling convention type
-     * @param effect specifies if the call destroys or preserves all registers (apart from
-     *            temporaries which are always destroyed)
-     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
-     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
-     *            side effects. Deoptimization will not return to a point before a foreign call that
-     *            cannot be re-executed.
-     * @param killedLocations the memory locations killed by the foreign call
-     */
-    protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type outgoingCcType, RegisterEffect effect, Transition transition,
-                    boolean reexecutable, LocationIdentity... killedLocations) {
-        Class<?> resultType = descriptor.getResultType();
-        assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor;
-        return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, outgoingCcType, null, transition, reexecutable, killedLocations));
-    }
-
-    private static void link(Stub stub) {
-        stub.getLinkage().setCompiledStub(stub);
-    }
-
-    /**
-     * Creates a {@linkplain ForeignCallStub stub} for a foreign call.
-     * 
-     * @param descriptor the signature of the call to the stub
-     * @param address the address of the foreign code to call
-     * @param prependThread true if the JavaThread value for the current thread is to be prepended
-     *            to the arguments for the call to {@code address}
-     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
-     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
-     *            side effects. Deoptimization will not return to a point before a foreign call that
-     *            cannot be re-executed.
-     * @param killedLocations the memory locations killed by the foreign call
-     */
-    private void linkForeignCall(Providers providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
-                    LocationIdentity... killedLocations) {
-        ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations);
-        HotSpotForeignCallLinkage linkage = stub.getLinkage();
-        HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage();
-        linkage.setCompiledStub(stub);
-        register(linkage);
-        register(targetLinkage);
-    }
-
-    public static final boolean PREPEND_THREAD = true;
-    public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD;
-
-    public static final boolean REEXECUTABLE = true;
-    public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE;
-
-    public static final LocationIdentity[] NO_LOCATIONS = {};
-
-    public void registerReplacements(Replacements r) {
-        HotSpotVMConfig c = config;
-        TargetDescription target = getTarget();
-
-        registerForeignCall(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-
-        registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-
-        registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        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);
-
-        Providers providers = new Providers(this, 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(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);
-        r.registerSubstitutions(ThreadSubstitutions.class);
-        r.registerSubstitutions(UnsafeSubstitutions.class);
-        r.registerSubstitutions(ClassSubstitutions.class);
-        r.registerSubstitutions(AESCryptSubstitutions.class);
-        r.registerSubstitutions(CipherBlockChainingSubstitutions.class);
-        r.registerSubstitutions(CRC32Substitutions.class);
-        r.registerSubstitutions(ReflectionSubstitutions.class);
-
-        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(providers, graalRuntime.getTarget()));
-    }
-
-    public HotSpotGraalRuntime getGraalRuntime() {
-        return graalRuntime;
-    }
-
-    /**
-     * Gets the register holding the current thread.
-     */
-    public abstract Register threadRegister();
-
-    /**
-     * Returns the register used by the runtime for maintaining the heap base address for compressed
-     * pointers.
-     */
-    public abstract Register heapBaseRegister();
-
-    /**
-     * Gets the stack pointer register.
-     */
-    public abstract Register stackPointerRegister();
-
-    @Override
-    public String disassemble(CompilationResult compResult, InstalledCode installedCode) {
-        byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode();
-        long start = installedCode == null ? 0L : installedCode.getStart();
-        TargetDescription target = graalRuntime.getTarget();
-        HexCodeFile hcf = new HexCodeFile(code, start, target.arch.getName(), target.wordSize * 8);
-        if (compResult != null) {
-            HexCodeFile.addAnnotations(hcf, compResult.getAnnotations());
-            addExceptionHandlersComment(compResult, hcf);
-            Register fp = regConfig.getFrameRegister();
-            RefMapFormatter slotFormatter = new RefMapFormatter(target.arch, target.wordSize, fp, 0);
-            for (Infopoint infopoint : compResult.getInfopoints()) {
-                if (infopoint instanceof Call) {
-                    Call call = (Call) infopoint;
-                    if (call.debugInfo != null) {
-                        hcf.addComment(call.pcOffset + call.size, CodeUtil.append(new StringBuilder(100), call.debugInfo, slotFormatter).toString());
-                    }
-                    addOperandComment(hcf, call.pcOffset, "{" + getTargetName(call) + "}");
-                } else {
-                    if (infopoint.debugInfo != null) {
-                        hcf.addComment(infopoint.pcOffset, CodeUtil.append(new StringBuilder(100), infopoint.debugInfo, slotFormatter).toString());
-                    }
-                    addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}");
-                }
-            }
-            for (DataPatch site : compResult.getDataReferences()) {
-                hcf.addOperandComment(site.pcOffset, "{" + site.getDataString() + "}");
-            }
-            for (Mark mark : compResult.getMarks()) {
-                hcf.addComment(mark.pcOffset, getMarkName(mark));
-            }
-        }
-        return hcf.toEmbeddedString();
-    }
-
-    /**
-     * Decodes a call target to a mnemonic if possible.
-     */
-    private String getTargetName(Call call) {
-        Field[] fields = config.getClass().getDeclaredFields();
-        for (Field f : fields) {
-            if (f.getName().endsWith("Stub")) {
-                f.setAccessible(true);
-                try {
-                    Object address = f.get(config);
-                    if (address.equals(call.target)) {
-                        return f.getName() + ":0x" + Long.toHexString((Long) address);
-                    }
-                } catch (Exception e) {
-                }
-            }
-        }
-        return String.valueOf(call.target);
-    }
-
-    /**
-     * Decodes a mark to a mnemonic if possible.
-     */
-    private static String getMarkName(Mark mark) {
-        Field[] fields = Marks.class.getDeclaredFields();
-        for (Field f : fields) {
-            if (Modifier.isStatic(f.getModifiers()) && f.getName().startsWith("MARK_")) {
-                f.setAccessible(true);
-                try {
-                    if (f.get(null).equals(mark.id)) {
-                        return f.getName();
-                    }
-                } catch (Exception e) {
-                }
-            }
-        }
-        return "MARK:" + mark.id;
-    }
-
-    private static void addExceptionHandlersComment(CompilationResult compResult, HexCodeFile hcf) {
-        if (!compResult.getExceptionHandlers().isEmpty()) {
-            String nl = HexCodeFile.NEW_LINE;
-            StringBuilder buf = new StringBuilder("------ Exception Handlers ------").append(nl);
-            for (CompilationResult.ExceptionHandler e : compResult.getExceptionHandlers()) {
-                buf.append("    ").append(e.pcOffset).append(" -> ").append(e.handlerPos).append(nl);
-                hcf.addComment(e.pcOffset, "[exception -> " + e.handlerPos + "]");
-                hcf.addComment(e.handlerPos, "[exception handler for " + e.pcOffset + "]");
-            }
-            hcf.addComment(0, buf.toString());
-        }
-    }
-
-    private static void addOperandComment(HexCodeFile hcf, int pos, String comment) {
-        String oldValue = hcf.addOperandComment(pos, comment);
-        assert oldValue == null : "multiple comments for operand of instruction at " + pos + ": " + comment + ", " + oldValue;
-    }
-
-    @Override
-    public ResolvedJavaType lookupJavaType(Constant constant) {
-        if (constant.getKind() != Kind.Object || constant.isNull()) {
-            return null;
-        }
-        Object o = constant.asObject();
-        return HotSpotResolvedObjectType.fromClass(o.getClass());
-    }
-
-    @Override
-    public Signature parseMethodDescriptor(String signature) {
-        return new HotSpotSignature(signature);
-    }
-
-    @Override
-    public boolean constantEquals(Constant x, Constant y) {
-        return x.equals(y);
-    }
-
-    @Override
-    public RegisterConfig getRegisterConfig() {
-        return regConfig;
-    }
-
-    @Override
-    public int getMinimumOutgoingSize() {
-        return config.runtimeCallStackSize;
-    }
-
-    @Override
-    public Integer lookupArrayLength(Constant array) {
-        if (array.getKind() != Kind.Object || array.isNull() || !array.asObject().getClass().isArray()) {
-            return null;
-        }
-        return Array.getLength(array.asObject());
-    }
-
-    public boolean useCompressedOops() {
-        return config.useCompressedOops;
-    }
-
-    public boolean useCompressedKlassPointers() {
-        return config.useCompressedClassPointers;
-    }
-
-    @Override
-    public void lower(Node n, LoweringTool tool) {
-        StructuredGraph graph = (StructuredGraph) n.graph();
-        Kind wordKind = graalRuntime.getTarget().wordKind;
-        if (n instanceof ArrayLengthNode) {
-            ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n;
-            ValueNode array = arrayLengthNode.array();
-            ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt(),
-                            BarrierType.NONE, false));
-            tool.createNullCheckGuard(arrayLengthRead, array);
-            graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead);
-        } else if (n instanceof Invoke) {
-            Invoke invoke = (Invoke) n;
-            if (invoke.callTarget() instanceof MethodCallTargetNode) {
-
-                MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
-                NodeInputList<ValueNode> parameters = callTarget.arguments();
-                ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0);
-                GuardingNode receiverNullCheck = null;
-                if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !ObjectStamp.isObjectNonNull(receiver)) {
-                    receiverNullCheck = tool.createNullCheckGuard(invoke, receiver);
-                }
-                JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass());
-
-                LoweredCallTargetNode loweredCallTarget = null;
-                if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) {
-
-                    HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod();
-                    if (!hsMethod.getDeclaringClass().isInterface()) {
-                        if (hsMethod.isInVirtualMethodTable()) {
-                            int vtableEntryOffset = hsMethod.vtableEntryOffset();
-                            assert vtableEntryOffset > 0;
-                            FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck);
-
-                            ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod);
-                            // We use LocationNode.ANY_LOCATION for the reads that access the
-                            // compiled code entry as HotSpot does not guarantee they are final
-                            // values.
-                            ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph),
-                                            StampFactory.forKind(wordKind()), BarrierType.NONE, false));
-
-                            loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(),
-                                            CallingConvention.Type.JavaCall));
-
-                            graph.addBeforeFixed(invoke.asNode(), metaspaceMethod);
-                            graph.addAfterFixed(metaspaceMethod, compiledEntry);
-                        }
-                    }
-                }
-
-                if (loweredCallTarget == null) {
-                    loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall,
-                                    callTarget.invokeKind()));
-                }
-                callTarget.replaceAndDelete(loweredCallTarget);
-            }
-        } else if (n instanceof LoadFieldNode) {
-            LoadFieldNode loadField = (LoadFieldNode) n;
-            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field();
-            ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object();
-            assert loadField.kind() != Kind.Illegal;
-            BarrierType barrierType = getFieldLoadBarrierType(field);
-            ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object)));
-            graph.replaceFixedWithFixed(loadField, memoryRead);
-            tool.createNullCheckGuard(memoryRead, object);
-
-            if (loadField.isVolatile()) {
-                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ));
-                graph.addBeforeFixed(memoryRead, preMembar);
-                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ));
-                graph.addAfterFixed(memoryRead, postMembar);
-            }
-        } else if (n instanceof StoreFieldNode) {
-            StoreFieldNode storeField = (StoreFieldNode) n;
-            HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field();
-            ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object();
-            BarrierType barrierType = getFieldStoreBarrierType(storeField);
-            WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object));
-            tool.createNullCheckGuard(memoryWrite, object);
-            memoryWrite.setStateAfter(storeField.stateAfter());
-            graph.replaceFixedWithFixed(storeField, memoryWrite);
-            FixedWithNextNode last = memoryWrite;
-            FixedWithNextNode first = memoryWrite;
-
-            if (storeField.isVolatile()) {
-                MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE));
-                graph.addBeforeFixed(first, preMembar);
-                MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE));
-                graph.addAfterFixed(last, postMembar);
-            }
-        } else if (n instanceof CompareAndSwapNode) {
-            // Separate out GC barrier semantics
-            CompareAndSwapNode cas = (CompareAndSwapNode) n;
-            LocationNode location = IndexedLocationNode.create(ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1);
-            LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas),
-                            cas.expected().kind() == Kind.Object));
-            atomicNode.setStateAfter(cas.stateAfter());
-            graph.replaceFixedWithFixed(cas, atomicNode);
-        } else if (n instanceof LoadIndexedNode) {
-            LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
-            GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool);
-            Kind elementKind = loadIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false);
-            ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object));
-            memoryRead.setGuard(boundsCheck);
-            graph.replaceFixedWithFixed(loadIndexed, memoryRead);
-        } else if (n instanceof StoreIndexedNode) {
-            StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
-            GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool);
-            Kind elementKind = storeIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false);
-            ValueNode value = storeIndexed.value();
-            ValueNode array = storeIndexed.array();
-
-            CheckCastNode checkcastNode = null;
-            CheckCastDynamicNode checkcastDynamicNode = null;
-            if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) {
-                // Store check!
-                ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array);
-                if (arrayType != null && ObjectStamp.isExactType(array)) {
-                    ResolvedJavaType elementType = arrayType.getComponentType();
-                    if (!MetaUtil.isJavaLangObject(elementType)) {
-                        checkcastNode = graph.add(new CheckCastNode(elementType, value, null, true));
-                        graph.addBeforeFixed(storeIndexed, checkcastNode);
-                        value = checkcastNode;
-                    }
-                } else {
-                    FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck);
-                    LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph);
-                    /*
-                     * Anchor the read of the element klass to the cfg, because it is only valid
-                     * when arrayClass is an object class, which might not be the case in other
-                     * parts of the compiled method.
-                     */
-                    FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind()), BeginNode.prevBegin(storeIndexed)));
-                    checkcastDynamicNode = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true));
-                    graph.addBeforeFixed(storeIndexed, checkcastDynamicNode);
-                    value = checkcastDynamicNode;
-                }
-            }
-            BarrierType barrierType = getArrayStoreBarrierType(storeIndexed);
-            WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object));
-            memoryWrite.setGuard(boundsCheck);
-            memoryWrite.setStateAfter(storeIndexed.stateAfter());
-            graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
-
-            // Lower the associated checkcast node.
-            if (checkcastNode != null) {
-                checkcastNode.lower(tool);
-            } else if (checkcastDynamicNode != null) {
-                checkcastDynamicSnippets.lower(checkcastDynamicNode);
-            }
-        } else if (n instanceof UnsafeLoadNode) {
-            UnsafeLoadNode load = (UnsafeLoadNode) n;
-            if (load.getGuardingCondition() != null) {
-                boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
-                ConditionAnchorNode valueAnchorNode = graph.add(new ConditionAnchorNode(load.getGuardingCondition()));
-                LocationNode location = createLocation(load);
-                ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), valueAnchorNode, BarrierType.NONE, compressible));
-                load.replaceAtUsages(memoryRead);
-                graph.replaceFixedWithFixed(load, valueAnchorNode);
-                graph.addAfterFixed(valueAnchorNode, memoryRead);
-            } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) {
-                assert load.kind() != Kind.Illegal;
-                boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object);
-                if (addReadBarrier(load)) {
-                    unsafeLoadSnippets.lower(load, tool);
-                } else {
-                    LocationNode location = createLocation(load);
-                    ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible));
-                    // An unsafe read must not float outside its block otherwise
-                    // it may float above an explicit null check on its object.
-                    memoryRead.setGuard(AbstractBeginNode.prevBegin(load));
-                    graph.replaceFixedWithFixed(load, memoryRead);
-                }
-            }
-        } else if (n instanceof UnsafeStoreNode) {
-            UnsafeStoreNode store = (UnsafeStoreNode) n;
-            LocationNode location = createLocation(store);
-            ValueNode object = store.object();
-            BarrierType barrierType = getUnsafeStoreBarrierType(store);
-            WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object));
-            write.setStateAfter(store.stateAfter());
-            graph.replaceFixedWithFixed(store, write);
-        } else if (n instanceof LoadHubNode) {
-            LoadHubNode loadHub = (LoadHubNode) n;
-            assert loadHub.kind() == wordKind;
-            ValueNode object = loadHub.object();
-            GuardingNode guard = loadHub.getGuard();
-            FloatingReadNode hub = createReadHub(graph, wordKind, object, guard);
-            graph.replaceFloating(loadHub, hub);
-        } else if (n instanceof LoadMethodNode) {
-            LoadMethodNode loadMethodNode = (LoadMethodNode) n;
-            ResolvedJavaMethod method = loadMethodNode.getMethod();
-            ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, loadMethodNode.getHub(), method);
-            graph.replaceFixed(loadMethodNode, metaspaceMethod);
-        } else if (n instanceof StoreHubNode) {
-            StoreHubNode storeHub = (StoreHubNode) n;
-            WriteNode hub = createWriteHub(graph, wordKind, storeHub.getObject(), storeHub.getValue());
-            graph.replaceFixed(storeHub, hub);
-        } else if (n instanceof CommitAllocationNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                CommitAllocationNode commit = (CommitAllocationNode) n;
-
-                ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
-                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
-                    int entryCount = virtual.entryCount();
-
-                    FixedWithNextNode newObject;
-                    if (virtual instanceof VirtualInstanceNode) {
-                        newObject = graph.add(new NewInstanceNode(virtual.type(), true));
-                    } else {
-                        ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType();
-                        newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true));
-                    }
-                    graph.addBeforeFixed(commit, newObject);
-                    allocations[objIndex] = newObject;
-                }
-                int valuePos = 0;
-                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                    VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
-                    int entryCount = virtual.entryCount();
-
-                    ValueNode newObject = allocations[objIndex];
-                    if (virtual instanceof VirtualInstanceNode) {
-                        VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
-                        for (int i = 0; i < entryCount; i++) {
-                            ValueNode value = commit.getValues().get(valuePos++);
-                            if (value instanceof VirtualObjectNode) {
-                                value = allocations[commit.getVirtualObjects().indexOf(value)];
-                            }
-                            if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true),
-                                                (virtualInstance.field(i).getKind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.IMPRECISE : BarrierType.NONE,
-                                                virtualInstance.field(i).getKind() == Kind.Object);
-                                graph.addBeforeFixed(commit, graph.add(write));
-                            }
-                        }
-
-                    } else {
-                        VirtualArrayNode array = (VirtualArrayNode) virtual;
-                        ResolvedJavaType element = array.componentType();
-                        for (int i = 0; i < entryCount; i++) {
-                            ValueNode value = commit.getValues().get(valuePos++);
-                            if (value instanceof VirtualObjectNode) {
-                                int indexOf = commit.getVirtualObjects().indexOf(value);
-                                assert indexOf != -1 : commit + " " + value;
-                                value = allocations[indexOf];
-                            }
-                            if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph), true),
-                                                (value.kind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object);
-                                graph.addBeforeFixed(commit, graph.add(write));
-                            }
-                        }
-                    }
-                }
-                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                    FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex]));
-                    allocations[objIndex] = anchor;
-                    graph.addBeforeFixed(commit, anchor);
-                }
-                for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
-                    for (int lockDepth : commit.getLocks().get(objIndex)) {
-                        MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth));
-                        graph.addBeforeFixed(commit, enter);
-                        enter.lower(tool);
-                    }
-                }
-                for (Node usage : commit.usages().snapshot()) {
-                    AllocatedObjectNode addObject = (AllocatedObjectNode) usage;
-                    int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject());
-                    graph.replaceFloating(addObject, allocations[index]);
-                }
-                graph.removeFixed(commit);
-            }
-        } else if (n instanceof OSRStartNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                OSRStartNode osrStart = (OSRStartNode) n;
-                StartNode newStart = graph.add(new StartNode());
-                LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind())));
-                ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(this, OSR_MIGRATION_END, buffer));
-                migrationEnd.setStateAfter(osrStart.stateAfter());
-
-                newStart.setNext(migrationEnd);
-                FixedNode next = osrStart.next();
-                osrStart.setNext(null);
-                migrationEnd.setNext(next);
-                graph.setStart(newStart);
-
-                // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block)
-                int localsOffset = (graph.method().getMaxLocals() - 1) * 8;
-                for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) {
-                    int size = FrameStateBuilder.stackSlots(osrLocal.kind());
-                    int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
-                    IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1);
-                    ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false));
-                    osrLocal.replaceAndDelete(load);
-                    graph.addBeforeFixed(migrationEnd, load);
-                }
-                osrStart.replaceAtUsages(newStart);
-                osrStart.safeDelete();
-            }
-        } else if (n instanceof DynamicCounterNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
-                BenchmarkCounters.lower((DynamicCounterNode) n, this);
-            }
-        } else if (n instanceof CheckCastDynamicNode) {
-            checkcastDynamicSnippets.lower((CheckCastDynamicNode) n);
-        } else if (n instanceof InstanceOfNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                instanceofSnippets.lower((InstanceOfNode) n, tool);
-            }
-        } else if (n instanceof InstanceOfDynamicNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                instanceofSnippets.lower((InstanceOfDynamicNode) n, tool);
-            }
-        } else if (n instanceof NewInstanceNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
-                newObjectSnippets.lower((NewInstanceNode) n);
-            }
-        } else if (n instanceof NewArrayNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
-                newObjectSnippets.lower((NewArrayNode) n);
-            }
-        } else if (n instanceof DynamicNewArrayNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
-                newObjectSnippets.lower((DynamicNewArrayNode) n);
-            }
-        } else if (n instanceof MonitorEnterNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                monitorSnippets.lower((MonitorEnterNode) n, tool);
-            }
-        } else if (n instanceof MonitorExitNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-                monitorSnippets.lower((MonitorExitNode) n, tool);
-            }
-        } else if (n instanceof G1PreWriteBarrier) {
-            writeBarrierSnippets.lower((G1PreWriteBarrier) n, tool);
-        } else if (n instanceof G1PostWriteBarrier) {
-            writeBarrierSnippets.lower((G1PostWriteBarrier) n, tool);
-        } else if (n instanceof G1ReferentFieldReadBarrier) {
-            writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool);
-        } else if (n instanceof SerialWriteBarrier) {
-            writeBarrierSnippets.lower((SerialWriteBarrier) n, tool);
-        } else if (n instanceof SerialArrayRangeWriteBarrier) {
-            writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
-        } else if (n instanceof G1ArrayRangePreWriteBarrier) {
-            writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool);
-        } else if (n instanceof G1ArrayRangePostWriteBarrier) {
-            writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool);
-        } else if (n instanceof NewMultiArrayNode) {
-            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
-                newObjectSnippets.lower((NewMultiArrayNode) n);
-            }
-        } else if (n instanceof LoadExceptionObjectNode) {
-            exceptionObjectSnippets.lower((LoadExceptionObjectNode) n);
-        } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) {
-            // Nothing to do for division nodes. The HotSpot signal handler catches divisions by
-            // zero and the MIN_VALUE / -1 cases.
-        } else if (n instanceof BoxNode) {
-            boxingSnippets.lower((BoxNode) n, tool);
-        } else if (n instanceof UnboxNode) {
-            boxingSnippets.lower((UnboxNode) n, tool);
-        } else {
-            assert false : "Node implementing Lowerable not handled: " + n;
-            throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    private static LocationNode createLocation(UnsafeAccessNode access) {
-        ValueNode offset = access.offset();
-        if (offset.isConstant()) {
-            long offsetValue = offset.asConstant().asLong();
-            return ConstantLocationNode.create(access.getLocationIdentity(), access.accessKind(), offsetValue, access.graph());
-        }
-
-        long displacement = 0;
-        int indexScaling = 1;
-        if (offset instanceof IntegerAddNode) {
-            IntegerAddNode integerAddNode = (IntegerAddNode) offset;
-            if (integerAddNode.y() instanceof ConstantNode) {
-                displacement = integerAddNode.y().asConstant().asLong();
-                offset = integerAddNode.x();
-            }
-        }
-
-        if (offset instanceof LeftShiftNode) {
-            LeftShiftNode leftShiftNode = (LeftShiftNode) offset;
-            if (leftShiftNode.y() instanceof ConstantNode) {
-                long shift = leftShiftNode.y().asConstant().asLong();
-                if (shift >= 1 && shift <= 3) {
-                    if (shift == 1) {
-                        indexScaling = 2;
-                    } else if (shift == 2) {
-                        indexScaling = 4;
-                    } else {
-                        indexScaling = 8;
-                    }
-                    offset = leftShiftNode.x();
-                }
-            }
-        }
-
-        return IndexedLocationNode.create(access.getLocationIdentity(), access.accessKind(), displacement, offset, access.graph(), indexScaling);
-    }
-
-    private static boolean addReadBarrier(UnsafeLoadNode load) {
-        if (useG1GC() && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object &&
-                        !ObjectStamp.isObjectAlwaysNull(load.object())) {
-            ResolvedJavaType type = ObjectStamp.typeOrNull(load.object());
-            if (type != null && !type.isArray()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) {
-        HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
-        assert !hsMethod.getDeclaringClass().isInterface();
-        assert hsMethod.isInVirtualMethodTable();
-
-        int vtableEntryOffset = hsMethod.vtableEntryOffset();
-        assert vtableEntryOffset > 0;
-        // We use LocationNode.ANY_LOCATION for the reads that access the vtable
-        // entry as HotSpot does not guarantee that this is a final value.
-        ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind()), BarrierType.NONE, false));
-        return metaspaceMethod;
-    }
-
-    private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) {
-        LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph);
-        assert !object.isConstant() || object.asConstant().isNull();
-        return graph.unique(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind()), guard, BarrierType.NONE, useCompressedKlassPointers()));
-    }
-
-    private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) {
-        LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph);
-        assert !object.isConstant() || object.asConstant().isNull();
-        return graph.add(new WriteNode(object, value, location, BarrierType.NONE, useCompressedKlassPointers()));
-    }
-
-    private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) {
-        BarrierType barrierType = BarrierType.NONE;
-        if (config().useG1GC && loadField.getKind() == Kind.Object && loadField.getDeclaringClass().mirror() == java.lang.ref.Reference.class && loadField.getName().equals("referent")) {
-            barrierType = BarrierType.PRECISE;
-        }
-        return barrierType;
-    }
-
-    private static BarrierType getFieldStoreBarrierType(StoreFieldNode storeField) {
-        BarrierType barrierType = BarrierType.NONE;
-        if (storeField.field().getKind() == Kind.Object && !deferInitBarrier(storeField.object())) {
-            barrierType = BarrierType.IMPRECISE;
-        }
-        return barrierType;
-    }
-
-    private static BarrierType getArrayStoreBarrierType(StoreIndexedNode store) {
-        BarrierType barrierType = BarrierType.NONE;
-        if (store.elementKind() == Kind.Object && !deferInitBarrier(store.array())) {
-            barrierType = BarrierType.PRECISE;
-        }
-        return barrierType;
-    }
-
-    private static boolean deferInitBarrier(ValueNode object) {
-        return useDeferredInitBarriers() && (object instanceof NewInstanceNode || object instanceof NewArrayNode);
-    }
-
-    private static BarrierType getUnsafeStoreBarrierType(UnsafeStoreNode store) {
-        BarrierType barrierType = BarrierType.NONE;
-        if (store.value().kind() == Kind.Object) {
-            ResolvedJavaType type = ObjectStamp.typeOrNull(store.object());
-            if (type != null && !type.isArray()) {
-                barrierType = BarrierType.IMPRECISE;
-            } else {
-                barrierType = BarrierType.PRECISE;
-            }
-        }
-        return barrierType;
-    }
-
-    private static BarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) {
-        BarrierType barrierType = BarrierType.NONE;
-        if (cas.expected().kind() == Kind.Object) {
-            ResolvedJavaType type = ObjectStamp.typeOrNull(cas.object());
-            if (type != null && !type.isArray()) {
-                barrierType = BarrierType.IMPRECISE;
-            } else {
-                barrierType = BarrierType.PRECISE;
-            }
-        }
-        return barrierType;
-    }
-
-    protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field, boolean initialization) {
-        LocationIdentity loc = initialization ? INIT_LOCATION : field;
-        return ConstantLocationNode.create(loc, field.getKind(), field.offset(), graph);
-    }
-
-    public int getScalingFactor(Kind kind) {
-        if (useCompressedOops() && kind == Kind.Object) {
-            return this.graalRuntime.getTarget().arch.getSizeInBytes(Kind.Int);
-        } else {
-            return this.graalRuntime.getTarget().arch.getSizeInBytes(kind);
-        }
-    }
-
-    protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) {
-        LocationIdentity loc = initialization ? INIT_LOCATION : NamedLocationIdentity.getArrayLocation(elementKind);
-        int scale = getScalingFactor(elementKind);
-        return IndexedLocationNode.create(loc, elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
-    }
-
-    @Override
-    public ValueNode reconstructArrayIndex(LocationNode location) {
-        Kind elementKind = location.getValueKind();
-        assert location.getLocationIdentity().equals(NamedLocationIdentity.getArrayLocation(elementKind));
-
-        long base;
-        ValueNode index;
-        int scale = getScalingFactor(elementKind);
-
-        if (location instanceof ConstantLocationNode) {
-            base = ((ConstantLocationNode) location).getDisplacement();
-            index = null;
-        } else if (location instanceof IndexedLocationNode) {
-            IndexedLocationNode indexedLocation = (IndexedLocationNode) location;
-            assert indexedLocation.getIndexScaling() == scale;
-            base = indexedLocation.getDisplacement();
-            index = indexedLocation.getIndex();
-        } else {
-            throw GraalInternalError.shouldNotReachHere();
-        }
-
-        base -= getArrayBaseOffset(elementKind);
-        assert base >= 0 && base % scale == 0;
-
-        base /= scale;
-        assert NumUtil.isInt(base);
-
-        if (index == null) {
-            return ConstantNode.forInt((int) base, location.graph());
-        } else {
-            if (base == 0) {
-                return index;
-            } else {
-                return IntegerArithmeticNode.add(ConstantNode.forInt((int) base, location.graph()), index);
-            }
-        }
-    }
-
-    private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
-        StructuredGraph g = n.graph();
-        ValueNode array = n.array();
-        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));
-            g.addBeforeFixed(n, readArrayLength);
-            tool.createNullCheckGuard(readArrayLength, array);
-            arrayLength = readArrayLength;
-        }
-
-        return tool.createGuard(g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile);
-    }
-
-    public ResolvedJavaType lookupJavaType(Class<?> clazz) {
-        if (clazz == null) {
-            throw new IllegalArgumentException("Class parameter was null");
-        }
-        return HotSpotResolvedObjectType.fromClass(clazz);
-    }
-
-    public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
-        HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor);
-        assert foreignCalls != null : descriptor;
-        callTarget.finalizeAddress(graalRuntime.getBackend());
-        return callTarget;
-    }
-
-    public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) {
-        CompilerToVM c2vm = graalRuntime.getCompilerToVM();
-        HotSpotResolvedObjectType[] resultHolder = {null};
-        long metaspaceMethod = c2vm.getMetaspaceMethod(reflectionMethod, resultHolder);
-        assert metaspaceMethod != 0L;
-        return resultHolder[0].createMethod(metaspaceMethod);
-    }
-
-    public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) {
-        CompilerToVM c2vm = graalRuntime.getCompilerToVM();
-        HotSpotResolvedObjectType[] resultHolder = {null};
-        long metaspaceMethod = c2vm.getMetaspaceConstructor(reflectionConstructor, resultHolder);
-        assert metaspaceMethod != 0L;
-        return resultHolder[0].createMethod(metaspaceMethod);
-    }
-
-    public ResolvedJavaField lookupJavaField(Field reflectionField) {
-        return graalRuntime.getCompilerToVM().getJavaField(reflectionField);
-    }
-
-    public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
-        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) {
-        HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false);
-        CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null);
-        if (result != CodeInstallResult.OK) {
-            return null;
-        }
-        return code;
-    }
-
-    public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
-
-        HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
-        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);
-        if (result != CodeInstallResult.OK) {
-            return null;
-        }
-        return icode;
-    }
-
-    @Override
-    public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
-        final int actionShift = 0;
-        final int reasonShift = 3;
-
-        int actionValue = convertDeoptAction(action);
-        int reasonValue = convertDeoptReason(reason);
-        return Constant.forInt(~(((reasonValue) << reasonShift) + ((actionValue) << actionShift)));
-    }
-
-    public int convertDeoptAction(DeoptimizationAction action) {
-        switch (action) {
-            case None:
-                return config.deoptActionNone;
-            case RecompileIfTooManyDeopts:
-                return config.deoptActionMaybeRecompile;
-            case InvalidateReprofile:
-                return config.deoptActionReinterpret;
-            case InvalidateRecompile:
-                return config.deoptActionMakeNotEntrant;
-            case InvalidateStopCompiling:
-                return config.deoptActionMakeNotCompilable;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public int convertDeoptReason(DeoptimizationReason reason) {
-        switch (reason) {
-            case None:
-                return config.deoptReasonNone;
-            case NullCheckException:
-                return config.deoptReasonNullCheck;
-            case BoundsCheckException:
-                return config.deoptReasonRangeCheck;
-            case ClassCastException:
-                return config.deoptReasonClassCheck;
-            case ArrayStoreException:
-                return config.deoptReasonArrayCheck;
-            case UnreachedCode:
-                return config.deoptReasonUnreached0;
-            case TypeCheckedInliningViolated:
-                return config.deoptReasonTypeCheckInlining;
-            case OptimizedTypeCheckViolated:
-                return config.deoptReasonOptimizedTypeCheck;
-            case NotCompiledExceptionHandler:
-                return config.deoptReasonNotCompiledExceptionHandler;
-            case Unresolved:
-                return config.deoptReasonUnresolved;
-            case JavaSubroutineMismatch:
-                return config.deoptReasonJsrMismatch;
-            case ArithmeticException:
-                return config.deoptReasonDiv0Check;
-            case RuntimeConstraint:
-                return config.deoptReasonConstraint;
-            case LoopLimitCheck:
-                return config.deoptReasonLoopLimitCheck;
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    public boolean needsDataPatch(Constant constant) {
-        return constant.getPrimitiveAnnotation() != null;
-    }
-
-    @Override
-    public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) {
-        switch (kind) {
-            case Boolean:
-                return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement));
-            case Byte:
-                return Constant.forByte(base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement));
-            case Char:
-                return Constant.forChar(base == null ? unsafe.getChar(displacement) : unsafe.getChar(base, displacement));
-            case Short:
-                return Constant.forShort(base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement));
-            case Int:
-                return Constant.forInt(base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement));
-            case Long:
-                if (displacement == config().hubOffset && useCompressedKlassPointers()) {
-                    if (base == null) {
-                        throw new GraalInternalError("Base of object must not be null");
-                    } else {
-                        return Constant.forLong(this.getGraalRuntime().getCompilerToVM().readUnsafeKlassPointer(base));
-                    }
-                } else {
-                    return Constant.forLong(base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement));
-                }
-            case Float:
-                return Constant.forFloat(base == null ? unsafe.getFloat(displacement) : unsafe.getFloat(base, displacement));
-            case Double:
-                return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement));
-            case Object: {
-                Object o = null;
-                if (compressible) {
-                    o = unsafe.getObject(base, displacement);
-                } else {
-                    o = this.getGraalRuntime().getCompilerToVM().readUnsafeUncompressedPointer(base, displacement);
-                }
-                return Constant.forObject(o);
-            }
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
-        return foreignCalls.get(descriptor).isReexecutable();
-    }
-
-    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
-        return foreignCalls.get(descriptor).canDeoptimize();
-    }
-
-    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
-        return foreignCalls.get(descriptor).getKilledLocations();
-    }
-
-    @Override
-    public TargetDescription getTarget() {
-        return graalRuntime.getTarget();
-    }
-
-    public String disassemble(InstalledCode code) {
-        if (code.isValid()) {
-            long codeBlob = ((HotSpotInstalledCode) code).getCodeBlob();
-            return graalRuntime.getCompilerToVM().disassembleCodeBlob(codeBlob);
-        }
-        return null;
-    }
-
-    public String disassemble(ResolvedJavaMethod method) {
-        return new BytecodeDisassembler().disassemble(method);
-    }
-
-    public Suites getDefaultSuites() {
-        return defaultSuites;
-    }
-
-    public Suites createSuites() {
-        Suites ret = Suites.createDefaultSuites();
-
-        if (AOTCompilation.getValue()) {
-            // lowering introduces class constants, therefore it must be after lowering
-            ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase());
-            if (VerifyPhases.getValue()) {
-                ret.getHighTier().appendPhase(new AheadOfTimeVerificationPhase());
-            }
-        }
-
-        ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase());
-        if (VerifyPhases.getValue()) {
-            ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase());
-        }
-
-        return ret;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Wed Oct 16 18:27:28 2013 +0200
@@ -134,7 +134,7 @@
         }
         JavaType type = parameterTypes[index];
         if (type == null || !(type instanceof ResolvedJavaType)) {
-            type = graalRuntime().lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false);
+            type = runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false);
             parameterTypes[index] = type;
         }
         return type;
@@ -153,7 +153,7 @@
     @Override
     public JavaType getReturnType(ResolvedJavaType accessingClass) {
         if (returnTypeCache == null || !(returnTypeCache instanceof ResolvedJavaType)) {
-            returnTypeCache = graalRuntime().lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false);
+            returnTypeCache = runtime().lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false);
         }
         return returnTypeCache;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.graal.phases.GraalOptions.*;
+
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.phases.*;
+import com.oracle.graal.phases.tiers.*;
+
+/**
+ * HotSpot implementation of {@link SuitesProvider}.
+ */
+public class HotSpotSuitesProvider implements SuitesProvider {
+
+    protected final Suites defaultSuites;
+    private final HotSpotGraalRuntime runtime;
+
+    public HotSpotSuitesProvider(HotSpotGraalRuntime runtime) {
+        this.runtime = runtime;
+        defaultSuites = createSuites();
+    }
+
+    public Suites getDefaultSuites() {
+        return defaultSuites;
+    }
+
+    public Suites createSuites() {
+        Suites ret = Suites.createDefaultSuites();
+
+        if (AOTCompilation.getValue()) {
+            // lowering introduces class constants, therefore it must be after lowering
+            ret.getHighTier().appendPhase(new LoadJavaMirrorWithKlassPhase(runtime.getConfig().classMirrorOffset));
+            if (VerifyPhases.getValue()) {
+                ret.getHighTier().appendPhase(new AheadOfTimeVerificationPhase());
+            }
+        }
+
+        ret.getMidTier().appendPhase(new WriteBarrierAdditionPhase());
+        if (VerifyPhases.getValue()) {
+            ret.getMidTier().appendPhase(new WriteBarrierVerificationPhase());
+        }
+
+        return ret;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Wed Oct 16 18:27:28 2013 +0200
@@ -86,6 +86,6 @@
 
     @Override
     public ResolvedJavaType resolve(ResolvedJavaType accessingClass) {
-        return (ResolvedJavaType) graalRuntime().lookupType(getName(), (HotSpotResolvedObjectType) accessingClass, true);
+        return (ResolvedJavaType) runtime().lookupType(getName(), (HotSpotResolvedObjectType) accessingClass, true);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -41,7 +41,7 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        Register rawThread = graalRuntime().getRuntime().threadRegister();
+        Register rawThread = runtime().getProviders().getRegisters().getThreadRegister();
         gen.setResult(this, rawThread.asValue(this.kind()));
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -60,7 +60,7 @@
     @Override
     public void generate(LIRGeneratorTool generator) {
         LIRGenerator gen = (LIRGenerator) generator;
-        HotSpotVMConfig config = graalRuntime().getConfig();
+        HotSpotVMConfig config = runtime().getConfig();
         ResolvedJavaMethod method = frameState.method();
         boolean isStatic = Modifier.isStatic(method.getModifiers());
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Wed Oct 16 18:27:28 2013 +0200
@@ -46,21 +46,26 @@
  */
 public class LoadJavaMirrorWithKlassPhase extends BasePhase<PhaseContext> {
 
+    private final int classMirrorOffset;
+
+    public LoadJavaMirrorWithKlassPhase(int classMirrorOffset) {
+        this.classMirrorOffset = classMirrorOffset;
+    }
+
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
         for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) {
             Constant constant = node.asConstant();
             if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class<?>) {
-                ResolvedJavaType type = context.getMetaAccess().lookupJavaType((Class<?>) constant.asObject());
+                MetaAccessProvider metaAccess = context.getMetaAccess();
+                ResolvedJavaType type = metaAccess.lookupJavaType((Class<?>) constant.asObject());
                 assert type instanceof HotSpotResolvedObjectType;
 
-                HotSpotRuntime runtime = (HotSpotRuntime) context.getMetaAccess();
+                Constant klass = ((HotSpotResolvedObjectType) type).klass();
+                ConstantNode klassNode = ConstantNode.forConstant(klass, metaAccess, graph);
 
-                Constant klass = ((HotSpotResolvedObjectType) type).klass();
-                ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph);
-
-                Stamp stamp = StampFactory.exactNonNull(runtime.lookupJavaType(Class.class));
-                LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), runtime.config.classMirrorOffset, graph));
+                Stamp stamp = StampFactory.exactNonNull(metaAccess.lookupJavaType(Class.class));
+                LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), classMirrorOffset, graph));
                 FloatingReadNode freadNode = graph.unique(new FloatingReadNode(klassNode, location, null, stamp));
 
                 graph.replaceFloating(node, freadNode);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java	Wed Oct 16 18:27:28 2013 +0200
@@ -46,7 +46,7 @@
      */
     @Fold
     private static long crcTableAddress() {
-        return graalRuntime().getConfig().crcTableAddress;
+        return runtime().getConfig().crcTableAddress;
     }
 
     @MethodSubstitution(isStatic = true)
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java	Wed Oct 16 18:27:28 2013 +0200
@@ -34,7 +34,7 @@
 public class CallSiteSubstitutions implements ReplacementsProvider {
 
     @Override
-    public void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target) {
+    public void registerReplacements(MetaAccessProvider metaAccess, LoweringProvider loweringProvider, Replacements replacements, TargetDescription target) {
         replacements.registerSubstitutions(ConstantCallSiteSubstitutions.class);
         replacements.registerSubstitutions(MutableCallSiteSubstitutions.class);
         replacements.registerSubstitutions(VolatileCallSiteSubstitutions.class);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Wed Oct 16 18:27:28 2013 +0200
@@ -24,7 +24,7 @@
 
 import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.hotspot.meta.HotSpotRuntime.*;
+import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 import sun.misc.*;
 
@@ -34,7 +34,6 @@
 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.nodes.extended.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.nodes.*;
@@ -48,7 +47,7 @@
 public class HotSpotReplacementsUtil {
 
     public static HotSpotVMConfig config() {
-        return graalRuntime().getConfig();
+        return runtime().getConfig();
     }
 
     @Fold
@@ -199,22 +198,22 @@
 
     @Fold
     public static Kind getWordKind() {
-        return graalRuntime().getTarget().wordKind;
+        return runtime().getTarget().wordKind;
     }
 
     @Fold
     public static Register threadRegister() {
-        return graalRuntime().getRuntime().threadRegister();
+        return runtime().getProviders().getRegisters().getThreadRegister();
     }
 
     @Fold
     public static Register stackPointerRegister() {
-        return graalRuntime().getRuntime().stackPointerRegister();
+        return runtime().getProviders().getRegisters().getStackPointerRegister();
     }
 
     @Fold
     public static int wordSize() {
-        return graalRuntime().getTarget().wordSize;
+        return runtime().getTarget().wordSize;
     }
 
     @Fold
@@ -344,12 +343,12 @@
 
     @Fold
     public static int arrayBaseOffset(Kind elementKind) {
-        return HotSpotRuntime.getArrayBaseOffset(elementKind);
+        return HotSpotGraalRuntime.getArrayBaseOffset(elementKind);
     }
 
     @Fold
     public static int arrayIndexScale(Kind elementKind) {
-        return HotSpotRuntime.getArrayIndexScale(elementKind);
+        return HotSpotGraalRuntime.getArrayIndexScale(elementKind);
     }
 
     @Fold
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Oct 16 18:27:28 2013 +0200
@@ -69,7 +69,7 @@
      * {@code N == } {@link GraalOptions#InstanceOfMaxHints}).
      */
     public static double hintHitProbabilityThresholdForDeoptimizingSnippet() {
-        return 1.0D - (1.0D / (graalRuntime().getConfig().compileThreshold * 10));
+        return 1.0D - (1.0D / (runtime().getConfig().compileThreshold * 10));
     }
 
     /**
@@ -221,7 +221,8 @@
                     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);
+                    Kind wordKind = providers.getCodeCache().getTarget().wordKind;
+                    args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind), hints.hubs);
                     args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive);
                 } else if (hintInfo.exact != null) {
                     args = new Arguments(instanceofExact, graph.getGuardsStage());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Wed Oct 16 18:27:28 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import static com.oracle.graal.hotspot.meta.HotSpotRuntime.*;
+import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.nodes.PiNode.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
@@ -33,7 +33,6 @@
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
 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;
@@ -64,15 +63,15 @@
 
         private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException");
 
-        public Templates(Providers providers, TargetDescription target) {
+        public Templates(HotSpotProviders providers, TargetDescription target) {
             super(providers, target);
         }
 
         public void lower(LoadExceptionObjectNode loadExceptionObject) {
             if (USE_C_RUNTIME) {
                 StructuredGraph graph = loadExceptionObject.graph();
-                HotSpotRuntime hsRuntime = (HotSpotRuntime) providers.getMetaAccess();
-                ReadRegisterNode thread = graph.add(new ReadRegisterNode(hsRuntime.threadRegister(), true, false));
+                HotSpotRegistersProvider registers = ((HotSpotProviders) providers).getRegisters();
+                ReadRegisterNode thread = graph.add(new ReadRegisterNode(registers.getThreadRegister(), true, false));
                 graph.addBeforeFixed(loadExceptionObject, thread);
                 ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(providers.getForeignCalls(), LOAD_AND_CLEAR_EXCEPTION, thread));
                 loadExceptionC.setStateAfter(loadExceptionObject.stateAfter());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,6 +37,7 @@
 import com.oracle.graal.graph.*;
 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.*;
@@ -330,8 +331,9 @@
             HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass();
             Kind elementKind = elementType.getKind();
             ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), providers.getMetaAccess(), graph);
-            final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
-            int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) providers.getMetaAccess()).getScalingFactor(elementKind));
+            final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind);
+            HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
+            int log2ElementSize = CodeUtil.log2(lowerer.getScalingFactor(elementKind));
 
             Arguments args = new Arguments(allocateArray, graph.getGuardsStage());
             args.add("hub", hub);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Wed Oct 16 18:27:28 2013 +0200
@@ -42,7 +42,7 @@
 
 public class UnsafeArrayCopySnippets implements Snippets {
 
-    private static final boolean supportsUnalignedMemoryAccess = graalRuntime().getTarget().arch.supportsUnalignedMemoryAccess();
+    private static final boolean supportsUnalignedMemoryAccess = runtime().getTarget().arch.supportsUnalignedMemoryAccess();
 
     private static final Kind VECTOR_KIND = Kind.Long;
     private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Wed Oct 16 18:27:28 2013 +0200
@@ -40,12 +40,12 @@
 public class UnsafeLoadSnippets implements Snippets {
 
     @Snippet
-    public static Object lowerUnsafeLoad(Object object, long displacement) {
+    public static Object lowerUnsafeLoad(Object object, long offset) {
         Object fixedObject = FixedValueAnchorNode.getObject(object);
-        if (object instanceof java.lang.ref.Reference && referentOffset() == displacement) {
-            return Word.fromObject(fixedObject).readObject((int) displacement, BarrierType.PRECISE, true);
+        if (object instanceof java.lang.ref.Reference && referentOffset() == offset) {
+            return Word.fromObject(fixedObject).readObject((int) offset, BarrierType.PRECISE, true);
         } else {
-            return Word.fromObject(fixedObject).readObject((int) displacement, BarrierType.NONE, true);
+            return Word.fromObject(fixedObject).readObject((int) offset, BarrierType.NONE, true);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -32,8 +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.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -48,7 +48,7 @@
  */
 public class ExceptionHandlerStub extends SnippetStub {
 
-    public ExceptionHandlerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+    public ExceptionHandlerStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
         super(providers, target, linkage);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -25,8 +25,6 @@
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.meta.MetaUtil.*;
 import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
-import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -45,7 +43,6 @@
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 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,7 +82,8 @@
      *            be re-executed.
      * @param killedLocations the memory locations killed by the stub call
      */
-    public ForeignCallStub(Providers providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable, LocationIdentity... killedLocations) {
+    public ForeignCallStub(HotSpotProviders providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable,
+                    LocationIdentity... killedLocations) {
         super(providers, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
         this.prependThread = prependThread;
         Class[] targetParameterTypes = createTargetParameters(descriptor);
@@ -122,12 +120,13 @@
 
             public Signature getSignature() {
                 ForeignCallDescriptor d = linkage.getDescriptor();
+                MetaAccessProvider metaAccess = providers.getMetaAccess();
                 Class<?>[] arguments = d.getArgumentTypes();
                 JavaType[] parameters = new JavaType[arguments.length];
                 for (int i = 0; i < arguments.length; i++) {
-                    parameters[i] = runtime.lookupJavaType(arguments[i]);
+                    parameters[i] = metaAccess.lookupJavaType(arguments[i]);
                 }
-                return new HotSpotSignature(runtime.lookupJavaType(d.getResultType()), parameters);
+                return new HotSpotSignature(metaAccess.lookupJavaType(d.getResultType()), parameters);
             }
 
             public String getName() {
@@ -135,7 +134,7 @@
             }
 
             public JavaType getDeclaringClass() {
-                return runtime.lookupJavaType(ForeignCallStub.class);
+                return providers.getMetaAccess().lookupJavaType(ForeignCallStub.class);
             }
 
             @Override
@@ -225,7 +224,7 @@
         LocalNode[] locals = createLocals(builder, args);
         List<InvokeNode> invokes = new ArrayList<>(3);
 
-        ReadRegisterNode thread = prependThread || isObjectResult ? builder.append(new ReadRegisterNode(runtime.threadRegister(), true, false)) : null;
+        ReadRegisterNode thread = prependThread || isObjectResult ? builder.append(new ReadRegisterNode(providers.getRegisters().getThreadRegister(), true, false)) : null;
         ValueNode result = createTargetCall(builder, locals, thread);
         invokes.add(createInvoke(builder, StubUtil.class, "handlePendingException", ConstantNode.forBoolean(isObjectResult, builder.graph)));
         if (isObjectResult) {
@@ -241,7 +240,7 @@
         }
 
         /* Rewrite all word types that can come in from the method argument types. */
-        new WordTypeRewriterPhase(runtime, wordKind()).apply(builder.graph);
+        new WordTypeRewriterPhase(providers.getMetaAccess(), providers.getCodeCache().getTarget().wordKind).apply(builder.graph);
         /* Inline all method calls that are create above. */
         for (InvokeNode invoke : invokes) {
             inline(invoke);
@@ -259,9 +258,9 @@
 
     private LocalNode[] createLocals(GraphBuilder builder, Class<?>[] args) {
         LocalNode[] locals = new LocalNode[args.length];
-        ResolvedJavaType accessingClass = runtime.lookupJavaType(getClass());
+        ResolvedJavaType accessingClass = providers.getMetaAccess().lookupJavaType(getClass());
         for (int i = 0; i < args.length; i++) {
-            ResolvedJavaType type = runtime.lookupJavaType(args[i]).resolve(accessingClass);
+            ResolvedJavaType type = providers.getMetaAccess().lookupJavaType(args[i]).resolve(accessingClass);
             Kind kind = type.getKind().getStackKind();
             Stamp stamp;
             if (kind == Kind.Object) {
@@ -280,7 +279,7 @@
         for (Method m : declaringClass.getDeclaredMethods()) {
             if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(name)) {
                 assert method == null : "found more than one method in " + declaringClass + " named " + name;
-                method = runtime.lookupJavaMethod(m);
+                method = providers.getMetaAccess().lookupJavaMethod(m);
             }
         }
         assert method != null : "did not find method in " + declaringClass + " named " + name;
@@ -295,15 +294,15 @@
             ValueNode[] targetArguments = new ValueNode[1 + locals.length];
             targetArguments[0] = thread;
             System.arraycopy(locals, 0, targetArguments, 1, locals.length);
-            return builder.append(new StubForeignCallNode(runtime, target.getDescriptor(), targetArguments));
+            return builder.append(new StubForeignCallNode(providers.getForeignCalls(), target.getDescriptor(), targetArguments));
         } else {
-            return builder.append(new StubForeignCallNode(runtime, target.getDescriptor(), locals));
+            return builder.append(new StubForeignCallNode(providers.getForeignCalls(), target.getDescriptor(), locals));
         }
     }
 
     private void inline(InvokeNode invoke) {
         ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
-        ReplacementsImpl repl = new ReplacementsImpl(runtime, runtime, runtime, runtime, runtime, new Assumptions(false), runtime.getTarget());
+        ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false));
         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	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -36,8 +36,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.nodes.StructuredGraph.*;
-import com.oracle.graal.phases.util.*;
+import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -53,19 +52,19 @@
  */
 public class NewArrayStub extends SnippetStub {
 
-    public NewArrayStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+    public NewArrayStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
         super(providers, target, linkage);
     }
 
     @Override
     protected Arguments makeArguments(SnippetInfo stub) {
-        HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) runtime.lookupJavaType(int[].class);
+        HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) providers.getMetaAccess().lookupJavaType(int[].class);
 
         // RuntimeStub cannot (currently) support oops or metadata embedded in the code so we
         // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since
         // the int[] class will never be unloaded.
         Constant intArrayHub = intArrayType.klass();
-        intArrayHub = Constant.forIntegerKind(graalRuntime().getTarget().wordKind, intArrayHub.asLong(), null);
+        intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null);
 
         Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS);
         args.add("hub", null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,8 +37,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.nodes.StructuredGraph.*;
-import com.oracle.graal.phases.util.*;
+import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -54,19 +53,19 @@
  */
 public class NewInstanceStub extends SnippetStub {
 
-    public NewInstanceStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+    public NewInstanceStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
         super(providers, target, linkage);
     }
 
     @Override
     protected Arguments makeArguments(SnippetInfo stub) {
-        HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) runtime.lookupJavaType(int[].class);
+        HotSpotResolvedObjectType intArrayType = (HotSpotResolvedObjectType) providers.getMetaAccess().lookupJavaType(int[].class);
 
         // RuntimeStub cannot (currently) support oops or metadata embedded in the code so we
         // convert the hub (i.e., Klass*) for int[] to be a naked word. This should be safe since
         // the int[] class will never be unloaded.
         Constant intArrayHub = intArrayType.klass();
-        intArrayHub = Constant.forIntegerKind(graalRuntime().getTarget().wordKind, intArrayHub.asLong(), null);
+        intArrayHub = Constant.forIntegerKind(runtime().getTarget().wordKind, intArrayHub.asLong(), null);
 
         Arguments args = new Arguments(stub, GuardsStage.FLOATING_GUARDS);
         args.add("hub", null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -27,6 +27,7 @@
 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.phases.util.*;
@@ -65,7 +66,7 @@
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public SnippetStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+    public SnippetStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
         super(providers, linkage);
         this.snippet = new Template(providers, target, getClass());
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -42,7 +42,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
-import com.oracle.graal.phases.util.*;
 
 //JaCoCo Exclude
 
@@ -91,18 +90,15 @@
         return true;
     }
 
-    protected final HotSpotRuntime runtime;
-
-    protected final Providers providers;
+    protected final HotSpotProviders providers;
 
     /**
      * Creates a new stub.
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public Stub(Providers providers, HotSpotForeignCallLinkage linkage) {
+    public Stub(HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
         this.linkage = linkage;
-        this.runtime = (HotSpotRuntime) providers.getMetaAccess();
         this.providers = providers;
     }
 
@@ -139,7 +135,7 @@
      */
     public synchronized InstalledCode getCode(final Backend backend) {
         if (code == null) {
-            Debug.sandbox("CompilingStub", new Object[]{runtime, debugScopeContext()}, DebugScope.getConfig(), new Runnable() {
+            Debug.sandbox("CompilingStub", new Object[]{providers.getCodeCache(), debugScopeContext()}, DebugScope.getConfig(), new Runnable() {
 
                 @Override
                 public void run() {
@@ -152,12 +148,15 @@
                     }
 
                     PhasePlan phasePlan = new PhasePlan();
-                    GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+                    ForeignCallsProvider foreignCalls = providers.getForeignCalls();
+                    MetaAccessProvider metaAccess = providers.getMetaAccess();
+                    CodeCacheProvider codeCache = providers.getCodeCache();
+                    GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
                     phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                     // The stub itself needs the incoming calling convention.
                     CallingConvention incomingCc = linkage.getIncomingCallingConvention();
-                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, runtime.getTarget(), null, phasePlan,
-                                    OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites(), new CompilationResult());
+                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null, phasePlan,
+                                    OptimisticOptimizations.ALL, new SpeculationLog(), providers.getSuites().getDefaultSuites(), new CompilationResult());
 
                     assert destroyedRegisters != null;
                     code = Debug.scope("CodeInstall", new Callable<InstalledCode>() {
@@ -167,7 +166,7 @@
                             Stub stub = Stub.this;
                             HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub);
                             HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult);
-                            CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
+                            CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
                             if (result != CodeInstallResult.OK) {
                                 throw new GraalInternalError("Error installing stub %s: %s", Stub.this, result);
                             }
@@ -175,7 +174,7 @@
                                 Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
                             }
                             if (Debug.isLogEnabled()) {
-                                Debug.log("%s", runtime.disassemble(installedCode));
+                                Debug.log("%s", providers.getDisassembler().disassemble(installedCode));
                             }
                             return installedCode;
                         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Wed Oct 16 18:27:28 2013 +0200
@@ -87,7 +87,7 @@
      */
     @Fold
     public static boolean cAssertionsEnabled() {
-        return graalRuntime().getConfig().cAssertions;
+        return runtime().getConfig().cAssertions;
     }
 
     @NodeIntrinsic(StubForeignCallNode.class)
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -32,9 +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.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -45,7 +45,7 @@
  */
 public class UnwindExceptionToCallerStub extends SnippetStub {
 
-    public UnwindExceptionToCallerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+    public UnwindExceptionToCallerStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
         super(providers, target, linkage);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java	Wed Oct 16 18:27:28 2013 +0200
@@ -27,15 +27,14 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 
 /**
- * Stub called via {@link HotSpotRuntime#VERIFY_OOP}.
+ * Stub called via {@link HotSpotForeignCallsProvider#VERIFY_OOP}.
  */
 public class VerifyOopStub extends SnippetStub {
 
-    public VerifyOopStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+    public VerifyOopStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
         super(providers, target, linkage);
     }
 
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Wed Oct 16 18:27:28 2013 +0200
@@ -30,7 +30,7 @@
 /**
  * Utility for producing a {@code javap}-like disassembly of bytecode.
  */
-public class BytecodeDisassembler {
+public class BytecodeDisassembler implements BytecodeDisassemblerProvider {
 
     /**
      * Specifies if the disassembly for a single instruction can span multiple lines.
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Oct 16 18:27:28 2013 +0200
@@ -1218,12 +1218,12 @@
         return monitorEnter;
     }
 
-    private MonitorExitNode genMonitorExit(ValueNode x) {
+    private MonitorExitNode genMonitorExit(ValueNode x, ValueNode returnValue) {
         ValueNode lockedObject = frameState.popLock();
         if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
             throw new BailoutException("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject));
         }
-        MonitorExitNode monitorExit = append(new MonitorExitNode(x, frameState.lockDepth()));
+        MonitorExitNode monitorExit = append(new MonitorExitNode(x, returnValue, frameState.lockDepth()));
         return monitorExit;
     }
 
@@ -1619,7 +1619,7 @@
         assert frameState.stackSize() == 1 : frameState;
         ValueNode exception = frameState.apop();
         append(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true));
-        synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI);
+        synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI, null);
         append(new UnwindNode(exception));
     }
 
@@ -1628,7 +1628,7 @@
         ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind);
         assert frameState.stackSize() == 0;
 
-        synchronizedEpilogue(FrameState.AFTER_BCI);
+        synchronizedEpilogue(FrameState.AFTER_BCI, x);
         if (frameState.lockDepth() != 0) {
             throw new BailoutException("unbalanced monitors");
         }
@@ -1640,9 +1640,9 @@
         append(new ReturnNode(x));
     }
 
-    private void synchronizedEpilogue(int bci) {
+    private void synchronizedEpilogue(int bci, ValueNode returnValue) {
         if (Modifier.isSynchronized(method.getModifiers())) {
-            MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject);
+            MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject, returnValue);
             monitorExit.setStateAfter(frameState.create(bci));
             assert !frameState.rethrowException();
         }
@@ -2002,7 +2002,7 @@
             case CHECKCAST      : genCheckCast(); break;
             case INSTANCEOF     : genInstanceOf(); break;
             case MONITORENTER   : genMonitorEnter(frameState.apop()); break;
-            case MONITOREXIT    : genMonitorExit(frameState.apop()); break;
+            case MONITOREXIT    : genMonitorExit(frameState.apop(), null); break;
             case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break;
             case IFNULL         : genIfNull(Condition.EQ); break;
             case IFNONNULL      : genIfNull(Condition.NE); break;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Wed Oct 16 18:27:28 2013 +0200
@@ -69,8 +69,8 @@
  */
 public class AMD64FrameMap extends FrameMap {
 
-    public AMD64FrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
-        super(codeCache, target, registerConfig);
+    public AMD64FrameMap(CodeCacheProvider codeCache) {
+        super(codeCache);
         // (negative) offset relative to sp + total frame size
         initialSpillSize = returnAddressSize() + calleeSaveAreaSize();
         spillSize = initialSpillSize;
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,8 +37,8 @@
  */
 public final class HSAILFrameMap extends FrameMap {
 
-    public HSAILFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
-        super(codeCache, target, registerConfig);
+    public HSAILFrameMap(CodeCacheProvider codeCache) {
+        super(codeCache);
     }
 
     @Override
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Wed Oct 16 18:27:28 2013 +0200
@@ -37,8 +37,8 @@
  */
 public final class PTXFrameMap extends FrameMap {
 
-    public PTXFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
-        super(codeCache, target, registerConfig);
+    public PTXFrameMap(CodeCacheProvider codeCache) {
+        super(codeCache);
     }
 
     @Override
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Wed Oct 16 18:27:28 2013 +0200
@@ -69,8 +69,8 @@
  */
 public final class SPARCFrameMap extends FrameMap {
 
-    public SPARCFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
-        super(codeCache, target, registerConfig);
+    public SPARCFrameMap(CodeCacheProvider codeCache) {
+        super(codeCache);
         // offset relative to sp + total frame size
         initialSpillSize = 0;
         spillSize = initialSpillSize;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Oct 16 18:27:28 2013 +0200
@@ -86,9 +86,9 @@
     /**
      * Creates a new frame map for the specified method.
      */
-    public FrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
-        this.target = target;
-        this.registerConfig = registerConfig;
+    public FrameMap(CodeCacheProvider codeCache) {
+        this.target = codeCache.getTarget();
+        this.registerConfig = codeCache.getRegisterConfig();
         this.frameSize = -1;
         this.outgoingSize = codeCache.getMinimumOutgoingSize();
         this.objectStackBlocks = new ArrayList<>();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Wed Oct 16 18:27:28 2013 +0200
@@ -63,9 +63,8 @@
 
     private List<ExceptionInfo> exceptionInfoList;
 
-    public TargetMethodAssembler(TargetDescription target, CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext,
-                    CompilationResult compilationResult) {
-        this.target = target;
+    public TargetMethodAssembler(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) {
+        this.target = codeCache.getTarget();
         this.codeCache = codeCache;
         this.foreignCalls = foreignCalls;
         this.frameMap = frameMap;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed Oct 16 18:27:28 2013 +0200
@@ -231,6 +231,7 @@
                 final Iterator<Block> it = blocks.iterator();
                 return new Iterator<AbstractBeginNode>() {
 
+                    @Override
                     public void remove() {
                         throw new UnsupportedOperationException();
                     }
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -52,18 +52,18 @@
     public void testByteConstant() {
         assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forByte((byte) 0, graph).stamp());
         assertEquals(new IntegerStamp(Kind.Int, 16, 16, 0x10, 0x10), ConstantNode.forByte((byte) 16, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -16, -16, 0xf0, 0xf0), ConstantNode.forByte((byte) -16, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -16, -16, 0xfffffff0L, 0xfffffff0L), ConstantNode.forByte((byte) -16, graph).stamp());
         assertEquals(new IntegerStamp(Kind.Int, 127, 127, 0x7f, 0x7f), ConstantNode.forByte((byte) 127, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0x80, 0x80), ConstantNode.forByte((byte) -128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forByte((byte) -128, graph).stamp());
     }
 
     @Test
     public void testShortConstant() {
         assertEquals(new IntegerStamp(Kind.Int, 0, 0, 0x0, 0x0), ConstantNode.forShort((short) 0, graph).stamp());
         assertEquals(new IntegerStamp(Kind.Int, 128, 128, 0x80, 0x80), ConstantNode.forShort((short) 128, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xff80, 0xff80), ConstantNode.forShort((short) -128, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -128, -128, 0xffffff80L, 0xffffff80L), ConstantNode.forShort((short) -128, graph).stamp());
         assertEquals(new IntegerStamp(Kind.Int, 32767, 32767, 0x7fff, 0x7fff), ConstantNode.forShort((short) 32767, graph).stamp());
-        assertEquals(new IntegerStamp(Kind.Int, -32768, -32768, 0x8000, 0x8000), ConstantNode.forShort((short) -32768, graph).stamp());
+        assertEquals(new IntegerStamp(Kind.Int, -32768, -32768, 0xffff8000L, 0xffff8000L), ConstantNode.forShort((short) -32768, graph).stamp());
     }
 
     @Test
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -75,7 +75,9 @@
     }
 
     public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess, Graph graph) {
-        if (constant.getKind() == Kind.Object) {
+        if (constant.getKind().getStackKind() == Kind.Int && constant.getKind() != Kind.Int) {
+            return forInt(constant.asInt(), graph);
+        } else if (constant.getKind() == Kind.Object) {
             return graph.unique(new ConstantNode(constant, metaAccess));
         } else {
             return graph.unique(new ConstantNode(constant));
@@ -142,7 +144,7 @@
      * @return a node representing the boolean
      */
     public static ConstantNode forBoolean(boolean i, Graph graph) {
-        return graph.unique(new ConstantNode(Constant.forBoolean(i)));
+        return graph.unique(new ConstantNode(Constant.forInt(i ? 1 : 0)));
     }
 
     /**
@@ -153,7 +155,7 @@
      * @return a node representing the byte
      */
     public static ConstantNode forByte(byte i, Graph graph) {
-        return graph.unique(new ConstantNode(Constant.forByte(i)));
+        return graph.unique(new ConstantNode(Constant.forInt(i)));
     }
 
     /**
@@ -164,7 +166,7 @@
      * @return a node representing the char
      */
     public static ConstantNode forChar(char i, Graph graph) {
-        return graph.unique(new ConstantNode(Constant.forChar(i)));
+        return graph.unique(new ConstantNode(Constant.forInt(i)));
     }
 
     /**
@@ -175,7 +177,7 @@
      * @return a node representing the short
      */
     public static ConstantNode forShort(short i, Graph graph) {
-        return graph.unique(new ConstantNode(Constant.forShort(i)));
+        return graph.unique(new ConstantNode(Constant.forInt(i)));
     }
 
     /**
@@ -199,7 +201,7 @@
             case Long:
                 return ConstantNode.forLong(value, graph);
             default:
-                throw new InternalError("Should not reach here");
+                throw GraalInternalError.shouldNotReachHere("unknown kind " + kind);
         }
     }
 
@@ -210,14 +212,13 @@
             case Double:
                 return ConstantNode.forDouble(value, graph);
             default:
-                throw new InternalError("Should not reach here");
+                throw GraalInternalError.shouldNotReachHere("unknown kind " + kind);
         }
     }
 
     public static ConstantNode defaultForKind(Kind kind, Graph graph) {
         switch (kind) {
             case Boolean:
-                return ConstantNode.forBoolean(false, graph);
             case Byte:
             case Char:
             case Short:
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -82,7 +82,7 @@
 
     @Override
     public void simplify(SimplifierTool tool) {
-        if (condition instanceof LogicNegationNode) {
+        while (condition instanceof LogicNegationNode) {
             LogicNegationNode negation = (LogicNegationNode) condition;
             setCondition(negation.getInput());
             negated = !negated;
@@ -99,8 +99,9 @@
                 DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, reason));
                 deopt.setDeoptimizationState(getDeoptimizationState());
                 setNext(deopt);
+            } else {
+                this.replaceAtUsages(null);
             }
-            this.replaceAtUsages(BeginNode.prevBegin(this));
             graph().removeFixed(this);
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -34,7 +34,7 @@
  * A node that changes the stamp of its input based on some condition being true.
  */
 @NodeInfo(nameTemplate = "GuardingPi(!={p#negated}) {p#reason/s}")
-public class GuardingPiNode extends FixedWithNextNode implements Lowerable, GuardingNode, Canonicalizable, ValueProxy {
+public class GuardingPiNode extends FixedWithNextNode implements Lowerable, Virtualizable, GuardingNode, Canonicalizable, ValueProxy {
 
     @Input private ValueNode object;
     @Input private LogicNode condition;
@@ -85,6 +85,14 @@
     }
 
     @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(object);
+        if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
+            tool.replaceWithVirtual(state.getVirtualObject());
+        }
+    }
+
+    @Override
     public boolean inferStamp() {
         return updateStamp(stamp().join(object().stamp()));
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -462,8 +462,8 @@
         List<AbstractEndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
         assert phi.valueCount() == merge.forwardEndCount();
 
-        Constant[] xs = constantValues(compare.x(), merge);
-        Constant[] ys = constantValues(compare.y(), merge);
+        Constant[] xs = constantValues(compare.x(), merge, false);
+        Constant[] ys = constantValues(compare.y(), merge, false);
         if (xs == null || ys == null) {
             return false;
         }
@@ -607,7 +607,7 @@
      * @return null if {@code node} is neither a {@link ConstantNode} nor a {@link PhiNode} whose
      *         input values are all constants
      */
-    private static Constant[] constantValues(ValueNode node, MergeNode merge) {
+    public static Constant[] constantValues(ValueNode node, MergeNode merge, boolean allowNull) {
         if (node.isConstant()) {
             Constant[] result = new Constant[merge.forwardEndCount()];
             Arrays.fill(result, node.asConstant());
@@ -620,7 +620,7 @@
                 Constant[] result = new Constant[merge.forwardEndCount()];
                 int i = 0;
                 for (ValueNode n : phi.values()) {
-                    if (!n.isConstant()) {
+                    if (!allowNull && !n.isConstant()) {
                         return null;
                     }
                     result[i++] = n.asConstant();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -185,7 +185,7 @@
 
     @Override
     public void setDeoptimizationState(FrameState f) {
-        throw new IllegalStateException();
+        throw new IllegalStateException("Cannot set deoptimization state " + f + " for invoke " + this);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -48,11 +48,11 @@
         this.foreignCalls = foreignCalls;
     }
 
-    protected ForeignCallNode(@InjectedNodeParameter ForeignCallsProvider metaAccess, ForeignCallDescriptor descriptor, Stamp stamp) {
+    protected ForeignCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, Stamp stamp) {
         super(stamp);
         this.arguments = new NodeInputList<>(this);
         this.descriptor = descriptor;
-        this.foreignCalls = metaAccess;
+        this.foreignCalls = foreignCalls;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -35,7 +35,7 @@
  * information, i.e., an unsafe cast is removed if the input object has a more precise or equal type
  * than the type this nodes casts to.
  */
-public class UnsafeCastNode extends FloatingGuardedNode implements LIRLowerable, GuardingNode, IterableNodeType, Canonicalizable, ValueProxy {
+public class UnsafeCastNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, GuardingNode, IterableNodeType, Canonicalizable, ValueProxy {
 
     @Input private ValueNode object;
 
@@ -86,6 +86,14 @@
     }
 
     @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(object);
+        if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
+            tool.replaceWithVirtual(state.getVirtualObject());
+        }
+    }
+
+    @Override
     public void generate(LIRGeneratorTool generator) {
         assert kind() == Kind.Object && object.kind() == Kind.Object;
         /*
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -63,8 +63,11 @@
             if (offsetValue.isConstant()) {
                 long offset = offsetValue.asConstant().asLong();
                 int entryIndex = state.getVirtualObject().entryIndexForOffset(offset);
-                if (entryIndex != -1 && state.getVirtualObject().entryKind(entryIndex) == accessKind()) {
-                    tool.replaceWith(state.getEntry(entryIndex));
+                if (entryIndex != -1) {
+                    ValueNode entry = state.getEntry(entryIndex);
+                    if (entry.kind() == kind() || state.getVirtualObject().entryKind(entryIndex) == accessKind()) {
+                        tool.replaceWith(entry);
+                    }
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -80,9 +80,12 @@
             if (indexValue.isConstant()) {
                 long offset = indexValue.asConstant().asLong();
                 int entryIndex = state.getVirtualObject().entryIndexForOffset(offset);
-                if (entryIndex != -1 && state.getVirtualObject().entryKind(entryIndex) == accessKind()) {
-                    tool.setVirtualEntry(state, entryIndex, value());
-                    tool.delete();
+                if (entryIndex != -1) {
+                    ValueNode entry = state.getEntry(entryIndex);
+                    if (entry.kind() == value.kind() || state.getVirtualObject().entryKind(entryIndex) == accessKind()) {
+                        tool.setVirtualEntry(state, entryIndex, value());
+                        tool.delete();
+                    }
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -60,13 +60,13 @@
 
     @Override
     public Node canonical(CanonicalizerTool tool) {
-        MetaAccessProvider runtime = tool.getMetaAccess();
-        if (tool.canonicalizeReads() && runtime != null) {
-            ConstantNode constant = asConstant(runtime);
+        MetaAccessProvider metaAccess = tool.getMetaAccess();
+        if (tool.canonicalizeReads() && metaAccess != null) {
+            ConstantNode constant = asConstant(metaAccess);
             if (constant != null) {
                 return constant;
             }
-            PhiNode phi = asPhi(runtime);
+            PhiNode phi = asPhi(metaAccess);
             if (phi != null) {
                 return phi;
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -34,17 +34,24 @@
 public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single, MonitorReference {
 
     private int lockDepth;
+    @Input private ValueNode escapedReturnValue;
 
     /**
      * Creates a new MonitorExitNode.
      * 
      * @param object the instruction produces the object value
      */
-    public MonitorExitNode(ValueNode object, int lockDepth) {
+    public MonitorExitNode(ValueNode object, ValueNode escapedReturnValue, int lockDepth) {
         super(object);
+        this.escapedReturnValue = escapedReturnValue;
         this.lockDepth = lockDepth;
     }
 
+    public void setEscapedReturnValue(ValueNode x) {
+        updateUsages(escapedReturnValue, x);
+        this.escapedReturnValue = x;
+    }
+
     @Override
     public LocationIdentity getLocationIdentity() {
         return LocationIdentity.ANY_LOCATION;
@@ -65,11 +72,20 @@
 
     @Override
     public void virtualize(VirtualizerTool tool) {
-        State state = tool.getObjectState(object());
-        if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) {
-            int removedLock = state.removeLock();
-            assert removedLock == getLockDepth();
-            tool.delete();
+        /*
+         * The last MonitorExitNode of a synchronized method cannot be removed anyway, and we need
+         * it to materialize the return value.
+         * 
+         * TODO: replace this with correct handling of AFTER_BCI frame states in the runtime.
+         */
+        if (stateAfter().bci != FrameState.AFTER_BCI) {
+            setEscapedReturnValue(null);
+            State state = tool.getObjectState(object());
+            if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) {
+                int removedLock = state.removeLock();
+                assert removedLock == getLockDepth();
+                tool.delete();
+            }
         }
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -74,7 +74,8 @@
             int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1;
             if (index >= 0 && index < arrayState.getVirtualObject().entryCount()) {
                 ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType();
-                if (componentType.isPrimitive() || ObjectStamp.isObjectAlwaysNull(value) || (ObjectStamp.typeOrNull(value) != null && componentType.isAssignableFrom(ObjectStamp.typeOrNull(value)))) {
+                if (componentType.isPrimitive() || ObjectStamp.isObjectAlwaysNull(value) || componentType.getSuperclass() == null ||
+                                (ObjectStamp.typeOrNull(value) != null && componentType.isAssignableFrom(ObjectStamp.typeOrNull(value)))) {
                     tool.setVirtualEntry(arrayState, index, value());
                     tool.delete();
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Wed Oct 16 18:27:28 2013 +0200
@@ -30,5 +30,5 @@
  */
 public interface ReplacementsProvider {
 
-    void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target);
+    void registerReplacements(MetaAccessProvider metaAccess, LoweringProvider lowerer, Replacements replacements, TargetDescription target);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java	Wed Oct 16 18:27:28 2013 +0200
@@ -24,9 +24,11 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 
@@ -45,7 +47,7 @@
  */
 public class ConvertDeoptimizeToGuardPhase extends Phase {
 
-    private static AbstractBeginNode findBeginNode(Node startNode) {
+    private static AbstractBeginNode findBeginNode(FixedNode startNode) {
         Node n = startNode;
         while (true) {
             if (n instanceof AbstractBeginNode) {
@@ -64,16 +66,50 @@
 
         for (DeoptimizeNode d : graph.getNodes(DeoptimizeNode.class)) {
             assert d.isAlive();
-            visitDeoptBegin(findBeginNode(d), d, graph);
+            visitDeoptBegin(BeginNode.prevBegin(d), d.action(), d.reason(), graph);
+        }
+
+        for (FixedGuardNode fixedGuard : graph.getNodes(FixedGuardNode.class)) {
+
+            AbstractBeginNode pred = BeginNode.prevBegin(fixedGuard);
+            if (pred instanceof MergeNode) {
+                MergeNode merge = (MergeNode) pred;
+                if (fixedGuard.condition() instanceof CompareNode) {
+                    CompareNode compare = (CompareNode) fixedGuard.condition();
+                    List<AbstractEndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
+
+                    Constant[] xs = IfNode.constantValues(compare.x(), merge, true);
+                    if (xs == null) {
+                        continue;
+                    }
+                    Constant[] ys = IfNode.constantValues(compare.y(), merge, true);
+                    if (ys == null) {
+                        continue;
+                    }
+                    for (int i = 0; i < mergePredecessors.size(); ++i) {
+                        AbstractEndNode mergePredecessor = mergePredecessors.get(i);
+                        if (xs[i] == null) {
+                            continue;
+                        }
+                        if (ys[i] == null) {
+                            continue;
+                        }
+                        if (xs[i].getKind() != Kind.Object && ys[i].getKind() != Kind.Object &&
+                                        compare.condition().foldCondition(xs[i], ys[i], null, compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
+                            visitDeoptBegin(BeginNode.prevBegin(mergePredecessor), fixedGuard.getAction(), fixedGuard.getReason(), graph);
+                        }
+                    }
+                }
+            }
         }
 
         new DeadCodeEliminationPhase().apply(graph);
     }
 
-    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizeNode deopt, StructuredGraph graph) {
+    private void visitDeoptBegin(AbstractBeginNode deoptBegin, DeoptimizationAction deoptAction, DeoptimizationReason deoptReason, StructuredGraph graph) {
         if (deoptBegin instanceof MergeNode) {
             MergeNode mergeNode = (MergeNode) deoptBegin;
-            Debug.log("Visiting %s followed by %s", mergeNode, deopt);
+            Debug.log("Visiting %s", mergeNode);
             List<AbstractBeginNode> begins = new ArrayList<>();
             for (AbstractEndNode end : mergeNode.forwardEnds()) {
                 AbstractBeginNode newBeginNode = findBeginNode(end);
@@ -82,7 +118,7 @@
             }
             for (AbstractBeginNode begin : begins) {
                 assert !begin.isDeleted();
-                visitDeoptBegin(begin, deopt, graph);
+                visitDeoptBegin(begin, deoptAction, deoptReason, graph);
             }
             assert mergeNode.isDeleted();
             return;
@@ -90,7 +126,7 @@
             IfNode ifNode = (IfNode) deoptBegin.predecessor();
             AbstractBeginNode otherBegin = ifNode.trueSuccessor();
             LogicNode conditionNode = ifNode.condition();
-            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.reason(), deopt.action(), deoptBegin == ifNode.trueSuccessor()));
+            FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deoptReason, deoptAction, deoptBegin == ifNode.trueSuccessor()));
             FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
             AbstractBeginNode survivingSuccessor;
             if (deoptBegin == ifNode.trueSuccessor()) {
@@ -115,7 +151,7 @@
                     }
                 }
             }
-            Debug.log("Converting %s on %-5s branch of %s to guard for remaining branch %s.", deopt, deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin);
+            Debug.log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", deoptBegin == ifNode.trueSuccessor() ? "true" : "false", ifNode, otherBegin);
             FixedNode next = pred.next();
             pred.setNext(guard);
             guard.setNext(next);
@@ -126,8 +162,8 @@
         FixedWithNextNode deoptPred = deoptBegin;
         FixedNode next = deoptPred.next();
 
-        if (next != deopt) {
-            DeoptimizeNode newDeoptNode = (DeoptimizeNode) deopt.clone(graph);
+        if (!(next instanceof DeoptimizeNode)) {
+            DeoptimizeNode newDeoptNode = graph.add(new DeoptimizeNode(deoptAction, deoptReason));
             deoptPred.setNext(newDeoptNode);
             assert deoptPred == newDeoptNode.predecessor();
             GraphUtil.killCFG(next);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -44,12 +43,10 @@
 
     private static final LocationIdentity ID = new NamedLocationIdentity("ID");
     private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object};
-    private final TargetDescription target;
     private final ReplacementsImpl installer;
 
     public ObjectAccessTest() {
-        target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getForeignCalls(), getLowerer(), new Assumptions(false), target);
+        installer = new ReplacementsImpl(getProviders(), new Assumptions(false));
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -52,8 +51,8 @@
     private final ReplacementsImpl installer;
 
     public PointerTest() {
-        target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getForeignCalls(), getLowerer(), new Assumptions(false), target);
+        target = getCodeCache().getTarget();
+        installer = new ReplacementsImpl(getProviders(), new Assumptions(false));
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -26,12 +26,11 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
-import com.oracle.graal.test.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.Snippet.*;
+import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy;
+import com.oracle.graal.test.*;
 import com.oracle.graal.word.*;
 
 /**
@@ -42,8 +41,7 @@
     private final ReplacementsImpl installer;
 
     public WordTest() {
-        TargetDescription target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getForeignCalls(), getLowerer(), new Assumptions(false), target);
+        installer = new ReplacementsImpl(getProviders(), new Assumptions(false));
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Wed Oct 16 18:27:28 2013 +0200
@@ -35,7 +35,7 @@
 @ServiceProvider(ReplacementsProvider.class)
 public class GraalMethodSubstitutions implements ReplacementsProvider {
 
-    public void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target) {
+    public void registerReplacements(MetaAccessProvider metaAccess, LoweringProvider loweringProvider, Replacements replacements, TargetDescription target) {
         for (Class<?> clazz : BoxingSubstitutions.getClasses()) {
             replacements.registerSubstitutions(clazz);
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Wed Oct 16 18:27:28 2013 +0200
@@ -68,10 +68,9 @@
     private final Set<ResolvedJavaMethod> forcedSubstitutions;
     private final Map<Class<? extends SnippetTemplateCache>, SnippetTemplateCache> snippetTemplateCache;
 
-    public ReplacementsImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, LoweringProvider lowerer,
-                    Assumptions assumptions, TargetDescription target) {
-        this.providers = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, this);
-        this.target = target;
+    public ReplacementsImpl(Providers providers, Assumptions assumptions) {
+        this.providers = providers.copyWith(this);
+        this.target = providers.getCodeCache().getTarget();
         this.assumptions = assumptions;
         this.graphs = new ConcurrentHashMap<>();
         this.registeredMethodSubstitutions = new HashMap<>();
--- a/graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/InlinePrinterProcessor.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +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.truffle.printer;
-
-import java.util.*;
-
-import com.oracle.graal.debug.*;
-import com.oracle.graal.truffle.printer.method.*;
-
-public final class InlinePrinterProcessor {
-
-    private static final String IDENT = "   ";
-    private static InlinePrinterProcessor instance;
-
-    private final List<TruffleMethodNode> inlineTree = new ArrayList<>();
-
-    public static void initialize() {
-        if (instance == null) {
-            instance = new InlinePrinterProcessor();
-        } else {
-            throw new IllegalStateException();
-        }
-    }
-
-    public static void addInlining(MethodHolder methodHolder) {
-        instance.addExecuteInline(methodHolder);
-    }
-
-    public static void printTree() {
-        instance.print();
-    }
-
-    public static void reset() {
-        instance = null;
-    }
-
-    private void addExecuteInline(MethodHolder executeMethod) {
-        if (inlineTree.isEmpty()) {
-            inlineTree.add(new TruffleMethodNode(null, executeMethod));
-        } else {
-            TruffleMethodNode newNode = null;
-            for (TruffleMethodNode node : inlineTree) {
-                newNode = node.addTruffleExecuteMethodNode(executeMethod);
-                if (newNode != null) {
-                    break;
-                }
-            }
-            if (newNode == null) {
-                throw new AssertionError("Not able to add " + executeMethod.getMethod().toString() + " to the inlineing tree");
-            }
-            inlineTree.add(newNode);
-        }
-    }
-
-    private TruffleMethodNode getInlineTree() {
-        TruffleMethodNode root = inlineTree.get(0);
-        while (root.getParent() != null) {
-            root = root.getParent();
-        }
-
-        // asserting:
-        for (TruffleMethodNode node : inlineTree) {
-            TruffleMethodNode nodeRoot = node;
-            while (nodeRoot.getParent() != null) {
-                nodeRoot = nodeRoot.getParent();
-            }
-            if (root != nodeRoot) {
-                throw new AssertionError("Different roots found");
-            }
-        }
-
-        return root;
-    }
-
-    private void print() {
-        String curIndent = "";
-        TruffleMethodNode root = getInlineTree();
-        String name = root.getJavaMethod().getDeclaringClass().getName();
-        TTY.print(name.substring(name.lastIndexOf('/') + 1, name.lastIndexOf(';')) + "::" + root.getJavaMethod().getName());
-        TTY.println();
-        recursivePrint(curIndent, root);
-    }
-
-    private void recursivePrint(String curIdent, TruffleMethodNode node) {
-        Map<Integer, List<TruffleMethodNode>> inlinings = node.getInlinings();
-        for (int l : inlinings.keySet()) {
-            for (TruffleMethodNode n : inlinings.get(l)) {
-                TTY.print(curIdent);
-                TTY.print("L" + l + " ");
-                String name = n.getJavaMethod().getDeclaringClass().getName();
-                TTY.print(name.substring(name.lastIndexOf('/') + 1, name.lastIndexOf(';')) + "::" + n.getJavaMethod().getName());
-                TTY.println();
-                recursivePrint(curIdent + IDENT, n);
-            }
-        }
-    }
-}
--- a/graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/method/CallStackElement.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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.truffle.printer.method;
-
-import com.oracle.graal.api.meta.*;
-
-public class CallStackElement {
-
-    private final int lineOfInvoke;
-    private final ResolvedJavaMethod callerMethod;
-
-    public CallStackElement(ResolvedJavaMethod callerMethod, int lineOfInvoke) {
-        this.lineOfInvoke = lineOfInvoke;
-        this.callerMethod = callerMethod;
-    }
-
-    public int getLineOfInvoke() {
-        return lineOfInvoke;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof CallStackElement) {
-            CallStackElement i = (CallStackElement) o;
-            if (i.getCallerMethod() == this.getCallerMethod()/*
-                                                              * && i.lineOfInvoke ==
-                                                              * this.lineOfInvoke
-                                                              */) {
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        return super.hashCode();
-    }
-
-    public ResolvedJavaMethod getCallerMethod() {
-        return callerMethod;
-    }
-}
--- a/graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/method/MethodHolder.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +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.truffle.printer.method;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-
-public final class MethodHolder {
-
-    private final List<CallStackElement> callStack;
-    private final ResolvedJavaMethod method;
-
-    public static MethodHolder getNewTruffleExecuteMethod(MethodCallTargetNode targetNode) {
-        return new MethodHolder(getCallStack(targetNode), targetNode.targetMethod());
-    }
-
-    private MethodHolder(List<CallStackElement> callStack, ResolvedJavaMethod callee) {
-        this.callStack = callStack;
-        this.method = callee;
-    }
-
-    public List<CallStackElement> getCallStack() {
-        return callStack;
-    }
-
-    public ResolvedJavaMethod getMethod() {
-        return method;
-    }
-
-    private static List<CallStackElement> getCallStack(MethodCallTargetNode targetNode) {
-        List<CallStackElement> callStack = new ArrayList<>();
-        FrameState state = targetNode.invoke().stateAfter();
-        while (state != null) {
-            ResolvedJavaMethod method = state.method();
-            LineNumberTable table = method.getLineNumberTable();
-            int lineNr = table.getLineNumber(state.bci - 1);
-            callStack.add(new CallStackElement(method, lineNr));
-            state = state.outerFrameState();
-        }
-        return callStack;
-    }
-}
--- a/graal/com.oracle.graal.truffle.printer/src/com/oracle/graal/truffle/printer/method/TruffleMethodNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +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.truffle.printer.method;
-
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-
-public final class TruffleMethodNode {
-
-    private final TruffleMethodNode parent;
-    private final MethodHolder truffleExecuteMethod;
-    private final Map<Integer, List<TruffleMethodNode>> inlinings;
-
-    public TruffleMethodNode(TruffleMethodNode parent, MethodHolder truffleExecuteMethod) {
-        this.parent = parent;
-        this.truffleExecuteMethod = truffleExecuteMethod;
-        this.inlinings = new HashMap<>();
-    }
-
-    public TruffleMethodNode getParent() {
-        return parent;
-    }
-
-    public ResolvedJavaMethod getJavaMethod() {
-        return truffleExecuteMethod.getMethod();
-    }
-
-    public Map<Integer, List<TruffleMethodNode>> getInlinings() {
-        return inlinings;
-    }
-
-    public void putInlineList(int lineOfInvoke, List<TruffleMethodNode> list) {
-        inlinings.put(lineOfInvoke, list);
-    }
-
-    public List<TruffleMethodNode> getInliningsAtLine(int line) {
-        return inlinings.get(line);
-    }
-
-    public MethodHolder getTruffleExecuteMethod() {
-        return truffleExecuteMethod;
-    }
-
-    public TruffleMethodNode addTruffleExecuteMethodNode(MethodHolder newMethod) {
-        int lineOfInvoke = newMethod.getCallStack().get(0).getLineOfInvoke();
-
-        if (!callStackMatch(newMethod.getCallStack())) {
-            return null;
-        } else {
-            TruffleMethodNode node = new TruffleMethodNode(this, newMethod);
-            if (getInliningsAtLine(lineOfInvoke) == null) {
-                List<TruffleMethodNode> list = new ArrayList<>();
-                list.add(node);
-                putInlineList(lineOfInvoke, list);
-            } else {
-                getInliningsAtLine(lineOfInvoke).add(node);
-            }
-            return node;
-        }
-    }
-
-    private boolean callStackMatch(List<CallStackElement> callStack) {
-        List<CallStackElement> curCallStack = truffleExecuteMethod.getCallStack();
-        if (curCallStack.size() == callStack.size() - 1) {
-            if (curCallStack.size() >= 1) {
-                if (curCallStack.get(0).getCallerMethod() != callStack.get(1).getCallerMethod()) {
-                    return false;
-                }
-            }
-            for (int i = 1; i < curCallStack.size(); i++) {
-                if (!curCallStack.get(i).equals(callStack.get(i + 1))) {
-                    return false;
-                }
-            }
-        } else {
-            return false;
-        }
-        return true;
-    }
-
-}
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.truffle.test;
 
-import static com.oracle.graal.truffle.TruffleCompilerOptions.*;
-
 import java.util.*;
 import java.util.concurrent.*;
 
@@ -44,7 +42,6 @@
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.printer.*;
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
@@ -59,7 +56,7 @@
         // Make sure Truffle runtime is initialized.
         Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime);
         Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
-        Providers providers = new Providers(getMetaAccess(), getCodeCache(), getConstantReflection(), getForeignCalls(), getLowerer(), truffleReplacements);
+        Providers providers = getProviders().copyWith(truffleReplacements);
         TruffleCache truffleCache = new TruffleCache(providers, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations);
         this.partialEvaluator = new PartialEvaluator(providers, truffleCache);
 
@@ -136,10 +133,6 @@
                 new DeadCodeEliminationPhase().apply(resultGraph);
                 new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context);
 
-                if (TruffleInlinePrinter.getValue()) {
-                    InlinePrinterProcessor.printTree();
-                }
-
                 return resultGraph;
             }
 
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/StoreLocalTestNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/StoreLocalTestNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -38,11 +38,7 @@
     @Override
     public int execute(VirtualFrame frame) {
         int value = valueNode.execute(frame);
-        try {
-            frame.setInt(slot, value);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException(e);
-        }
+        frame.setInt(slot, value);
         return value;
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Wed Oct 16 18:27:28 2013 +0200
@@ -36,8 +36,6 @@
  */
 public final class FrameWithoutBoxing implements VirtualFrame, MaterializedFrame, PackedFrame {
 
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
-
     private final FrameDescriptor descriptor;
     private final PackedFrame caller;
     private final Arguments arguments;
@@ -87,17 +85,17 @@
     }
 
     private Object getObjectUnsafe(FrameSlot slot) {
-        return unsafe.getObject(locals, (long) slot.getIndex() * Unsafe.ARRAY_OBJECT_INDEX_SCALE + Unsafe.ARRAY_OBJECT_BASE_OFFSET);
+        return CompilerDirectives.unsafeGetObject(locals, (long) slot.getIndex() * Unsafe.ARRAY_OBJECT_INDEX_SCALE + Unsafe.ARRAY_OBJECT_BASE_OFFSET, true, slot);
     }
 
     @Override
     public void setObject(FrameSlot slot, Object value) {
-        verifySetObject(slot);
+        verifySet(slot, FrameSlotKind.Object);
         setObjectUnsafe(slot, value);
     }
 
     private void setObjectUnsafe(FrameSlot slot, Object value) {
-        unsafe.putObject(locals, (long) slot.getIndex() * Unsafe.ARRAY_OBJECT_INDEX_SCALE + Unsafe.ARRAY_OBJECT_BASE_OFFSET, value);
+        CompilerDirectives.unsafePutObject(locals, (long) slot.getIndex() * Unsafe.ARRAY_OBJECT_INDEX_SCALE + Unsafe.ARRAY_OBJECT_BASE_OFFSET, value, slot);
     }
 
     @Override
@@ -107,17 +105,17 @@
     }
 
     private byte getByteUnsafe(FrameSlot slot) {
-        return unsafe.getByte(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+        return CompilerDirectives.unsafeGetByte(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, true, slot);
     }
 
     @Override
-    public void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException {
+    public void setByte(FrameSlot slot, byte value) {
         verifySet(slot, FrameSlotKind.Byte);
         setByteUnsafe(slot, value);
     }
 
     private void setByteUnsafe(FrameSlot slot, byte value) {
-        unsafe.putByte(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+        CompilerDirectives.unsafePutByte(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value, slot);
     }
 
     @Override
@@ -127,17 +125,17 @@
     }
 
     private boolean getBooleanUnsafe(FrameSlot slot) {
-        return unsafe.getBoolean(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+        return CompilerDirectives.unsafeGetBoolean(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, true, slot);
     }
 
     @Override
-    public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException {
+    public void setBoolean(FrameSlot slot, boolean value) {
         verifySet(slot, FrameSlotKind.Boolean);
         setBooleanUnsafe(slot, value);
     }
 
     private void setBooleanUnsafe(FrameSlot slot, boolean value) {
-        unsafe.putBoolean(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+        CompilerDirectives.unsafePutBoolean(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value, slot);
     }
 
     @Override
@@ -147,17 +145,17 @@
     }
 
     private float getFloatUnsafe(FrameSlot slot) {
-        return unsafe.getFloat(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+        return CompilerDirectives.unsafeGetFloat(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, true, slot);
     }
 
     @Override
-    public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException {
+    public void setFloat(FrameSlot slot, float value) {
         verifySet(slot, FrameSlotKind.Float);
         setFloatUnsafe(slot, value);
     }
 
     private void setFloatUnsafe(FrameSlot slot, float value) {
-        unsafe.putFloat(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+        CompilerDirectives.unsafePutFloat(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value, slot);
     }
 
     @Override
@@ -167,17 +165,17 @@
     }
 
     private long getLongUnsafe(FrameSlot slot) {
-        return unsafe.getLong(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+        return CompilerDirectives.unsafeGetLong(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, true, slot);
     }
 
     @Override
-    public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException {
+    public void setLong(FrameSlot slot, long value) {
         verifySet(slot, FrameSlotKind.Long);
         setLongUnsafe(slot, value);
     }
 
     private void setLongUnsafe(FrameSlot slot, long value) {
-        unsafe.putLong(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+        CompilerDirectives.unsafePutLong(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value, slot);
     }
 
     @Override
@@ -187,17 +185,17 @@
     }
 
     private int getIntUnsafe(FrameSlot slot) {
-        return unsafe.getInt(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+        return CompilerDirectives.unsafeGetInt(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, true, slot);
     }
 
     @Override
-    public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException {
+    public void setInt(FrameSlot slot, int value) {
         verifySet(slot, FrameSlotKind.Int);
         setIntUnsafe(slot, value);
     }
 
     private void setIntUnsafe(FrameSlot slot, int value) {
-        unsafe.putInt(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+        CompilerDirectives.unsafePutInt(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value, slot);
     }
 
     @Override
@@ -207,17 +205,17 @@
     }
 
     private double getDoubleUnsafe(FrameSlot slot) {
-        return unsafe.getDouble(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET);
+        return CompilerDirectives.unsafeGetDouble(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, true, slot);
     }
 
     @Override
-    public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException {
+    public void setDouble(FrameSlot slot, double value) {
         verifySet(slot, FrameSlotKind.Double);
         setDoubleUnsafe(slot, value);
     }
 
     private void setDoubleUnsafe(FrameSlot slot, double value) {
-        unsafe.putDouble(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value);
+        CompilerDirectives.unsafePutDouble(primitiveLocals, (long) slot.getIndex() * Unsafe.ARRAY_LONG_INDEX_SCALE + Unsafe.ARRAY_LONG_BASE_OFFSET, value, slot);
     }
 
     @Override
@@ -225,16 +223,7 @@
         return this.descriptor;
     }
 
-    private void verifySet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
-        FrameSlotKind slotKind = slot.getKind();
-        if (slotKind != accessKind) {
-            CompilerDirectives.transferToInterpreter();
-            if (slotKind == FrameSlotKind.Illegal) {
-                slot.setKind(accessKind);
-            } else {
-                throw new FrameSlotTypeException();
-            }
-        }
+    private void verifySet(FrameSlot slot, FrameSlotKind accessKind) {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
             CompilerDirectives.transferToInterpreter();
@@ -243,27 +232,14 @@
         tags[slotIndex] = (byte) accessKind.ordinal();
     }
 
-    private void verifySetObject(FrameSlot slot) {
-        if (slot.getKind() != FrameSlotKind.Object) {
-            CompilerDirectives.transferToInterpreter();
-            slot.setKind(FrameSlotKind.Object);
-        }
-        int slotIndex = slot.getIndex();
-        if (slotIndex >= tags.length) {
-            CompilerDirectives.transferToInterpreter();
-            resize();
-        }
-        tags[slotIndex] = (byte) FrameSlotKind.Object.ordinal();
-    }
-
     private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
             CompilerDirectives.transferToInterpreter();
             resize();
         }
-        byte tag = tags[slotIndex];
-        if (accessKind == FrameSlotKind.Object ? (tag & 0xfe) != 0 : tag != accessKind.ordinal()) {
+        byte tag = this.tags[slotIndex];
+        if (accessKind == FrameSlotKind.Object ? tag != 0 : tag != accessKind.ordinal()) {
             CompilerDirectives.transferToInterpreter();
             if (slot.getKind() == accessKind || tag == 0) {
                 descriptor.getTypeConversion().updateFrameSlot(this, slot, getValue(slot));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Wed Oct 16 18:27:28 2013 +0200
@@ -183,6 +183,12 @@
     @Override
     public void nodeReplaced() {
         replaceCount++;
+        if (compiledMethod != null) {
+            if (compiledMethod.isValid()) {
+                compiledMethod.invalidate();
+            }
+            compiledMethod = null;
+        }
         compilationPolicy.nodeReplaced();
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed Oct 16 18:27:28 2013 +0200
@@ -55,8 +55,6 @@
 import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode;
 import com.oracle.graal.truffle.phases.*;
-import com.oracle.graal.truffle.printer.*;
-import com.oracle.graal.truffle.printer.method.*;
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
@@ -80,7 +78,7 @@
         CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection());
         this.canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue(), customCanonicalizer);
         this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess());
-        this.cache = HotSpotGraalRuntime.graalRuntime().getCache();
+        this.cache = HotSpotGraalRuntime.runtime().getCache();
         this.truffleCache = truffleCache;
 
         try {
@@ -107,10 +105,6 @@
 
         final StructuredGraph graph = new StructuredGraph(executeHelperMethod);
 
-        if (TruffleInlinePrinter.getValue()) {
-            InlinePrinterProcessor.initialize();
-        }
-
         Debug.scope("createGraph", graph, new Runnable() {
 
             @Override
@@ -140,11 +134,6 @@
 
                 new VerifyFrameDoesNotEscapePhase().apply(graph, false);
 
-                if (TruffleInlinePrinter.getValue()) {
-                    InlinePrinterProcessor.printTree();
-                    InlinePrinterProcessor.reset();
-                }
-
                 if (TraceTruffleCompilationDetails.getValue() && constantReceivers != null) {
                     DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes");
                     for (Constant c : constantReceivers) {
@@ -164,7 +153,7 @@
                 }
 
                 // EA frame and clean up.
-                new PartialEscapePhase(false, canonicalizer).apply(graph, tierContext);
+                new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext);
                 new VerifyNoIntrinsicsLeftPhase().apply(graph, false);
                 for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) {
                     materializeNode.replaceAtUsages(materializeNode.getFrame());
@@ -196,9 +185,6 @@
             for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.class)) {
                 InvokeKind kind = methodCallTargetNode.invokeKind();
                 if (kind == InvokeKind.Static || (kind == InvokeKind.Special && (methodCallTargetNode.receiver().isConstant() || methodCallTargetNode.receiver() instanceof NewFrameNode))) {
-                    if (TruffleInlinePrinter.getValue()) {
-                        InlinePrinterProcessor.addInlining(MethodHolder.getNewTruffleExecuteMethod(methodCallTargetNode));
-                    }
                     if (TraceTruffleCompilationDetails.getValue() && kind == InvokeKind.Special) {
                         ConstantNode constantNode = (ConstantNode) methodCallTargetNode.arguments().first();
                         constantReceivers.add(constantNode.asConstant());
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Oct 16 18:27:28 2013 +0200
@@ -59,7 +59,7 @@
     private final PartialEvaluator partialEvaluator;
     private final Backend backend;
     private final ResolvedJavaType[] skippedExceptionTypes;
-    private final HotSpotGraalRuntime graalRuntime;
+    private final HotSpotGraalRuntime runtime;
     private final TruffleCache truffleCache;
 
     private static final Class[] SKIPPED_EXCEPTION_CLASSES = new Class[]{SlowPathException.class, UnexpectedResultException.class, ArithmeticException.class};
@@ -72,7 +72,7 @@
         this.providers = GraalCompiler.getGraalProviders().copyWith(truffleReplacements);
         this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
         this.backend = Graal.getRequiredCapability(Backend.class);
-        this.graalRuntime = HotSpotGraalRuntime.graalRuntime();
+        this.runtime = HotSpotGraalRuntime.runtime();
         this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
 
         final GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault();
@@ -113,7 +113,7 @@
         final StructuredGraph graph;
         final GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
         config.setSkippedExceptionTypes(skippedExceptionTypes);
-        graalRuntime.evictDeoptedGraphs();
+        runtime.evictDeoptedGraphs();
 
         compilable.timeCompilationStarted = System.nanoTime();
         Assumptions assumptions = new Assumptions(true);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Wed Oct 16 18:27:28 2013 +0200
@@ -56,13 +56,13 @@
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleFunctionInlining = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Integer> TruffleGraphMaxNodes = new OptionValue<>(20000);
+    public static final OptionValue<Integer> TruffleGraphMaxNodes = new OptionValue<>(25000);
     @Option(help = "")
     public static final OptionValue<Integer> TruffleInliningMaxRecursiveDepth = new OptionValue<>(2);
     @Option(help = "")
-    public static final OptionValue<Integer> TruffleInliningMaxCallerSize = new OptionValue<>(600);
+    public static final OptionValue<Integer> TruffleInliningMaxCallerSize = new OptionValue<>(2500);
     @Option(help = "")
-    public static final OptionValue<Integer> TruffleInliningMaxCalleeSize = new OptionValue<>(62);
+    public static final OptionValue<Integer> TruffleInliningMaxCalleeSize = new OptionValue<>(250);
     @Option(help = "")
     public static final OptionValue<Integer> TruffleInliningTrivialSize = new OptionValue<>(10);
     @Option(help = "")
@@ -79,8 +79,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleCacheDetails = new OptionValue<>(false);
     @Option(help = "")
-    public static final OptionValue<Boolean> TruffleInlinePrinter = new OptionValue<>(false);
-    @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleCompilationExceptions = new OptionValue<>(true);
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleCompilationExceptionsAreFatal = new OptionValue<>(true);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Wed Oct 16 18:27:28 2013 +0200
@@ -24,13 +24,13 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.*;
 import com.oracle.graal.graph.*;
 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.truffle.substitutions.*;
 
@@ -41,22 +41,14 @@
 
     private final Replacements graalReplacements;
 
-    private TruffleReplacements(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, LoweringProvider lowerer,
-                    Assumptions assumptions, TargetDescription target, Replacements graalReplacements) {
-        super(metaAccess, constantReflection, codeCache, foreignCalls, lowerer, assumptions, target);
-        this.graalReplacements = graalReplacements;
+    private TruffleReplacements(Providers providers) {
+        super(providers, providers.getReplacements().getAssumptions());
+        this.graalReplacements = providers.getReplacements();
     }
 
     static Replacements makeInstance() {
-        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
-        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
-        ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
-        ForeignCallsProvider foreignCalls = Graal.getRequiredCapability(ForeignCallsProvider.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, constantReflection, codeCache, foreignCalls, lowerer, graalReplacements.getAssumptions(), targetDescription,
-                        graalReplacements);
+        Providers graalProviders = GraalCompiler.getGraalProviders();
+        Replacements truffleReplacements = new TruffleReplacements(graalProviders);
 
         truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class);
         truffleReplacements.registerSubstitutions(CompilerDirectivesSubstitutions.class);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +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.truffle.nodes.frame;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.spi.*;
-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.type.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.nodes.*;
-import com.oracle.graal.truffle.substitutions.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Base node class for the intrinsic nodes for read and write access to a Truffle frame.
- */
-public abstract class FrameAccessNode extends FixedWithNextNode implements Simplifiable {
-
-    @Input private ValueNode frame;
-    @Input private ValueNode slot;
-    protected final ResolvedJavaField field;
-    protected final Kind slotKind;
-
-    public FrameAccessNode(Stamp stamp, Kind slotKind, ValueNode frame, ValueNode slot, ResolvedJavaField field) {
-        super(stamp);
-        this.slotKind = slotKind;
-        this.frame = frame;
-        this.slot = slot;
-        this.field = field;
-    }
-
-    public ValueNode getFrame() {
-        return frame;
-    }
-
-    public ValueNode getSlot() {
-        return slot;
-    }
-
-    public Kind getSlotKind() {
-        return slotKind;
-    }
-
-    protected int getSlotIndex() {
-        return getConstantFrameSlot().getIndex();
-    }
-
-    public boolean isConstantFrameSlot() {
-        return slot.isConstant() && !slot.isNullConstant();
-    }
-
-    protected FrameSlot getConstantFrameSlot() {
-        assert isConstantFrameSlot() : slot;
-        return (FrameSlot) slot.asConstant().asObject();
-    }
-
-    protected final void insertDeoptimization(VirtualizerTool tool) {
-        LogicNode contradiction = LogicConstantNode.contradiction(graph());
-        FixedGuardNode fixedGuard = new FixedGuardNode(contradiction, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile);
-        tool.addNode(fixedGuard);
-    }
-
-    @Override
-    public String toString(Verbosity verbosity) {
-        if (verbosity == Verbosity.Name) {
-            return super.toString(verbosity) + getSlotKind().name() + (slot != null && isConstantFrameSlot() ? " " + getConstantFrameSlot() : "");
-        } else {
-            return super.toString(verbosity);
-        }
-    }
-
-    protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccess) {
-        if (isConstantFrameSlot()) {
-            return ConstantNode.forInt(getSlotIndex() * scale, graph());
-        } else {
-            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()));
-        }
-    }
-
-    private static Field getFrameSlotIndexField() {
-        try {
-            return FrameSlotImpl.class.getDeclaredField("index");
-        } catch (NoSuchFieldException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    protected final boolean isValidAccessKind() {
-        if (isTagAccess()) {
-            return true;
-        }
-
-        return getSlotKind() == getGraalKind(getConstantFrameSlot().getKind());
-    }
-
-    protected final boolean isTagAccess() {
-        return field == FrameWithoutBoxingSubstitutions.TAGS_FIELD;
-    }
-
-    private static Kind getGraalKind(FrameSlotKind kind) {
-        switch (kind) {
-            case Object:
-                return Kind.Object;
-            case Long:
-                return Kind.Long;
-            case Int:
-                return Kind.Int;
-            case Byte:
-                return Kind.Byte;
-            case Double:
-                return Kind.Double;
-            case Float:
-                return Kind.Float;
-            case Boolean:
-                return Kind.Boolean;
-            case Illegal:
-            default:
-                return Kind.Illegal;
-        }
-    }
-
-    @Override
-    public final void simplify(SimplifierTool tool) {
-        if (isConstantFrameSlot()) {
-            if (!isValidAccessKind()) {
-                tool.deleteBranch(this.next());
-                this.replaceAndDelete(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode)));
-            } else {
-                tool.assumptions().record(new AssumptionValidAssumption((OptimizedAssumption) getConstantFrameSlot().getFrameDescriptor().getVersion()));
-            }
-        }
-    }
-
-    @Override
-    public Map<Object, Object> getDebugProperties(Map<Object, Object> map) {
-        Map<Object, Object> properties = super.getDebugProperties(map);
-        if (isTagAccess()) {
-            properties.put("slotKind", "Tag");
-        }
-        if (isConstantFrameSlot()) {
-            properties.put("frameSlot", getConstantFrameSlot().toString());
-        }
-        return properties;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +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.truffle.nodes.frame;
-
-import sun.misc.*;
-
-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.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.virtual.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Intrinsic node for read access to a Truffle frame.
- */
-@NodeInfo(nameTemplate = "FrameGet{p#slotKind/s}{p#frameSlot/s}")
-public class FrameGetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable {
-
-    public FrameGetNode(Kind kind, ValueNode frame, ValueNode slot, ResolvedJavaField field) {
-        super(StampFactory.forKind(kind), kind, frame, slot, field);
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        if (!isConstantFrameSlot()) {
-            return;
-        }
-        assert isValidAccessKind();
-        State virtualFrame = tool.getObjectState(getFrame());
-        if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) {
-            return;
-        }
-        assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame;
-        VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject();
-        int arrayFieldIndex = virtualFrameObject.fieldIndex(field);
-        State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex));
-        assert virtualArray != null;
-        ValueNode result = virtualArray.getEntry(getSlotIndex());
-        State virtualResult = tool.getObjectState(result);
-        if (virtualResult != null) {
-            tool.replaceWithVirtual(virtualResult.getVirtualObject());
-        } else {
-            tool.replaceWithValue(result);
-        }
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        assert !(getFrame() instanceof NewFrameNode);
-        StructuredGraph structuredGraph = graph();
-
-        LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field));
-        structuredGraph.addBeforeFixed(this, loadFieldNode);
-        FixedWithNextNode loadNode;
-        if (isTagAccess()) {
-            ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess());
-            loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, getSlotKind()));
-        } else if (!getSlotKind().isPrimitive()) {
-            ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess());
-            loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object));
-        } else {
-            ValueNode slotOffset = graph().unique(
-                            new IntegerAddNode(Kind.Long, getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getMetaAccess()), ConstantNode.forLong(Unsafe.ARRAY_LONG_BASE_OFFSET, graph())));
-            loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, slotOffset, getSlotKind()));
-        }
-        structuredGraph.replaceFixedWithFixed(this, loadNode);
-        loadFieldNode.lower(tool);
-        ((Lowerable) loadNode).lower(tool);
-    }
-
-    @NodeIntrinsic
-    public static native <T> T get(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, @ConstantNodeParameter ResolvedJavaField field);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +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.truffle.nodes.frame;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-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.nodes.virtual.*;
-import com.oracle.graal.truffle.*;
-import com.oracle.truffle.api.frame.*;
-
-/**
- * Intrinsic node for write access to a Truffle frame.
- */
-@NodeInfo(nameTemplate = "FrameSet{p#slotKind/s}{p#frameSlot/s}")
-public class FrameSetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable {
-
-    @Input private ValueNode value;
-
-    public FrameSetNode(Kind kind, ValueNode frame, ValueNode frameSlot, ValueNode value, ResolvedJavaField field) {
-        super(StampFactory.forVoid(), kind, frame, frameSlot, field);
-        this.value = value;
-    }
-
-    public ValueNode getValue() {
-        return value;
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        if (!isConstantFrameSlot()) {
-            return;
-        }
-        assert isValidAccessKind();
-        State virtualFrame = tool.getObjectState(getFrame());
-        if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) {
-            return;
-        }
-        assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame;
-        VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject();
-        int arrayFieldIndex = virtualFrameObject.fieldIndex(field);
-        State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex));
-        assert virtualArray != null;
-        ValueNode storedValue = value;
-        tool.setVirtualEntry(virtualArray, getSlotIndex(), storedValue);
-        tool.delete();
-    }
-
-    @Override
-    public void lower(LoweringTool tool) {
-        assert !(getFrame() instanceof NewFrameNode);
-        StructuredGraph structuredGraph = graph();
-
-        LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field));
-        structuredGraph.addBeforeFixed(this, loadFieldNode);
-        FixedWithNextNode storeNode;
-        ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess());
-        if (isTagAccess()) {
-            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, getSlotKind(), value));
-        } else if (!getSlotKind().isPrimitive()) {
-            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Object, value));
-        } else {
-            storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Long, value));
-        }
-        structuredGraph.replaceFixedWithFixed(this, storeNode);
-        loadFieldNode.lower(tool);
-        ((Lowerable) storeNode).lower(tool);
-    }
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, Object value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, byte value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, boolean value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, int value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, long value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, double value, @ConstantNodeParameter ResolvedJavaField field);
-
-    @NodeIntrinsic
-    public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, float value, @ConstantNodeParameter ResolvedJavaField field);
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -147,7 +147,7 @@
         ResolvedJavaField primitiveLocalsField = findField(frameFields, "primitiveLocals");
         ResolvedJavaField tagsField = findField(frameFields, "tags");
 
-        VirtualObjectNode virtualFrame = new VirtualOnlyInstanceNode(frameType, frameFields);
+        VirtualObjectNode virtualFrame = new VirtualInstanceNode(frameType, frameFields, false);
         VirtualObjectNode virtualFrameObjectArray = new VirtualArrayNode((ResolvedJavaType) localsField.getType().getComponentType(), frameSize);
         VirtualObjectNode virtualFramePrimitiveArray = new VirtualArrayNode((ResolvedJavaType) primitiveLocalsField.getType().getComponentType(), frameSize);
         VirtualObjectNode virtualFrameTagArray = new VirtualArrayNode((ResolvedJavaType) tagsField.getType().getComponentType(), frameSize);
@@ -186,8 +186,14 @@
     }
 
     private ValueNode initialValue(FrameSlotKind kind) {
-        Kind graalKind = Kind.Long;
+        Kind graalKind = null;
         switch (kind) {
+            case Boolean:
+                graalKind = Kind.Boolean;
+                break;
+            case Byte:
+                graalKind = Kind.Byte;
+                break;
             case Int:
                 graalKind = Kind.Int;
                 break;
@@ -197,9 +203,17 @@
             case Float:
                 graalKind = Kind.Float;
                 break;
-            case Boolean:
-                graalKind = Kind.Boolean;
+            case Long:
+                graalKind = Kind.Long;
+                break;
+            case Object:
+                graalKind = Kind.Object;
                 break;
+            case Illegal:
+                graalKind = Kind.Long;
+                break;
+            default:
+                throw new IllegalStateException("Unexpected frame slot kind: " + kind);
         }
 
         return ConstantNode.defaultForKind(graalKind, graph());
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -61,9 +61,11 @@
             } else {
                 locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
             }
-            return graph().add(
-                            new UnsafeLoadNode(objectArgument, offsetArgument, this.stamp().kind(), locationIdentity, CompareNode.createCompareNode(Condition.EQ, conditionArgument,
-                                            ConstantNode.forBoolean(true, graph()))));
+            Node result = graph().add(
+                            new UnsafeLoadNode(objectArgument, offsetArgument, this.getTargetMethod().getSignature().getReturnKind(), locationIdentity, CompareNode.createCompareNode(Condition.EQ,
+                                            conditionArgument, ConstantNode.forBoolean(true, graph()))));
+
+            return result;
         }
         return this;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -61,7 +61,8 @@
                 locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
             }
 
-            UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, valueArgument.kind(), locationIdentity));
+            UnsafeStoreNode unsafeStoreNode = graph().add(
+                            new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, this.getTargetMethod().getSignature().getParameterKind(VALUE_ARGUMENT_INDEX), locationIdentity));
             unsafeStoreNode.setStateAfter(this.stateAfter());
             return unsafeStoreNode;
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java	Wed Oct 16 18:27:28 2013 +0200
@@ -46,12 +46,6 @@
                     throw GraphUtil.approxSourceException(callTarget, exception);
                 }
             }
-            for (FrameAccessNode frameAccess : virtualFrame.usages().filter(FrameAccessNode.class)) {
-                if (!frameAccess.isConstantFrameSlot()) {
-                    Throwable exception = new VerificationError("Frame slot must be compile-time constant in virtual frame access at: %s frameSlot=%s", frameAccess, frameAccess.getSlot());
-                    throw GraphUtil.approxSourceException(frameAccess, exception);
-                }
-            }
         }
     }
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Wed Oct 16 18:27:28 2013 +0200
@@ -29,16 +29,18 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.nodes.*;
 import com.oracle.graal.truffle.nodes.typesystem.*;
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
 
 @ClassSubstitution(CompilerDirectives.class)
 public class CompilerDirectivesSubstitutions {
 
     @MethodSubstitution
     public static void transferToInterpreter() {
-        DeoptimizeNode.deopt(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode);
+        DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.UnreachedCode);
     }
 
     @MethodSubstitution
@@ -66,6 +68,11 @@
     @MacroSubstitution(macro = UnsafeTypeCastMacroNode.class, isStatic = true)
     public static native Object unsafeCast(Object value, Class clazz, boolean condition);
 
+    @MethodSubstitution
+    private static Class<? extends MaterializedFrame> getUnsafeFrameType() {
+        return FrameWithoutBoxing.class;
+    }
+
     @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
     public static native boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity);
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java	Wed Oct 16 18:27:28 2013 +0200
@@ -22,218 +22,15 @@
  */
 package com.oracle.graal.truffle.substitutions;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.nodes.*;
 import com.oracle.graal.truffle.*;
-import com.oracle.graal.truffle.nodes.frame.*;
-import com.oracle.truffle.api.frame.*;
 
 @ClassSubstitution(FrameWithoutBoxing.class)
 public class FrameWithoutBoxingSubstitutions {
 
-    private static final ResolvedJavaField LOCALS_FIELD;
-    private static final ResolvedJavaField PRIMITIVELOCALS_FIELD;
-    public static final ResolvedJavaField TAGS_FIELD;
-
-    static {
-        try {
-            MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class);
-            LOCALS_FIELD = runtime.lookupJavaField(FrameWithoutBoxing.class.getDeclaredField("locals"));
-            PRIMITIVELOCALS_FIELD = runtime.lookupJavaField(FrameWithoutBoxing.class.getDeclaredField("primitiveLocals"));
-            TAGS_FIELD = runtime.lookupJavaField(FrameWithoutBoxing.class.getDeclaredField("tags"));
-        } catch (NoSuchFieldException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     @SuppressWarnings("unused")
     @MethodSubstitution(isStatic = false, forced = true)
     public static Object pack(FrameWithoutBoxing frame) {
         return null;
     }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static Object getObject(FrameWithoutBoxing frame, FrameSlot slot) {
-        verifyGet(frame, slot, FrameSlotKind.Object);
-        return getObjectUnsafe(frame, slot);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static void setObject(FrameWithoutBoxing frame, FrameSlot slot, Object value) {
-        verifySet(frame, slot, FrameSlotKind.Object);
-        setObjectUnsafe(frame, slot, value);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static boolean getBoolean(FrameWithoutBoxing frame, FrameSlot slot) {
-        verifyGet(frame, slot, FrameSlotKind.Boolean);
-        return getBooleanUnsafe(frame, slot);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static void setBoolean(FrameWithoutBoxing frame, FrameSlot slot, boolean value) {
-        verifySet(frame, slot, FrameSlotKind.Boolean);
-        setBooleanUnsafe(frame, slot, value);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static byte getByte(FrameWithoutBoxing frame, FrameSlot slot) {
-        verifyGet(frame, slot, FrameSlotKind.Byte);
-        return getByteUnsafe(frame, slot);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static void setByte(FrameWithoutBoxing frame, FrameSlot slot, byte value) {
-        verifySet(frame, slot, FrameSlotKind.Byte);
-        setByteUnsafe(frame, slot, value);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static float getFloat(FrameWithoutBoxing frame, FrameSlot slot) {
-        verifyGet(frame, slot, FrameSlotKind.Float);
-        return getFloatUnsafe(frame, slot);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static void setFloat(FrameWithoutBoxing frame, FrameSlot slot, float value) {
-        verifySet(frame, slot, FrameSlotKind.Float);
-        setFloatUnsafe(frame, slot, value);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static long getLong(FrameWithoutBoxing frame, FrameSlot slot) {
-        verifyGet(frame, slot, FrameSlotKind.Long);
-        return getLongUnsafe(frame, slot);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static void setLong(FrameWithoutBoxing frame, FrameSlot slot, long value) {
-        verifySet(frame, slot, FrameSlotKind.Long);
-        setLongUnsafe(frame, slot, value);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static int getInt(FrameWithoutBoxing frame, FrameSlot slot) {
-        verifyGet(frame, slot, FrameSlotKind.Int);
-        return getIntUnsafe(frame, slot);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static void setInt(FrameWithoutBoxing frame, FrameSlot slot, int value) {
-        verifySet(frame, slot, FrameSlotKind.Int);
-        setIntUnsafe(frame, slot, value);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static double getDouble(FrameWithoutBoxing frame, FrameSlot slot) {
-        verifyGet(frame, slot, FrameSlotKind.Double);
-        return getDoubleUnsafe(frame, slot);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static void setDouble(FrameWithoutBoxing frame, FrameSlot slot, double value) {
-        verifySet(frame, slot, FrameSlotKind.Double);
-        setDoubleUnsafe(frame, slot, value);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static Object getObjectUnsafe(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Object, frame, slot, LOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void setObjectUnsafe(FrameWithoutBoxing frame, FrameSlot slot, Object value) {
-        FrameSetNode.set(Kind.Object, frame, slot, value, LOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static boolean getBooleanUnsafe(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Boolean, frame, slot, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void setBooleanUnsafe(FrameWithoutBoxing frame, FrameSlot slot, boolean value) {
-        FrameSetNode.set(Kind.Boolean, frame, slot, value, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static byte getByteUnsafe(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Byte, frame, slot, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void setByteUnsafe(FrameWithoutBoxing frame, FrameSlot slot, byte value) {
-        FrameSetNode.set(Kind.Byte, frame, slot, value, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static int getIntUnsafe(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Int, frame, slot, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void setIntUnsafe(FrameWithoutBoxing frame, FrameSlot slot, int value) {
-        FrameSetNode.set(Kind.Int, frame, slot, value, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static long getLongUnsafe(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Long, frame, slot, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void setLongUnsafe(FrameWithoutBoxing frame, FrameSlot slot, long value) {
-        FrameSetNode.set(Kind.Long, frame, slot, value, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static double getDoubleUnsafe(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Double, frame, slot, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void setDoubleUnsafe(FrameWithoutBoxing frame, FrameSlot slot, double value) {
-        FrameSetNode.set(Kind.Double, frame, slot, value, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static float getFloatUnsafe(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Float, frame, slot, PRIMITIVELOCALS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false)
-    public static void setFloatUnsafe(FrameWithoutBoxing frame, FrameSlot slot, float value) {
-        FrameSetNode.set(Kind.Float, frame, slot, value, PRIMITIVELOCALS_FIELD);
-    }
-
-    private static void verifySet(FrameWithoutBoxing frame, FrameSlot slot, FrameSlotKind accessType) {
-        setTag(frame, slot, (byte) accessType.ordinal());
-    }
-
-    private static void verifyGet(FrameWithoutBoxing frame, FrameSlot slot, FrameSlotKind accessType) {
-        byte tag = getTag(frame, slot);
-        if (accessType == FrameSlotKind.Object ? (tag & 0xfe) != 0 : tag != (byte) accessType.ordinal()) {
-            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode);
-        }
-    }
-
-    private static byte getTag(FrameWithoutBoxing frame, FrameSlot slot) {
-        return FrameGetNode.get(Kind.Byte, frame, slot, TAGS_FIELD);
-    }
-
-    private static void setTag(FrameWithoutBoxing frame, FrameSlot slot, byte tag) {
-        FrameSetNode.set(Kind.Byte, frame, slot, tag, TAGS_FIELD);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static MaterializedFrame materialize(FrameWithoutBoxing frame) {
-        return MaterializeFrameNode.materialize(frame);
-    }
-
-    @MethodSubstitution(isStatic = false, forced = true)
-    public static boolean isInitialized(FrameWithoutBoxing frame, FrameSlot slot) {
-        return getTag(frame, slot) != 0;
-    }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Wed Oct 16 18:27:28 2013 +0200
@@ -111,85 +111,6 @@
             return !(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode);
         }
         if (isMarked) {
-            if (node instanceof NodeWithState) {
-                NodeWithState nodeWithState = (NodeWithState) node;
-                FrameState stateAfter = nodeWithState.getState();
-                if (stateAfter != null) {
-                    if (stateAfter.usages().count() > 1) {
-                        if (nodeWithState instanceof StateSplit) {
-                            StateSplit split = (StateSplit) nodeWithState;
-                            stateAfter = (FrameState) stateAfter.copyWithInputs();
-                            split.setStateAfter(stateAfter);
-                        } else {
-                            throw GraalInternalError.shouldNotReachHere();
-                        }
-                    }
-                    final HashSet<ObjectState> virtual = new HashSet<>();
-                    stateAfter.applyToNonVirtual(new NodeClosure<ValueNode>() {
-
-                        @Override
-                        public void apply(Node usage, ValueNode value) {
-                            ObjectState valueObj = getObjectState(state, value);
-                            if (valueObj != null) {
-                                virtual.add(valueObj);
-                                effects.replaceFirstInput(usage, value, valueObj.virtual);
-                            } else if (value instanceof VirtualObjectNode) {
-                                ObjectState virtualObj = null;
-                                for (ObjectState obj : state.getStates()) {
-                                    if (value == obj.virtual) {
-                                        virtualObj = obj;
-                                        break;
-                                    }
-                                }
-                                if (virtualObj != null) {
-                                    virtual.add(virtualObj);
-                                }
-                            }
-                        }
-                    });
-                    for (ObjectState obj : state.getStates()) {
-                        if (obj.isVirtual() && obj.hasLocks()) {
-                            virtual.add(obj);
-                        }
-                    }
-
-                    ArrayDeque<ObjectState> queue = new ArrayDeque<>(virtual);
-                    while (!queue.isEmpty()) {
-                        ObjectState obj = queue.removeLast();
-                        if (obj.isVirtual()) {
-                            for (ValueNode field : obj.getEntries()) {
-                                if (field instanceof VirtualObjectNode) {
-                                    ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field);
-                                    if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) {
-                                        virtual.add(fieldObj);
-                                        queue.addLast(fieldObj);
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    for (ObjectState obj : virtual) {
-                        EscapeObjectState v;
-                        if (obj.isVirtual()) {
-                            ValueNode[] fieldState = obj.getEntries().clone();
-                            for (int i = 0; i < fieldState.length; i++) {
-                                ObjectState valueObj = getObjectState(state, fieldState[i]);
-                                if (valueObj != null) {
-                                    if (valueObj.isVirtual()) {
-                                        fieldState[i] = valueObj.virtual;
-                                    } else {
-                                        fieldState[i] = valueObj.getMaterializedValue();
-                                    }
-                                }
-                            }
-                            v = new VirtualObjectState(obj.virtual, fieldState);
-                        } else {
-                            v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue());
-                        }
-                        effects.addVirtualMapping(stateAfter, v);
-                    }
-                }
-            }
             for (ValueNode input : node.inputs().filter(ValueNode.class)) {
                 ObjectState obj = getObjectState(state, input);
                 if (obj != null) {
@@ -201,10 +122,92 @@
                     replaceWithMaterialized(input, node, insertBefore, state, obj, effects, METRIC_MATERIALIZATIONS_UNHANDLED);
                 }
             }
+            if (node instanceof NodeWithState) {
+                processNodeWithState((NodeWithState) node, state, effects);
+            }
         }
         return false;
     }
 
+    private void processNodeWithState(NodeWithState nodeWithState, final BlockT state, final GraphEffectList effects) {
+        FrameState stateAfter = nodeWithState.getState();
+        if (stateAfter != null) {
+            if (stateAfter.usages().count() > 1) {
+                if (nodeWithState instanceof StateSplit) {
+                    StateSplit split = (StateSplit) nodeWithState;
+                    stateAfter = (FrameState) stateAfter.copyWithInputs();
+                    split.setStateAfter(stateAfter);
+                } else {
+                    throw GraalInternalError.shouldNotReachHere();
+                }
+            }
+            final HashSet<ObjectState> virtual = new HashSet<>();
+            stateAfter.applyToNonVirtual(new NodeClosure<ValueNode>() {
+
+                @Override
+                public void apply(Node usage, ValueNode value) {
+                    ObjectState valueObj = getObjectState(state, value);
+                    if (valueObj != null) {
+                        virtual.add(valueObj);
+                        effects.replaceFirstInput(usage, value, valueObj.virtual);
+                    } else if (value instanceof VirtualObjectNode) {
+                        ObjectState virtualObj = null;
+                        for (ObjectState obj : state.getStates()) {
+                            if (value == obj.virtual) {
+                                virtualObj = obj;
+                                break;
+                            }
+                        }
+                        if (virtualObj != null) {
+                            virtual.add(virtualObj);
+                        }
+                    }
+                }
+            });
+            for (ObjectState obj : state.getStates()) {
+                if (obj.isVirtual() && obj.hasLocks()) {
+                    virtual.add(obj);
+                }
+            }
+
+            ArrayDeque<ObjectState> queue = new ArrayDeque<>(virtual);
+            while (!queue.isEmpty()) {
+                ObjectState obj = queue.removeLast();
+                if (obj.isVirtual()) {
+                    for (ValueNode field : obj.getEntries()) {
+                        if (field instanceof VirtualObjectNode) {
+                            ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field);
+                            if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) {
+                                virtual.add(fieldObj);
+                                queue.addLast(fieldObj);
+                            }
+                        }
+                    }
+                }
+            }
+            for (ObjectState obj : virtual) {
+                EscapeObjectState v;
+                if (obj.isVirtual()) {
+                    ValueNode[] fieldState = obj.getEntries().clone();
+                    for (int i = 0; i < fieldState.length; i++) {
+                        ObjectState valueObj = getObjectState(state, fieldState[i]);
+                        if (valueObj != null) {
+                            if (valueObj.isVirtual()) {
+                                fieldState[i] = valueObj.virtual;
+                            } else {
+                                fieldState[i] = valueObj.getMaterializedValue();
+                            }
+                        }
+                    }
+                    v = new VirtualObjectState(obj.virtual, fieldState);
+                } else {
+                    v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue());
+                }
+                effects.addVirtualMapping(stateAfter, v);
+            }
+        }
+    }
+
     private void ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
         assert obj != null;
         if (obj.getState() == EscapeState.Virtual) {
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java	Wed Oct 16 18:27:28 2013 +0200
@@ -657,9 +657,7 @@
 
     @Override
     @Operation(opcode = Opcode.READ)
-    public Object readObject(WordBase offset, LocationIdentity locationIdentity) {
-        return unsafe.getObject(null, add((Word) offset).unbox());
-    }
+    public native Object readObject(WordBase offset, LocationIdentity locationIdentity);
 
     @Override
     @Operation(opcode = Opcode.READ)
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -115,14 +115,11 @@
         Object execute(VirtualFrame frame) {
             Object o = value.execute(frame);
             if (o instanceof Integer) {
-                try {
-                    frame.setInt(slot, (Integer) o);
-                } catch (FrameSlotTypeException e) {
-                    // fall through
-                }
+                frame.setInt(slot, (Integer) o);
+            } else {
+                frame.setObject(slot, o);
+                this.replace(new ObjectAssignLocal(slot, value));
             }
-            frame.setObject(slot, o);
-            this.replace(new ObjectAssignLocal(slot, value));
             return null;
         }
     }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -114,11 +114,7 @@
 
         @Override
         int execute(VirtualFrame frame) {
-            try {
-                frame.setInt(slot, 42);
-            } catch (FrameSlotTypeException e) {
-                throw new IllegalStateException(e);
-            }
+            frame.setInt(slot, 42);
             return 0;
         }
     }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java	Wed Oct 16 18:27:28 2013 +0200
@@ -122,12 +122,7 @@
         Object execute(VirtualFrame frame) {
             try {
                 int result = value.executeInt(frame);
-                try {
-                    frame.setInt(slot, result);
-                } catch (FrameSlotTypeException e) {
-                    frame.setObject(slot, result);
-                    replace(new ObjectAssignLocal(slot, value));
-                }
+                frame.setInt(slot, result);
             } catch (UnexpectedResultException e) {
                 frame.setObject(slot, e.getResult());
                 replace(new ObjectAssignLocal(slot, value));
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Oct 16 18:27:28 2013 +0200
@@ -28,6 +28,8 @@
 import java.lang.reflect.*;
 import java.util.concurrent.*;
 
+import com.oracle.truffle.api.frame.*;
+
 import sun.misc.*;
 
 /**
@@ -165,6 +167,20 @@
     }
 
     /**
+     * Asserts that this value is not null and retrieved from a call to Frame.materialize.
+     * 
+     * @param value the value that is known to have been obtained via Frame.materialize
+     * @return the value to be casted to the new type
+     */
+    public static MaterializedFrame unsafeFrameCast(MaterializedFrame value) {
+        return unsafeCast(value, getUnsafeFrameType(), true);
+    }
+
+    private static Class<? extends MaterializedFrame> getUnsafeFrameType() {
+        return MaterializedFrame.class;
+    }
+
+    /**
      * Unsafe access to a boolean value within an object. The condition parameter gives a hint to
      * the compiler under which circumstances this access can be moved to an earlier location in the
      * program. The location identity gives a hint to the compiler for improved global value
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Wed Oct 16 18:27:28 2013 +0200
@@ -70,6 +70,7 @@
      * 
      * @param slot the slot of the local variable
      * @return the current value of the local variable
+     * @throws FrameSlotTypeException
      */
     byte getByte(FrameSlot slot) throws FrameSlotTypeException;
 
@@ -80,7 +81,7 @@
      * @param value the new value of the local variable
      */
 
-    void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException;
+    void setByte(FrameSlot slot, byte value);
 
     /**
      * Read access to a local variable of type boolean.
@@ -96,7 +97,7 @@
      * @param slot the slot of the local variable
      * @param value the new value of the local variable
      */
-    void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException;
+    void setBoolean(FrameSlot slot, boolean value);
 
     /**
      * Read access to a local variable of type int.
@@ -112,7 +113,7 @@
      * @param slot the slot of the local variable
      * @param value the new value of the local variable
      */
-    void setInt(FrameSlot slot, int value) throws FrameSlotTypeException;
+    void setInt(FrameSlot slot, int value);
 
     /**
      * Read access to a local variable of type long.
@@ -128,7 +129,7 @@
      * @param slot the slot of the local variable
      * @param value the new value of the local variable
      */
-    void setLong(FrameSlot slot, long value) throws FrameSlotTypeException;
+    void setLong(FrameSlot slot, long value);
 
     /**
      * Read access to a local variable of type float.
@@ -144,7 +145,7 @@
      * @param slot the slot of the local variable
      * @param value the new value of the local variable
      */
-    void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException;
+    void setFloat(FrameSlot slot, float value);
 
     /**
      * Read access to a local variable of type double.
@@ -160,7 +161,7 @@
      * @param slot the slot of the local variable
      * @param value the new value of the local variable
      */
-    void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException;
+    void setDouble(FrameSlot slot, double value);
 
     /**
      * Read access to a local variable of any type.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java	Wed Oct 16 18:27:28 2013 +0200
@@ -29,7 +29,7 @@
     private final FrameDescriptor descriptor;
     private final Object identifier;
     private final int index;
-    private FrameSlotKind kind;
+    @com.oracle.truffle.api.CompilerDirectives.CompilationFinal private FrameSlotKind kind;
 
     public FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, FrameSlotKind kind) {
         this.descriptor = descriptor;
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java	Wed Oct 16 18:27:28 2013 +0200
@@ -25,5 +25,5 @@
 package com.oracle.truffle.api.frame;
 
 public enum FrameSlotKind {
-    Illegal, Object, Long, Int, Double, Float, Boolean, Byte;
+    Object, Illegal, Long, Int, Double, Float, Boolean, Byte;
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java	Wed Oct 16 18:27:28 2013 +0200
@@ -47,14 +47,7 @@
      * @param value the new value of the local variable
      */
     public static void setByteSafe(Frame frame, FrameSlot slot, byte value) {
-        if (slot.getKind() != FrameSlotKind.Byte) {
-            slot.setKind(FrameSlotKind.Byte);
-        }
-        try {
-            frame.setByte(slot, value);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
+        frame.setByte(slot, value);
     }
 
     /**
@@ -66,14 +59,7 @@
      * @param value the new value of the local variable
      */
     public static void setBooleanSafe(Frame frame, FrameSlot slot, boolean value) {
-        if (slot.getKind() != FrameSlotKind.Boolean) {
-            slot.setKind(FrameSlotKind.Boolean);
-        }
-        try {
-            frame.setBoolean(slot, value);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
+        frame.setBoolean(slot, value);
     }
 
     /**
@@ -85,14 +71,7 @@
      * @param value the new value of the local variable
      */
     public static void setIntSafe(Frame frame, FrameSlot slot, int value) {
-        if (slot.getKind() != FrameSlotKind.Int) {
-            slot.setKind(FrameSlotKind.Int);
-        }
-        try {
-            frame.setInt(slot, value);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
+        frame.setInt(slot, value);
     }
 
     /**
@@ -104,14 +83,7 @@
      * @param value the new value of the local variable
      */
     public static void setLongSafe(Frame frame, FrameSlot slot, long value) {
-        if (slot.getKind() != FrameSlotKind.Long) {
-            slot.setKind(FrameSlotKind.Long);
-        }
-        try {
-            frame.setLong(slot, value);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
+        frame.setLong(slot, value);
     }
 
     /**
@@ -123,14 +95,7 @@
      * @param value the new value of the local variable
      */
     public static void setFloatSafe(Frame frame, FrameSlot slot, float value) {
-        if (slot.getKind() != FrameSlotKind.Float) {
-            slot.setKind(FrameSlotKind.Float);
-        }
-        try {
-            frame.setFloat(slot, value);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
+        frame.setFloat(slot, value);
     }
 
     /**
@@ -142,13 +107,6 @@
      * @param value the new value of the local variable
      */
     public static void setDoubleSafe(Frame frame, FrameSlot slot, double value) {
-        if (slot.getKind() != FrameSlotKind.Double) {
-            slot.setKind(FrameSlotKind.Double);
-        }
-        try {
-            frame.setDouble(slot, value);
-        } catch (FrameSlotTypeException e) {
-            throw new IllegalStateException();
-        }
+        frame.setDouble(slot, value);
     }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultFrameTypeConversion.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultFrameTypeConversion.java	Wed Oct 16 18:27:28 2013 +0200
@@ -40,6 +40,9 @@
 
     @Override
     public void updateFrameSlot(Frame frame, FrameSlot slot, Object value) {
+        if (slot.getKind() != FrameSlotKind.Object) {
+            slot.setKind(FrameSlotKind.Object);
+        }
         frame.setObject(slot, value);
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java	Wed Oct 16 18:27:28 2013 +0200
@@ -56,7 +56,7 @@
     }
 
     @Override
-    public void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException {
+    public void setByte(FrameSlot slot, byte value) {
         wrapped.setByte(slot, value);
     }
 
@@ -66,7 +66,7 @@
     }
 
     @Override
-    public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException {
+    public void setBoolean(FrameSlot slot, boolean value) {
         wrapped.setBoolean(slot, value);
     }
 
@@ -76,7 +76,7 @@
     }
 
     @Override
-    public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException {
+    public void setInt(FrameSlot slot, int value) {
         wrapped.setInt(slot, value);
     }
 
@@ -86,7 +86,7 @@
     }
 
     @Override
-    public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException {
+    public void setLong(FrameSlot slot, long value) {
         wrapped.setLong(slot, value);
     }
 
@@ -96,7 +96,7 @@
     }
 
     @Override
-    public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException {
+    public void setFloat(FrameSlot slot, float value) {
         wrapped.setFloat(slot, value);
     }
 
@@ -106,7 +106,7 @@
     }
 
     @Override
-    public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException {
+    public void setDouble(FrameSlot slot, double value) {
         wrapped.setDouble(slot, value);
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java	Wed Oct 16 18:27:28 2013 +0200
@@ -75,7 +75,7 @@
 
     @Override
     public void setObject(FrameSlot slot, Object value) {
-        verifySetObject(slot);
+        verifySet(slot, FrameSlotKind.Object);
         locals[slot.getIndex()] = value;
     }
 
@@ -86,7 +86,7 @@
     }
 
     @Override
-    public void setByte(FrameSlot slot, byte value) throws FrameSlotTypeException {
+    public void setByte(FrameSlot slot, byte value) {
         verifySet(slot, FrameSlotKind.Byte);
         locals[slot.getIndex()] = value;
     }
@@ -98,7 +98,7 @@
     }
 
     @Override
-    public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException {
+    public void setBoolean(FrameSlot slot, boolean value) {
         verifySet(slot, FrameSlotKind.Boolean);
         locals[slot.getIndex()] = value;
     }
@@ -110,7 +110,7 @@
     }
 
     @Override
-    public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException {
+    public void setInt(FrameSlot slot, int value) {
         verifySet(slot, FrameSlotKind.Int);
         locals[slot.getIndex()] = value;
     }
@@ -122,7 +122,7 @@
     }
 
     @Override
-    public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException {
+    public void setLong(FrameSlot slot, long value) {
         verifySet(slot, FrameSlotKind.Long);
         locals[slot.getIndex()] = value;
     }
@@ -134,7 +134,7 @@
     }
 
     @Override
-    public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException {
+    public void setFloat(FrameSlot slot, float value) {
         verifySet(slot, FrameSlotKind.Float);
         locals[slot.getIndex()] = value;
     }
@@ -146,7 +146,7 @@
     }
 
     @Override
-    public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException {
+    public void setDouble(FrameSlot slot, double value) {
         verifySet(slot, FrameSlotKind.Double);
         locals[slot.getIndex()] = value;
     }
@@ -165,15 +165,7 @@
         return locals[slotIndex];
     }
 
-    private void verifySet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
-        FrameSlotKind slotKind = slot.getKind();
-        if (slotKind != accessKind) {
-            if (slotKind == FrameSlotKind.Illegal) {
-                slot.setKind(accessKind);
-            } else {
-                throw new FrameSlotTypeException();
-            }
-        }
+    private void verifySet(FrameSlot slot, FrameSlotKind accessKind) {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
             resize();
@@ -181,24 +173,13 @@
         tags[slotIndex] = (byte) accessKind.ordinal();
     }
 
-    private void verifySetObject(FrameSlot slot) {
-        if (slot.getKind() != FrameSlotKind.Object) {
-            slot.setKind(FrameSlotKind.Object);
-        }
-        int slotIndex = slot.getIndex();
-        if (slotIndex >= tags.length) {
-            resize();
-        }
-        tags[slotIndex] = (byte) FrameSlotKind.Object.ordinal();
-    }
-
     private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException {
         int slotIndex = slot.getIndex();
         if (slotIndex >= tags.length) {
             resize();
         }
         byte tag = tags[slotIndex];
-        if (accessKind == FrameSlotKind.Object ? (tag & 0xfe) != 0 : tag != accessKind.ordinal()) {
+        if (accessKind == FrameSlotKind.Object ? tag != 0 : tag != accessKind.ordinal()) {
             if (slot.getKind() == accessKind || tag == 0) {
                 descriptor.getTypeConversion().updateFrameSlot(this, slot, getValue(slot));
                 if (tags[slotIndex] == accessKind.ordinal()) {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java	Wed Oct 16 18:27:11 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java	Wed Oct 16 18:27:28 2013 +0200
@@ -36,14 +36,14 @@
         this(node.slot);
     }
 
-    @Specialization(rewriteOn = FrameSlotTypeException.class)
-    public int write(VirtualFrame frame, int right) throws FrameSlotTypeException {
+    @Specialization
+    public int write(VirtualFrame frame, int right) {
         frame.setInt(slot, right);
         return right;
     }
 
-    @Specialization(rewriteOn = FrameSlotTypeException.class)
-    public boolean write(VirtualFrame frame, boolean right) throws FrameSlotTypeException {
+    @Specialization
+    public boolean write(VirtualFrame frame, boolean right) {
         frame.setBoolean(slot, right);
         return right;
     }
--- a/make/bsd/makefiles/fastdebug.make	Wed Oct 16 18:27:11 2013 +0200
+++ b/make/bsd/makefiles/fastdebug.make	Wed Oct 16 18:27:28 2013 +0200
@@ -59,6 +59,5 @@
 MAPFILE = $(GAMMADIR)/make/bsd/makefiles/mapfile-vers-debug
 
 VERSION = fastdebug
-#SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
-SYSDEFS += -DASSERT
+SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
 PICFLAGS = DEFAULT
--- a/make/linux/makefiles/fastdebug.make	Wed Oct 16 18:27:11 2013 +0200
+++ b/make/linux/makefiles/fastdebug.make	Wed Oct 16 18:27:28 2013 +0200
@@ -59,6 +59,5 @@
 MAPFILE = $(GAMMADIR)/make/linux/makefiles/mapfile-vers-debug
 
 VERSION = optimized
-#SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
-SYSDEFS += -DASSERT
+SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
 PICFLAGS = DEFAULT
--- a/make/solaris/makefiles/fastdebug.make	Wed Oct 16 18:27:11 2013 +0200
+++ b/make/solaris/makefiles/fastdebug.make	Wed Oct 16 18:27:28 2013 +0200
@@ -126,6 +126,5 @@
 MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
 
 VERSION = optimized
-#SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
-SYSDEFS += -DASSERT
+SYSDEFS += -DASSERT -DCHECK_UNHANDLED_OOPS
 PICFLAGS = DEFAULT
--- a/make/windows/makefiles/fastdebug.make	Wed Oct 16 18:27:11 2013 +0200
+++ b/make/windows/makefiles/fastdebug.make	Wed Oct 16 18:27:28 2013 +0200
@@ -38,8 +38,7 @@
 !include ../local.make
 !include compile.make
 
-#CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION) /D "CHECK_UNHANDLED_OOPS"
-CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION)
+CXX_FLAGS=$(CXX_FLAGS) $(FASTDEBUG_OPT_OPTION) /D "CHECK_UNHANDLED_OOPS"
 
 !include $(WorkSpace)/make/windows/makefiles/vm.make
 !include local.make
--- a/mx/commands.py	Wed Oct 16 18:27:11 2013 +0200
+++ b/mx/commands.py	Wed Oct 16 18:27:28 2013 +0200
@@ -955,12 +955,11 @@
         vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
         tasks.append(t.stop())
 
-    # temporarily disable G1 verification until merge issues are resolved
-    # with VM('graal', 'product'):
-    #     t = Task('BootstrapWithG1GCVerification:product')
-    #     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'):
+        t = Task('BootstrapWithG1GCVerification:product')
+        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'):
         t = Task('BootstrapWithRegisterPressure:product')
--- a/mx/projects	Wed Oct 16 18:27:11 2013 +0200
+++ b/mx/projects	Wed Oct 16 18:27:28 2013 +0200
@@ -28,7 +28,7 @@
 library@OKRA@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.2.jar
 
 distribution@GRAAL@path=graal.jar
-distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.hotspot.ptx,com.oracle.graal.truffle,com.oracle.graal.truffle.printer,com.oracle.graal.hotspot.sparc,com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail
+distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.hotspot.ptx,com.oracle.graal.truffle,com.oracle.graal.hotspot.sparc,com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail
 
 # graal.api.runtime
 project@com.oracle.graal.api.runtime@subDir=graal
@@ -143,6 +143,15 @@
 project@com.oracle.graal.hotspot.ptx@javaCompliance=1.7
 project@com.oracle.graal.hotspot.ptx@workingSets=Graal,HotSpot,PTX
 
+# graal.hotspot.hsail
+project@com.oracle.graal.hotspot.hsail@subDir=graal
+project@com.oracle.graal.hotspot.hsail@sourceDirs=src
+project@com.oracle.graal.hotspot.hsail@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail
+project@com.oracle.graal.hotspot.hsail@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.hotspot.hsail@annotationProcessors=com.oracle.graal.service.processor
+project@com.oracle.graal.hotspot.hsail@javaCompliance=1.7
+project@com.oracle.graal.hotspot.hsail@workingSets=Graal,HotSpot,PTX
+
 # graal.hotspot.server
 project@com.oracle.graal.hotspot.server@subDir=graal
 project@com.oracle.graal.hotspot.server@sourceDirs=src
@@ -511,14 +520,14 @@
 # graal.compiler.hsail
 project@com.oracle.graal.compiler.hsail@subDir=graal
 project@com.oracle.graal.compiler.hsail@sourceDirs=src
-project@com.oracle.graal.compiler.hsail@dependencies=com.oracle.graal.lir.hsail,com.oracle.graal.hotspot.amd64
+project@com.oracle.graal.compiler.hsail@dependencies=com.oracle.graal.compiler,com.oracle.graal.lir.hsail
 project@com.oracle.graal.compiler.hsail@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler.hsail@javaCompliance=1.7
 
 # graal.compiler.hsail.test.infra - HSAIL compiler test infrastructure
 project@com.oracle.graal.compiler.hsail.test.infra@subDir=graal
 project@com.oracle.graal.compiler.hsail.test.infra@sourceDirs=src
-project@com.oracle.graal.compiler.hsail.test.infra@dependencies=com.oracle.graal.compiler.hsail,JUNIT
+project@com.oracle.graal.compiler.hsail.test.infra@dependencies=com.oracle.graal.hotspot.hsail,JUNIT
 project@com.oracle.graal.compiler.hsail.test.infra@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler.hsail.test.infra@javaCompliance=1.7
 
@@ -613,7 +622,7 @@
 # graal.truffle
 project@com.oracle.graal.truffle@subDir=graal
 project@com.oracle.graal.truffle@sourceDirs=src
-project@com.oracle.graal.truffle@dependencies=com.oracle.truffle.api,com.oracle.graal.truffle.printer,com.oracle.graal.hotspot
+project@com.oracle.graal.truffle@dependencies=com.oracle.truffle.api,com.oracle.graal.hotspot
 project@com.oracle.graal.truffle@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.truffle@javaCompliance=1.7
 project@com.oracle.graal.truffle@workingSets=Graal,Truffle
@@ -626,12 +635,4 @@
 project@com.oracle.graal.truffle.test@javaCompliance=1.7
 project@com.oracle.graal.truffle.test@workingSets=Graal,Truffle,Test
 
-# graal.truffle.printer
-project@com.oracle.graal.truffle.printer@subDir=graal
-project@com.oracle.graal.truffle.printer@sourceDirs=src
-project@com.oracle.graal.truffle.printer@dependencies=com.oracle.graal.nodes
-project@com.oracle.graal.truffle.printer@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.truffle.printer@javaCompliance=1.7
-project@com.oracle.graal.truffle.printer@workingSets=Graal,Truffle
 
-
--- a/mxtool/mx.py	Wed Oct 16 18:27:11 2013 +0200
+++ b/mxtool/mx.py	Wed Oct 16 18:27:28 2013 +0200
@@ -2675,7 +2675,8 @@
 
         if _isAnnotationProcessorDependency(p):
             _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh=False, async=False, xmlIndent='', xmlStandalone='no')
-            _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh=True, async=True)
+            # Refresh.launch seems to cause occasional build looping in Eclipse
+            # _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh=True, async=True)
 
         if projToDist.has_key(p.name):
             dist, distDeps = projToDist[p.name]
--- a/src/cpu/x86/vm/templateInterpreter_x86.hpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/cpu/x86/vm/templateInterpreter_x86.hpp	Wed Oct 16 18:27:28 2013 +0200
@@ -34,7 +34,7 @@
   // Run with +PrintInterpreter to get the VM to print out the size.
   // Max size with JVMTI
 #ifdef AMD64
-  const static int InterpreterCodeSize = 240 * 1024;
+  const static int InterpreterCodeSize = GRAAL_ONLY(256) NOT_GRAAL(208) * 1024;
 #else
   const static int InterpreterCodeSize = 176 * 1024;
 #endif // AMD64
--- a/src/share/vm/code/nmethod.cpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/share/vm/code/nmethod.cpp	Wed Oct 16 18:27:28 2013 +0200
@@ -1405,13 +1405,6 @@
     // cache call.
     if (!is_osr_method() && !is_not_entrant()) {
       address stub = SharedRuntime::get_handle_wrong_method_stub();
-#ifdef GRAAL
-      if (_graal_installed_code != NULL) {
-        // Break the link between nmethod and HotSpotInstalledCode such that the nmethod can subsequently be flushed safely.
-        HotSpotInstalledCode::set_codeBlob(_graal_installed_code, 0);
-        _graal_installed_code = NULL;
-      }
-#endif
       NativeJump::patch_verified_entry(entry_point(), verified_entry_point(), stub);
     }
 
@@ -1491,6 +1484,12 @@
   } else {
     assert(state == not_entrant, "other cases may need to be handled differently");
   }
+#ifdef GRAAL
+      if (_graal_installed_code != NULL) {
+        // Break the link between nmethod and HotSpotInstalledCode such that the nmethod can subsequently be flushed safely.
+        HotSpotInstalledCode::set_codeBlob(_graal_installed_code, 0);
+      }
+#endif
 
   if (TraceCreateZombies) {
     ResourceMark m;
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Oct 16 18:27:28 2013 +0200
@@ -1132,6 +1132,7 @@
     VM_Deoptimize op;
     VMThread::execute(&op);
   }
+  HotSpotInstalledCode::set_codeBlob(hotspotInstalledCode, 0);
 C2V_END
 
 
--- a/src/share/vm/graal/graalGlobals.hpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/share/vm/graal/graalGlobals.hpp	Wed Oct 16 18:27:28 2013 +0200
@@ -55,7 +55,7 @@
   product(intx, TraceGraal, 0,                                              \
           "Trace level for Graal")                                          \
                                                                             \
-  product(bool, GraalDeferredInitBarriers, false,                           \
+  product(bool, GraalDeferredInitBarriers, true,                            \
           "Defer write barriers of young objects")                          \
                                                                             \
   develop(bool, GraalUseFastLocking, true,                                  \
--- a/src/share/vm/graal/graalRuntime.cpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Wed Oct 16 18:27:28 2013 +0200
@@ -56,7 +56,8 @@
   }
 }
 
-JRT_ENTRY(void, GraalRuntime::new_instance(JavaThread* thread, Klass* klass))
+JRT_BLOCK_ENTRY(void, GraalRuntime::new_instance(JavaThread* thread, Klass* klass))
+  JRT_BLOCK;
   assert(klass->is_klass(), "not a class");
   instanceKlassHandle h(thread, klass);
   h->check_valid_for_instantiation(true, CHECK);
@@ -64,13 +65,16 @@
   h->initialize(CHECK);
   // allocate instance and return via TLS
   oop obj = h->allocate_instance(CHECK);
+  thread->set_vm_result(obj);
+  JRT_BLOCK_END;
+
   if (GraalDeferredInitBarriers) {
-    obj = Universe::heap()->new_store_pre_barrier(thread, obj);
+    new_store_pre_barrier(thread);
   }
-  thread->set_vm_result(obj);
 JRT_END
 
-JRT_ENTRY(void, GraalRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length))
+JRT_BLOCK_ENTRY(void, GraalRuntime::new_array(JavaThread* thread, Klass* array_klass, jint length))
+  JRT_BLOCK;
   // Note: no handle for klass needed since they are not used
   //       anymore after new_objArray() and no GC can happen before.
   //       (This may have to change if this code changes!)
@@ -83,9 +87,6 @@
     Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
     obj = oopFactory::new_objArray(elem_klass, length, CHECK);
   }
-  if (GraalDeferredInitBarriers) {
-    obj = Universe::heap()->new_store_pre_barrier(thread, obj);
-  }
   thread->set_vm_result(obj);
   // This is pretty rare but this runtime patch is stressful to deoptimization
   // if we deoptimize here so force a deopt to stress the path.
@@ -99,8 +100,30 @@
       deopt_caller();
     }
   }
+  JRT_BLOCK_END;
+
+  if (GraalDeferredInitBarriers) {
+    new_store_pre_barrier(thread);
+  }
 JRT_END
 
+void GraalRuntime::new_store_pre_barrier(JavaThread* thread) {
+  // After any safepoint, just before going back to compiled code,
+  // we inform the GC that we will be doing initializing writes to
+  // this object in the future without emitting card-marks, so
+  // GC may take any compensating steps.
+  // NOTE: Keep this code consistent with GraphKit::store_barrier.
+
+  oop new_obj = thread->vm_result();
+  if (new_obj == NULL)  return;
+
+  assert(Universe::heap()->can_elide_tlab_store_barriers(),
+         "compiler must check this first");
+  // GC may decide to give back a safer copy of new_obj.
+  new_obj = Universe::heap()->new_store_pre_barrier(thread, new_obj);
+  thread->set_vm_result(new_obj);
+}
+
 JRT_ENTRY(void, GraalRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
   assert(klass->is_klass(), "not a class");
   assert(rank >= 1, "rank must be nonzero");
@@ -108,7 +131,7 @@
   thread->set_vm_result(obj);
 JRT_END
 
-JRT_ENTRY(void, GraalRuntime::dynamic_new_array(JavaThread* thread, oop element_mirror, jint length))
+JRT_ENTRY(void, GraalRuntime::dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length))
   oop obj = Reflection::reflect_new_array(element_mirror, length, CHECK);
   thread->set_vm_result(obj);
 JRT_END
@@ -348,7 +371,7 @@
   }
 JRT_END
 
-JRT_ENTRY(void, GraalRuntime::log_object(JavaThread* thread, oop obj, jint flags))
+JRT_ENTRY(void, GraalRuntime::log_object(JavaThread* thread, oopDesc* obj, jint flags))
   bool string =  mask_bits_are_true(flags, LOG_OBJECT_STRING);
   bool addr = mask_bits_are_true(flags, LOG_OBJECT_ADDRESS);
   bool newline = mask_bits_are_true(flags, LOG_OBJECT_NEWLINE);
@@ -393,7 +416,7 @@
   return (jint)ret;
 JRT_END
 
-JRT_ENTRY(void, GraalRuntime::vm_error(JavaThread* thread, oop where, oop format, jlong value))
+JRT_ENTRY(void, GraalRuntime::vm_error(JavaThread* thread, oopDesc* where, oopDesc* format, jlong value))
   ResourceMark rm;
   assert(where == NULL || java_lang_String::is_instance(where), "must be");
   const char *error_msg = where == NULL ? "<internal Graal error>" : java_lang_String::as_utf8_string(where);
@@ -407,7 +430,7 @@
   report_vm_error(__FILE__, __LINE__, error_msg, detail_msg);
 JRT_END
 
-JRT_LEAF(oop, GraalRuntime::load_and_clear_exception(JavaThread* thread))
+JRT_LEAF(oopDesc*, GraalRuntime::load_and_clear_exception(JavaThread* thread))
   oop exception = thread->exception_oop();
   assert(exception != NULL, "npe");
   thread->set_exception_oop(NULL);
@@ -415,7 +438,7 @@
   return exception;
 JRT_END
 
-JRT_LEAF(void, GraalRuntime::log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3))
+JRT_LEAF(void, GraalRuntime::log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3))
   ResourceMark rm;
   assert(format != NULL && java_lang_String::is_instance(format), "must be");
   char *buf = java_lang_String::as_utf8_string(format);
@@ -485,14 +508,14 @@
   }
 JRT_END
 
-JRT_ENTRY(jint, GraalRuntime::identity_hash_code(JavaThread* thread, oop obj))
+JRT_ENTRY(jint, GraalRuntime::identity_hash_code(JavaThread* thread, oopDesc* obj))
   return (jint) obj->identity_hash();
 JRT_END
 
-JRT_ENTRY(jboolean, GraalRuntime::thread_is_interrupted(JavaThread* thread, oop receiver, jboolean clear_interrupted))
+JRT_ENTRY(jboolean, GraalRuntime::thread_is_interrupted(JavaThread* thread, oopDesc* receiver, jboolean clear_interrupted))
   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
   Handle receiverHandle(thread, receiver);
-  MutexLockerEx ml(thread->threadObj() == receiver ? NULL : Threads_lock);
+  MutexLockerEx ml(thread->threadObj() == (void*)receiver ? NULL : Threads_lock);
   JavaThread* receiverThread = java_lang_Thread::thread(receiverHandle());
   return (jint) Thread::is_interrupted(receiverThread, clear_interrupted != 0);
 JRT_END
--- a/src/share/vm/graal/graalRuntime.hpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Wed Oct 16 18:27:28 2013 +0200
@@ -33,18 +33,18 @@
   static void new_instance(JavaThread* thread, Klass* klass);
   static void new_array(JavaThread* thread, Klass* klass, jint length);
   static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
-  static void dynamic_new_array(JavaThread* thread, oop element_mirror, jint length);
-  static jboolean thread_is_interrupted(JavaThread* thread, oop obj, jboolean clear_interrupted);
+  static void dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length);
+  static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupted);
   static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3);
-  static jint identity_hash_code(JavaThread* thread, oop obj);
+  static jint identity_hash_code(JavaThread* thread, oopDesc* obj);
   static address exception_handler_for_pc(JavaThread* thread);
   static void monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);
   static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock);
   static void create_null_exception(JavaThread* thread);
   static void create_out_of_bounds_exception(JavaThread* thread, jint index);
-  static void vm_error(JavaThread* thread, oop where, oop format, jlong value);
-  static oop load_and_clear_exception(JavaThread* thread);
-  static void log_printf(JavaThread* thread, oop format, jlong v1, jlong v2, jlong v3);
+  static void vm_error(JavaThread* thread, oopDesc* where, oopDesc* format, jlong value);
+  static oopDesc* load_and_clear_exception(JavaThread* thread);
+  static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3);
   static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
   // Note: Must be kept in sync with constants in com.oracle.graal.replacements.Log
   enum {
@@ -52,10 +52,11 @@
     LOG_OBJECT_STRING  = 0x02,
     LOG_OBJECT_ADDRESS = 0x04
   };
-  static void log_object(JavaThread* thread, oop msg, jint flags);
+  static void log_object(JavaThread* thread, oopDesc* msg, jint flags);
   static void write_barrier_pre(JavaThread* thread, oopDesc* obj);
   static void write_barrier_post(JavaThread* thread, void* card);
   static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child);
+  static void new_store_pre_barrier(JavaThread* thread);
 };
 
 #endif // SHARE_VM_GRAAL_GRAAL_RUNTIME_HPP
--- a/src/share/vm/prims/unsafe.cpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/share/vm/prims/unsafe.cpp	Wed Oct 16 18:27:28 2013 +0200
@@ -173,9 +173,7 @@
 #define GET_OOP_FIELD(obj, offset, v) \
   oop p = JNIHandles::resolve(obj);   \
   oop v;                              \
-   /* Uncompression is not performed to unsafeAccess with null object. \
-    * This concerns accesses to the metaspace such as the classMirrorOffset in Graal which is not compressed.*/ \
-  if (UseCompressedOops GRAAL_ONLY(&& p != NULL && offset >= oopDesc::header_size())) {            \
+  if (UseCompressedOops) {            \
     narrowOop n = *(narrowOop*)index_oop_from_field_offset_long(p, offset); \
     v = oopDesc::decode_heap_oop(n);                                \
   } else {                            \
--- a/src/share/vm/runtime/vframeArray.cpp	Wed Oct 16 18:27:11 2013 +0200
+++ b/src/share/vm/runtime/vframeArray.cpp	Wed Oct 16 18:27:28 2013 +0200
@@ -338,7 +338,7 @@
 #ifndef PRODUCT
         if (PrintDeoptimizationDetails) {
           tty->print("Reconstructed expression %d (OBJECT): ", i);
-          oop o = (oop)(*addr);
+          oop o = (oop)(address)(*addr);
           if (o == NULL) {
             tty->print_cr("NULL");
           } else {
@@ -375,7 +375,7 @@
 #ifndef PRODUCT
         if (PrintDeoptimizationDetails) {
           tty->print("Reconstructed local %d (OBJECT): ", i);
-          oop o = (oop)(*addr);
+          oop o = (oop)(address)(*addr);
           if (o == NULL) {
             tty->print_cr("NULL");
           } else {